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();

        /// <summary>
        /// 操作日志服务
        /// </summary>
        private RecordLogService recordLogService = new RecordLogService();

        // ============================================================
        // 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 EnginePreviewModes -- 引擎预览模式集合

        private List<EnumModel> enginePreviewModes = EnumHelper.GetEnumModels<EnginePreviewMode>();
        /// <summary>
        /// 引擎预览模式集合
        /// </summary>
        public List<EnumModel> EnginePreviewModes
        {
            get { return enginePreviewModes; }
            set { enginePreviewModes = value; this.RaisePropertyChanged(nameof(EnginePreviewModes)); }
        }

        #endregion

        #region SelectedEnginePreviewMode -- 选中的引擎预览模式

        private EnumModel selectedEnginePreviewMode;
        /// <summary>
        /// 选中的引擎预览模式
        /// </summary>
        public EnumModel SelectedEnginePreviewMode
        {
            get { return selectedEnginePreviewMode; }
            set { selectedEnginePreviewMode = value; this.RaisePropertyChanged(nameof(SelectedEnginePreviewMode)); }
        }

        #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 GH_ServerName_List -- GH 服务名列表

        private List<string> gh_ServerName_List;
        /// <summary>
        /// GH 服务名列表
        /// </summary>
        public List<string> GH_ServerName_List
        {
            get { return gh_ServerName_List; }
            set { gh_ServerName_List = value; this.RaisePropertyChanged(nameof(GH_ServerName_List)); }
        }

        #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_UserName_List -- VIZ 用户名列表

        private List<string> viz_UserName_List;
        /// <summary>
        /// 用户名列表
        /// </summary>
        public List<string> VIZ_UserName_List
        {
            get { return viz_UserName_List; }
            set { viz_UserName_List = value; this.RaisePropertyChanged(nameof(VIZ_UserName_List)); }
        }

        #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;

            // 记录操作日志
            this.recordLogService.AppendLog(ApplicationConstants.APPLICATION_GROUP_NAME, RecordLogOperate.System, RecordLogTrigger.System, RecordLogConstants.SYSTEM_SET_UP);

            // Step 1. 加载GH服务名列表 & VIZ服务名
            this.GH_ServerName_List = ApplicationDomainEx.IniStorage.GetValue<VizConfig, string>(p => p.VIZ_GH_SERVER_NAME)
                                      ?.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)?.ToList();

            this.VIZ_UserName_List = ApplicationDomainEx.IniStorage.GetValue<VizConfig, string>(p => p.VIZ_USER_NAME)
                                     ?.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)?.ToList();

            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;

                //时钟控件加载读取
                ClockFieldEntity clockFieldEntity = ApplicationDomainEx.LocalDbContext.ClockField.FindAll().FirstOrDefault();
                clockFieldEntity= clockFieldEntity ?? new ClockFieldEntity();   
                ApplicationDomainEx.ClockField= clockFieldEntity;   

                // 布局保存存在加载数据读取

                SaveLayoutFieldEntity saveLayoutFieldEntity= ApplicationDomainEx.LocalDbContext.SaveLayoutField.FindAll().FirstOrDefault(); 
                saveLayoutFieldEntity= saveLayoutFieldEntity ?? new SaveLayoutFieldEntity();
                ApplicationDomainEx.SaveLayoutField = saveLayoutFieldEntity;    

                // 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);
                this.SelectedEnginePreviewMode = this.EnginePreviewModes.FirstOrDefault(p => (EnginePreviewMode)p.Key == vizConfig.EnginePreviewMode);
            });
        }

        /// <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;
            vizConfig.EnginePreviewMode = (EnginePreviewMode)this.SelectedEnginePreviewMode.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();

            // 记录操作日志
            StringBuilder remark = new StringBuilder();
            remark.Append($"GH库: {vizConfig.GH_IP}:{vizConfig.GH_Port} 服务名: {vizConfig.GH_ServerName} ");
            remark.Append($"账号: {vizConfig.GH_UserName} ");
            remark.Append($"节目: {vizConfig.PluginGroup ?? string.Empty} ");
            remark.Append($"引擎类型: {vizConfig.EngineFullType.GetDescription()} ");
            remark.Append($"预览模式: {vizConfig.EnginePreviewMode.GetDescription()} ");

            this.recordLogService.AppendLog(ApplicationConstants.APPLICATION_GROUP_NAME, RecordLogOperate.Operate, RecordLogTrigger.Human, RecordLogConstants.OPERATE_LOGIN, remark.ToString());
        }

        #endregion
    }
}
