using DevExpress.Utils.About;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Service;
using VIZ.Package.Storage;

namespace VIZ.Package.Module
{
    /// <summary>
    /// 登录视图模型
    /// </summary>
    public class LoginViewModel : ViewModelBase
    {
        public LoginViewModel()
        {
            // 初始化命令
            this.InitCommand();
        }

        /// <summary>
        /// 初始化命令
        /// </summary>
        private void InitCommand()
        {
            this.LoadedCommand = new VCommand(this.Loaded);
            this.LoginCommand = new VCommand(this.Login);
        }

        // ============================================================
        // Service & Controller
        // ============================================================

        /// <summary>
        /// 插件服务
        /// </summary>
        private PluginService pluginService = new PluginService();

        /// <summary>
        /// 注册表服务
        /// </summary>
        private RegistryService registryService = new RegistryService();

        // ============================================================
        // Property
        // ============================================================

        #region IsLoading -- 是否正在加载

        private bool isLoading;
        /// <summary>
        /// 是否正在加载
        /// </summary>
        public bool IsLoading
        {
            get { return isLoading; }
            set { isLoading = value; this.RaisePropertyChanged(nameof(IsLoading)); }
        }

        #endregion

        #region EngineFullTypes -- 引擎类型集合

        private List<EnumModel> engineFullTypes = EnumHelper.GetEnumModels<EngineFullType>();
        /// <summary>
        /// 引擎类型集合
        /// </summary>
        public List<EnumModel> EngineFullTypes
        {
            get { return engineFullTypes; }
            set { engineFullTypes = value; this.RaisePropertyChanged(nameof(EngineFullTypes)); }
        }

        #endregion

        #region SelectedEngineFullType -- 选中的引擎类型

        private EnumModel selectedEngineFullType;
        /// <summary>
        /// 选中的引擎类型
        /// </summary>
        public EnumModel SelectedEngineFullType
        {
            get { return selectedEngineFullType; }
            set { selectedEngineFullType = value; this.RaisePropertyChanged(nameof(SelectedEngineFullType)); }
        }

        #endregion

        #region PluginGroups -- 插件分组

        private List<string> pluginGroups;
        /// <summary>
        /// 插件分组
        /// </summary>
        public List<string> PluginGroups
        {
            get { return pluginGroups; }
            set { pluginGroups = value; this.RaisePropertyChanged(nameof(PluginGroups)); }
        }

        #endregion

        #region SelectedPluginGroup -- 选中的插件分组

        private string selectedPluginGroup;
        /// <summary>
        /// 选中的插件分组
        /// </summary>
        public string SelectedPluginGroup
        {
            get { return selectedPluginGroup; }
            set { selectedPluginGroup = value; this.RaisePropertyChanged(nameof(SelectedPluginGroup)); }
        }

        #endregion

        #region GH_IP -- GH IP

        private string gh_ip;
        /// <summary>
        /// GH_IP
        /// </summary>
        public string GH_IP
        {
            get { return gh_ip; }
            set { gh_ip = value; this.RaisePropertyChanged(nameof(GH_IP)); }
        }


        #endregion

        #region GH_Port -- GH 端口

        private int gh_port;
        /// <summary>
        /// GH 端口
        /// </summary>
        public int GH_Port
        {
            get { return gh_port; }
            set { gh_port = value; this.RaisePropertyChanged(nameof(GH_Port)); }
        }

        #endregion

        #region GH_ServerName -- GH 服务名

        private string gh_serverName;
        /// <summary>
        /// GH 服务名
        /// </summary>
        public string GH_ServerName
        {
            get { return gh_serverName; }
            set { gh_serverName = value; this.RaisePropertyChanged(nameof(GH_ServerName)); }
        }

        #endregion

        #region VIZ_UserName -- VIZ 用户名

        private string viz_userName;
        /// <summary>
        /// VIZ 用户名
        /// </summary>
        public string VIZ_UserName
        {
            get { return viz_userName; }
            set { viz_userName = value; this.RaisePropertyChanged(nameof(VIZ_UserName)); }
        }

        #endregion

        #region VIZ_Password -- VIZ 密码

        private string viz_password;
        /// <summary>
        /// VIZ 密码
        /// </summary>
        public string VIZ_Password
        {
            get { return viz_password; }
            set { viz_password = value; this.RaisePropertyChanged(nameof(VIZ_Password)); }
        }

        #endregion

        // ============================================================
        // Command
        // ============================================================

        #region LoadedCommand -- 加载命令

        /// <summary>
        /// 加载命令
        /// </summary>
        public VCommand LoadedCommand { get; set; }

        /// <summary>
        /// 加载
        /// </summary>
        private void Loaded()
        {
            if (this.IsAlreadyLoaded)
                return;

            this.IsAlreadyLoaded = true;

            this.IsLoading = true;

            ThreadHelper.SafeRun(action: () =>
            {
                // Step 1. 加载Viz配置信息
                VizConfigEntity vizConfig = ApplicationDomainEx.LocalDbContext.VizConfig.FindAll().FirstOrDefault();
                vizConfig = vizConfig ?? this.CreateDefaultVizConfig();
                ApplicationDomainEx.VizConfig = vizConfig;
                this.UpdateVizConfig(vizConfig);

                // Step 2. 加载媒资库信息
                MediaConfigEntity mediaConfig = ApplicationDomainEx.LocalDbContext.MediaConfig.FindAll().FirstOrDefault();
                mediaConfig = mediaConfig ?? new MediaConfigEntity();
                ApplicationDomainEx.MediaConfig = mediaConfig;

                // Step 3. 加载插件信息
                ApplicationDomainEx.PluginInfos = this.pluginService.LoadPluginInfos();
                this.UpdatePluginInfos(vizConfig);

            }, final: () =>
            {
                WPFHelper.BeginInvoke(() =>
                {
                    this.IsLoading = false;
                });
            });
        }

        /// <summary>
        /// 创建默认的Viz配置文件
        /// </summary>
        /// <returns>默认的Viz配置文件</returns>
        private VizConfigEntity CreateDefaultVizConfig()
        {
            VizConfigEntity config = new VizConfigEntity();

            config.VIZ_Eng3Path = this.registryService.GetVizSetupPath();
            config.VIZ_Eng4Path = config.VIZ_Eng3Path;

            return config;
        }

        /// <summary>
        /// 更新Viz配置
        /// </summary>
        /// <param name="vizConfig">Viz配置</param>
        private void UpdateVizConfig(VizConfigEntity vizConfig)
        {
            WPFHelper.Invoke(() =>
            {
                this.GH_IP = vizConfig.GH_IP;
                this.GH_Port = vizConfig.GH_Port;
                this.GH_ServerName = vizConfig.GH_ServerName;
                this.VIZ_UserName = vizConfig.VIZ_UserName;
                this.VIZ_Password = vizConfig.VIZ_Password;
                this.SelectedEngineFullType = this.EngineFullTypes.FirstOrDefault(p => (EngineFullType)p.Key == vizConfig.EngineFullType);
            });
        }

        /// <summary>
        /// 更新插件信息
        /// </summary>
        /// <param name="vizConfig">Viz配置</param>
        private void UpdatePluginInfos(VizConfigEntity vizConfig)
        {
            WPFHelper.Invoke(() =>
            {
                this.PluginGroups = ApplicationDomainEx.PluginInfos
                                                       .Where(p => !string.IsNullOrWhiteSpace(p.Group) &&
                                                                   p.Group != ApplicationConstants.APPLICATION_GROUP_NAME)
                                                       .GroupBy(p => p.Group)
                                                       .Select(p => p.Key)
                                                       .ToList();
                this.SelectedPluginGroup = this.PluginGroups.FirstOrDefault(p => p == vizConfig.PluginGroup);
            });
        }

        #endregion

        #region LoginCommand -- 登录命令

        /// <summary>
        /// 登录命令
        /// </summary>
        public VCommand LoginCommand { get; set; }

        /// <summary>
        /// 登录
        /// </summary>
        private void Login()
        {
            VizConfigEntity vizConfig = ApplicationDomainEx.VizConfig;
            vizConfig.GH_IP = this.GH_IP;
            vizConfig.GH_Port = this.GH_Port;
            vizConfig.GH_ServerName = this.GH_ServerName;
            vizConfig.VIZ_UserName = this.VIZ_UserName;
            vizConfig.VIZ_Password = this.VIZ_Password;
            vizConfig.PluginGroup = this.SelectedPluginGroup;
            vizConfig.EngineFullType = (EngineFullType)this.SelectedEngineFullType.Key;

            ApplicationDomainEx.LocalDbContext.VizConfig.Upsert(vizConfig);

            Window loginWindow = this.GetWindow();
            loginWindow.ShowInTaskbar = false;
            ApplicationDomainEx.MainWindow = ApplicationDomainEx.MainWindowType.Assembly.CreateInstance(ApplicationDomainEx.MainWindowType.FullName) as Window;
            ApplicationDomainEx.MainWindow.Show();
            loginWindow.Hide();
        }

        #endregion
    }
}
