using Prism.Commands;
using Valg.EVA.Skanning.ContainerExtensions;
using Valg.EVA.Skanning.Contracts.CommonEnums;
using Valg.EVA.Skanning.JobManagement.Startup.Data;
using Valg.EVA.Skanning.Resources.Language;
using Valg.EVA.Skanning.ServicesModel.Internal;
using Valg.EVA.Skanning.UserInterfaceElements.LightBox;

namespace Valg.EVA.Skanning.JobManagement.Startup.UI.Counting
{
    public class BoxCountingViewModel : ReactiveViewModel
    {
        private BoxCountingDetailsModel model;
        private readonly ITypedFactory typedFactory;

        public BoxCountingViewModel(ITypedFactory typedFactory)
        {
            this.typedFactory = typedFactory;
            ShowClearBoxCommand = new DelegateCommand(ShowClearBoxPopupView);
        }

        public void Initialize(BoxCountingDetailsModel detailsModel)
        {
            model = detailsModel;
            AddBubbleEvents();
        }

        public string BallotsToVerify => Model.HasScannedBallots
            ? Model.BallotsToVerify.ToString()
            : JobManagementLanguageString.BoxCounting_NoData;

        public BoxCountingState BoxCountingState => Model.BoxCountingState;

        public string BoxName => $"{JobManagementLanguageString.BoxCounting_BoxName} {Model.BarcodeLong.GetBoxNumberFromBarcodeLong()}";

        public BoxCountingDetailsModel Model => model;

        public string ScannedBallots => Model.HasScannedBallots
            ? Model.ScannedBallots.ToString()
            : (int)Model.BoxCountingState >= (int)BoxCountingState.ReadyForVerify
                ? JobManagementLanguageString.BoxCounting_ScannedBallots_Empty
                :JobManagementLanguageString.BoxCounting_ScannedBallots_None;

        public DelegateCommand ShowClearBoxCommand { get; }

        public string Status => GetStatusText();

        public bool IsEnabled => (BoxCountingState != BoxCountingState.Locked && BoxCountingState != BoxCountingState.Complete);

        public bool HasDuplicates => Model.BoxCountingState == BoxCountingState.ResolveDuplicates;

        private void AddBubbleEvents()
        {
            model.Bubble(
                m => m.ScannedBallots,
                this,
                vm => vm.ScannedBallots,
                vm => vm.BallotsToVerify);
            model.Bubble(
                m => m.BallotsToVerify,
                this,
                vm => vm.BallotsToVerify);
            model.Bubble(
                s => s.HasBallotsToVerify,
                this,
                t => t.Status);
            model.Bubble(
                m => m.BoxCountingState,
                this,
                vm => vm.Status,
                vm => vm.BoxCountingState,
                vm => vm.IsEnabled,
                vm => vm.HasDuplicates,
                vm => vm.ScannedBallots);
        }

        private string GetStatusText()
        {
            string status;
            switch (BoxCountingState)
            {
                case BoxCountingState.RegisteredNotScanned:
                    status = JobManagementLanguageString.BoxCounting__Status_RegisteredNotScanned;
                    break;

                case BoxCountingState.ReadyForScan:
                    status = JobManagementLanguageString.BoxCounting__Status_ReadyForScan;
                    break;

                case BoxCountingState.Scanning:
                    status = JobManagementLanguageString.BoxCounting__Status_Scanning;
                    break;

                case BoxCountingState.ScanComplete:
                    status = JobManagementLanguageString.BoxCounting__Status_ScanComplete;
                    break;

                case BoxCountingState.ResolveDuplicates:
                    status = JobManagementLanguageString.BoxCounting__Status_HasDuplicates;
                    break;

                case BoxCountingState.ReadyForVerify:
                    status = GetStatusWhenReadyForVerify();
                    break;

                case BoxCountingState.Locked:
                    status = JobManagementLanguageString.BoxCounting__Status_Locked;
                    break;

                case BoxCountingState.Complete:
                    status = JobManagementLanguageString.BoxCounting__Status_Complete;
                    break;

                case BoxCountingState.Empty:
                    status = JobManagementLanguageString.BoxCounting__Status_Empty;
                    break;

                default:
                    status = "---";
                    break;
            }
            return status;
        }

        private string GetStatusWhenReadyForVerify()
        {
            string status = JobManagementLanguageString.BoxCounting__Status_ReadyToBeFinished;

            if (Model.CountingType == CountingType.Final && Model.HasBallotsToVerify)
            {
                status = JobManagementLanguageString.BoxCounting__Status_ReadyForVerify;
            }

            return status;
        }

        private void ShowClearBoxPopupView()
        {
            var viewModel = typedFactory.Create<ClearBoxPopupViewModel>();
            viewModel.Initialize(BoxName, Model);
            var eventArgs = new LightBoxEventArgs(typeof(ClearBoxPopupView), viewModel);
            PublishEvent<ShowLightBoxEvent, LightBoxEventArgs>(eventArgs);
        }
    }
}
