using System.Linq;
using System.Reflection;
using Valg.EVA.Skanning.ContainerExtensions;
using Valg.EVA.Skanning.UserInterfaceElements.Help;
using Valg.EVA.Skanning.Identity;
using System.Windows;
using System.Windows.Input;
using Prism.Commands;
using Prism.Events;
using Valg.EVA.Skanning.UserInterfaceElements.ApplicationEvents;
using Valg.EVA.Skanning.UserInterfaceElements.LightBox;
using Valg.EVA.Skanning.UserInterfaceElements.ScannerQuality;
using Valg.EVA.Skanning.UserInterfaceElements.UserSettingWindow;

namespace Valg.EVA.Skanning.UserInterfaceElements.TopBar
{
    public class TopBarViewModel : ViewModelBase
    {
        private readonly IIdentityProvider identityProvider;
        private readonly ITypedFactory typedFactory;
        private string name;
        private string roleName;
        private string area;
        private string election;
        private string contest;
        private bool isPrerelease;

        public TopBarViewModel(
            IIdentityProvider provider,
            IEventAggregator bus,
            BoxCountingInformationViewModel
            boxCountingInformationViewModel,
            ITypedFactory typedFactory)
        {
            identityProvider = provider;
            this.typedFactory = typedFactory;
            BoxCountingInformationViewModel = boxCountingInformationViewModel;
            SetRoleValues();
            Name = provider.GetCurrentUserDisplayName();
            bus.GetEvent<SecurityContextHasChangedEvent>().Subscribe(e => SetRoleValues());
            bus.GetEvent<ClaimsAddedEvent>().Subscribe(e => SetUserName());
            ShowScannerQualityCommand = new DelegateCommand(ShowScannerQuality);
            GoToHomePageCommand = new DelegateCommand(() => bus
                .GetEvent<MainWindowRequestedEvent>()
                .Publish(System.EventArgs.Empty));
            ShowHelpCommand = new DelegateCommand(bus.ShowHelpWindow);

            IsPrerelease = ResolvePrereleaseFlag();
        }

        private bool ResolvePrereleaseFlag()
        {
            var assembly = GetType().Assembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute)).FirstOrDefault();
            var asDescriptionAttribute = assembly as AssemblyDescriptionAttribute;
            return asDescriptionAttribute != null && asDescriptionAttribute.Description.Contains("prerelease: true");
        }

        public bool IsPrerelease
        {
            get { return isPrerelease; }
            set
            {
                isPrerelease = value;
                OnPropertyChanged();
            }
        }

        public ICommand ShowUserSettingCommand { get; set; }

        public ICommand ShowScannerQualityCommand { get; set; }

        public ICommand GoToHomePageCommand { get; set; }

        public ICommand ShowHelpCommand { get; private set; }

        public string Name
        {
            get { return name; }
            set
            {
                if (name == value)
                    return;

                name = value;
                OnPropertyChanged();
            }
        }

        public string RoleName
        {
            get { return roleName; }
            set
            {
                if (roleName == value)
                    return;

                roleName = value;
                OnPropertyChanged();
            }
        }

        public string Area
        {
            get { return area; }
            set
            {
                if (area == value)
                    return;

                area = value;
                OnPropertyChanged();
            }
        }

        public string Election
        {
            get { return election; }
            set
            {
                if (election == value)
                    return;

                election = value;
                OnPropertyChanged();
            }
        }

        public string Contest
        {
            get { return contest; }
            set
            {
                if (contest == value)
                    return;

                contest = value;
                OnPropertyChanged();
            }
        }

        public bool HasUserName => !string.IsNullOrEmpty(identityProvider.GetCurrentUserDisplayName());

        public bool IsInEmergencyMode => identityProvider.IsInEmergencyMode;

        public bool ShowRoleField
        {
            get
            {
                if (identityProvider.IsInEmergencyMode)
                {
                    return true;
                }
                else
                {
                    return identityProvider.CurrentSelectedRole != null;
                }
            }
        }

        public bool HasRole => identityProvider.CurrentSelectedRole != null;

        public BoxCountingInformationViewModel BoxCountingInformationViewModel { get; set; }


        private void ShowScannerQuality()
        {
            PublishEvent<LaunchScannerQualityCheckEvent, LaunchScannerQualityCheckEventArgs>(new LaunchScannerQualityCheckEventArgs());
        }

        private void SetUserName()
        {
            Name = identityProvider.GetCurrentUserDisplayName();
        }

        private void SetRoleValues()
        {
            OnPropertyChanged(PropertyHelper.GetName<TopBarViewModel>(p => p.HasRole));
            OnPropertyChanged(PropertyHelper.GetName<TopBarViewModel>(p => p.HasUserName));

            if (identityProvider.IsInEmergencyMode)
            {
                RoleName = Resources.Language.LanguageString.EmergencyMode_EmergencyModeDisplayText;
            }

            if (identityProvider.CurrentSelectedRole != null)
            {
                var role = identityProvider.CurrentSelectedRole;
                RoleName = identityProvider.IsInEmergencyMode ? Resources.Language.LanguageString.EmergencyMode_EmergencyModeDisplayText : role.RoleName;
                Area = role.IsSubArea
                    ? role.CountyArea.AreaName
                    : role.Area.AreaName;
                Election = role.ElectionName;
                Contest = role.ContestName;
                SetUserName();
            }
        }
    }
}
