using System;
using System.Linq;
using System.Reflection;
using System.Windows;
using Valg.EVA.Skanning.ContainerExtensions;
using Valg.EVA.Skanning.Identity;
using Valg.EVA.Skanning.ServicesModel.ServiceContracts.Version.Read;
using Valg.EVA.Skanning.UserInterfaceElements.BrowserLaunch;
using Valg.EVA.Skanning.UserInterfaceElements.MessageBox;
using System.Windows.Input;
using Valg.EVA.Skanning.Services.SystemServices;
using Prism.Commands;
using Valg.EVA.Skanning.Contracts;
using Valg.EVA.Skanning.Contracts.Security;
using Valg.EVA.Skanning.UserInterfaceElements.LightBox;
using Res = Valg.EVA.Skanning.Resources.Language.LanguageString;

namespace Valg.EVA.Skanning.UserInterfaceElements.Help
{
    public class HelpViewModel : ViewModelBase
    {
        private readonly IBrowserLauncher browserLauncher;
        private readonly IHelpProvider helpProvider;
        private readonly ITypedFactory typedFactory;
        private readonly IExternalEndpointsConfiguration externalEndpointsConfiguration;

        public HelpViewModel(ISystemService systemService, IBrowserLauncher browserLauncher, 
            IHelpProvider helpProvider, ITypedFactory typedFactory, IIdentityProvider identityProvider, 
            IExternalEndpointsConfiguration externalEndpointsConfiguration)
        {
            this.browserLauncher = browserLauncher;
            this.helpProvider = helpProvider;
            this.typedFactory = typedFactory;
            this.externalEndpointsConfiguration = externalEndpointsConfiguration;

            var electionEventId = identityProvider.ClaimValue(ClaimDefinitions.ElectionEventIdClaimType);
            Initialize(systemService.GetVersionInfo(electionEventId));

            ShowExternalHelpCommand = new DelegateCommand(ShowExternalHelp);
        }

        public ICommand ShowExternalHelpCommand { get; private set; }

        public string Resource { get; set; }

        public string ProductVersion { get; private set; }

        public string ProductVersionLabel { get; private set; }

        public string DatabaseVersion { get; private set; }

        public string DatabaseVersionLabel { get; private set; }

        public string ConfigurationVersion { get; private set; }

        public string ConfigurationVersionLabel { get; private set; }

        public string ConfigurationMetadata { get; private set; }
        
        public string BranchAndCommitLabel { get; private set; }
        
        public string BranchAndCommit { get; private set; }

        public string AdminLogonEnvironmentLabel { get; private set; }

        public string AdminLogonEnvironment { get; private set; }

        public string AdminTransferEnvironmentLabel { get; private set; }

        public string AdminTransferEnvironment { get; private set; }

        public bool ShowAdminTransferEnvironment { get; private set; }

        private void Initialize(VersionInfo versionInfo)
        {
            ProductVersionLabel = Res.Help_ProductVersion;
            ProductVersion = versionInfo.ProductVersion;
            DatabaseVersionLabel = Res.Help_DatabaseVersion;
            DatabaseVersion = versionInfo.DatabaseVersion;
            AdminLogonEnvironmentLabel = Res.Help_AdminLogonEnvironment;
            AdminLogonEnvironment = new Uri(externalEndpointsConfiguration.LogonStartUrl).Host;
            AdminTransferEnvironmentLabel = Res.Help_AdminTransferEnvironment;
            AdminTransferEnvironment = externalEndpointsConfiguration.TransferWebServiceUrl;

            if (AdminTransferEnvironment != string.Empty)
            {
                ShowAdminTransferEnvironment = true;
            }
            
            var assembly = GetType().Assembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute)).FirstOrDefault();
            var asDescriptionAttribute = assembly as AssemblyDescriptionAttribute;
            if (asDescriptionAttribute != null)
            {
                BranchAndCommitLabel = Res.Help_BranchAndCommit;
                BranchAndCommit = asDescriptionAttribute.Description;
            }

            if (!versionInfo.HasConfigurationMetadata)
                return;

            ConfigurationVersionLabel = Res.Help_ConfigurationVersion;
            ConfigurationVersion = versionInfo.ConfigurationMetadata.Version.ToString();
            ConfigurationMetadata = string.Format(Res.Help_ConfigurationMetadata, versionInfo.ConfigurationMetadata.MetadataTimestamp, versionInfo.ConfigurationMetadata.Created);
        }

        private void ShowExternalHelp()
        {
            var uri = helpProvider.GetUri(Resource);

            if (uri != null)
            {
                browserLauncher.OpenWebBrowser(uri);
            }
            else
            {
                var warningDialog = typedFactory.Create<IMessageBox>();
                warningDialog.Initialize(Res.CouldNotResolveHelp,
                    null,
                    string.Format(Res.CouldNotResolveHelpPossibleSolutions_WithFormatArgument, Resource),
                    MessageBoxType.Warning);

                var eventArgs = new LightBoxEventArgs(warningDialog as Window);
                PublishEvent<ShowLightBoxEvent, LightBoxEventArgs>(eventArgs);
            }
        }
    }
}
