using DevExpress.Xpf.Core;
using DevExpress.Xpf.Core.HandleDecorator.Helpers;
using log4net;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media.Animation;
using VIZ.Framework.Common;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Service;
using VIZ.Package.Storage;

namespace VIZ.Package.Module
{
    /// <summary>
    /// 页模板视图模型
    /// </summary>
    public class PageTemplateViewModel : ViewModelBase, IPageTemplateService
    {
        /// <summary>
        /// 日志
        /// </summary>
        private readonly static ILog log = LogManager.GetLogger(typeof(PageTemplateViewModel));

        public PageTemplateViewModel()
        {
            // 初始化命令
            this.InitCommand();

            // 初始化消息
            this.InitMessage();

            // 注册服务
            ApplicationDomainEx.ServiceManager.AddService(ViewServiceKeys.PAGE_TEMPLATE_SERVICE, this);
        }

        /// <summary>
        /// 初始化命令
        /// </summary>
        private void InitCommand()
        {
            this.AddToPageGroupCommand = new VCommand(this.AddToPageGroup);
            this.OpenScenePageCommand = new VCommand(this.OpenScenePage);
            this.UpdateCommand = new VCommand(this.Update);
            this.DeleteCommand = new VCommand(this.Delete);
            this.PreviewKeyDownCommand = new VCommand<KeyEventArgs>(this.PreviewKeyDown);
        }

        /// <summary>
        /// 初始化消息
        /// </summary>
        private void InitMessage()
        {
            ApplicationDomainEx.MessageManager.Register<ProjectOpenMessage>(this, this.OnProjectOpenMessage);
            ApplicationDomainEx.MessageManager.Register<ProjectCloseMessage>(this, this.OnProjectCloseMessage);
            ApplicationDomainEx.MessageManager.Register<ProjectSaveMessage>(this, this.OnProjectSaveMessage);
            ApplicationDomainEx.MessageManager.Register<PageOpenMessage>(this, this.OnPageOpenMessage);
            ApplicationDomainEx.MessageManager.Register<PageOpenOverMessage>(this, this.OnPageOpenOverMessage);
        }

        // ======================================================================================
        // Field
        // ======================================================================================

        /// <summary>
        /// 页模型控制器
        /// </summary>
        private PageModelController pageModelController = new PageModelController();

        /// <summary>
        /// GH服务
        /// </summary>
        private GHService ghService = new GHService();

        /// <summary>
        /// 页服务
        /// </summary>
        private PageService pageService = new PageService();

        /// <summary>
        /// Viz命令服务
        /// </summary>
        private VizCommandService vizCommandService = new VizCommandService();

        /// <summary>
        /// Viz控制对象服务
        /// </summary>
        private VizCommandControlObjectService vizCommandControlObjectService = new VizCommandControlObjectService();

        /// <summary>
        /// 控制对象服务
        /// </summary>
        private ControlObjectService controlObjectService = new ControlObjectService();

        /// <summary>
        /// Viz控制对象下载服务
        /// </summary>
        private VizControlObjectDownloadService vizControlObjectDownloadService = new VizControlObjectDownloadService();

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

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

        #region IsEnabled -- 是否可用

        private bool isEnabled;
        /// <summary>
        /// 是否可用
        /// </summary>
        public bool IsEnabled
        {
            get { return isEnabled; }
            set { isEnabled = value; this.RaisePropertyChanged(nameof(IsEnabled)); }
        }

        #endregion

        #region IsLoading -- 是否正在加载

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

        #endregion

        #region IsWaitingPageOpen -- 是否正在等待页打开

        private bool isWaitingPageOpen;
        /// <summary>
        /// 是否正在等待页打开
        /// </summary>
        public bool IsWaitingPageOpen
        {
            get { return isWaitingPageOpen; }
            set { isWaitingPageOpen = value; this.RaisePropertyChanged(nameof(IsWaitingPageOpen)); }
        }

        #endregion

        #region SceneTemplateModels -- 场景模板模型集合

        private ObservableCollection<PageTemplateModel> sceneTemplateModels;
        /// <summary>
        /// 场景模板集合
        /// </summary>
        public ObservableCollection<PageTemplateModel> SceneTemplateModels
        {
            get { return sceneTemplateModels; }
            set { sceneTemplateModels = value; this.RaisePropertyChanged(nameof(SceneTemplateModels)); }
        }

        #endregion

        #region SelectedSceneTemplateModel -- 当前选中的场景模板

        private PageTemplateModel selectedSceneTemplateModel;
        /// <summary>
        /// 当前选中的场景模板
        /// </summary>
        public PageTemplateModel SelectedSceneTemplateModel
        {
            get { return selectedSceneTemplateModel; }
            set { selectedSceneTemplateModel = value; this.RaisePropertyChanged(nameof(SelectedSceneTemplateModel)); }
        }

        #endregion

        #region SelectedSceneTemplateModels -- 当前选中的场景模板集合

        private ObservableCollection<PageTemplateModel> selectedSceneTemplateModels = new ObservableCollection<PageTemplateModel>();
        /// <summary>
        /// 当前选中的场景模板集合
        /// </summary>
        public ObservableCollection<PageTemplateModel> SelectedSceneTemplateModels
        {
            get { return selectedSceneTemplateModels; }
        }

        #endregion

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

        #region AddToPageGroupCommand -- 场景模板添加至页分组命令

        /// <summary>
        /// 场景模板添加至页分组命令
        /// </summary>
        public VCommand AddToPageGroupCommand { get; set; }

        /// <summary>
        /// 场景模板添加至页分组
        /// </summary>
        private void AddToPageGroup()
        {
            if (this.SelectedSceneTemplateModels == null || this.SelectedSceneTemplateModels.Count == 0)
                return;

            IPageGroupService service = ApplicationDomainEx.ServiceManager.GetService<IPageGroupService>(ViewServiceKeys.PAGE_GROUP_SERVICE);
            if (service == null)
                return;

            foreach (PageTemplateModel template in this.SelectedSceneTemplateModels)
            {
                service.AddPage(template);
            }
        }

        #endregion

        #region OpenScenePageCommand -- 打开场景页命令

        /// <summary>
        /// 打开场景页命令
        /// </summary>
        public VCommand OpenScenePageCommand { get; set; }

        /// <summary>
        /// 打开场景页
        /// </summary>
        private void OpenScenePage()
        {
            if (this.SelectedSceneTemplateModel == null)
                return;

            // 打开模板页
            this.OpenScenePage(this.SelectedSceneTemplateModel);
        }

        /// <summary>
        /// 打开模板
        /// </summary>
        /// <param name="page">页</param>
        private void OpenScenePage(PageModelBase page)
        {
            // 记录操作日志
            string remark = $"{page.ScenePath}";
            this.recordLogService.AppendLog(ApplicationConstants.APPLICATION_GROUP_NAME, RecordLogOperate.Operate, RecordLogTrigger.Human, RecordLogConstants.OPERATE_TEMPLATE_OPEN, remark);

            if (ApplicationDomainEx.CurrentPage != null)
            {
                ApplicationDomainEx.CurrentPage.IsOpen = false;
            }

            ApplicationDomainEx.CurrentPage = page;
            page.IsOpen = true;

            PageOpenMessage msg = new PageOpenMessage();
            msg.Page = page;
            ApplicationDomainEx.MessageManager.Send(msg);
        }

        #endregion

        #region UpdateCommand -- 更新命令

        /// <summary>
        /// 更新命令
        /// </summary>
        public VCommand UpdateCommand { get; set; }

        /// <summary>
        /// 更新
        /// </summary>
        private void Update()
        {
            if (this.SelectedSceneTemplateModels == null || this.SelectedSceneTemplateModels.Count == 0)
                return;

            List<PageModelBase> templates = this.SelectedSceneTemplateModels.ToList<PageModelBase>();

            // 记录操作日志
            string remark = string.Join(",", templates.Select(p => p.Scene));
            this.recordLogService.AppendLog(ApplicationConstants.APPLICATION_GROUP_NAME, RecordLogOperate.Operate, RecordLogTrigger.Human, RecordLogConstants.OPERATE_TEMPLATE_UPDATE, remark);

            // 开始下载控制对象
            this.pageModelController.BeginDownLoadControlObject(templates, () =>
            {
                // 控制对象下载完成后打开最后一个模板
                PageModelBase last = templates.LastOrDefault();
                if (last == null)
                    return;

                this.OpenScenePage(last);
            });
        }

        #endregion

        #region DeleteCommand -- 删除命令

        /// <summary>
        /// 删除命令
        /// </summary>
        public VCommand DeleteCommand { get; set; }

        /// <summary>
        /// 删除
        /// </summary>
        private void Delete()
        {
            if (this.SelectedSceneTemplateModels == null || this.SelectedSceneTemplateModels.Count == 0)
                return;

            string scenes = string.Join(" ,", this.SelectedSceneTemplateModels.Select(p => p.Scene));
            if (DXMessageBox.Show($"是否删除模板 [{scenes}] ?", "提示", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                return;

            // 记录操作日志
            string remark = string.Join(",", this.SelectedSceneTemplateModels.Select(p => p.Scene));
            this.recordLogService.AppendLog(ApplicationConstants.APPLICATION_GROUP_NAME, RecordLogOperate.Operate, RecordLogTrigger.Human, RecordLogConstants.OPERATE_TEMPLATE_DELETE, remark);

            List<PageTemplateModel> templates = this.SelectedSceneTemplateModels.ToList();
            foreach (PageTemplateModel template in templates)
            {
                this.SceneTemplateModels.Remove(template);
            }
        }

        #endregion

        #region PreviewKeyDownCommand -- 按键按下命令

        /// <summary>
        /// 按键按下命令
        /// </summary>
        public VCommand<KeyEventArgs> PreviewKeyDownCommand { get; set; }

        /// <summary>
        /// 按键按下
        /// </summary>
        /// <param name="e">事件参数</param>
        private void PreviewKeyDown(KeyEventArgs e)
        {
            try
            {
                TextBoxBase tb = e.OriginalSource as TextBoxBase;
                if (tb != null)
                    return;

                string key = HotkeyHelper.GetHotkey(e);

                // 删除模板
                if (string.Equals(key, HotKeyConfigEntity.DELETE))
                {
                    // 记录操作日志
                    this.recordLogService.AppendLog(ApplicationConstants.APPLICATION_GROUP_NAME, RecordLogOperate.System, RecordLogTrigger.Human, RecordLogConstants.SYSTEM_HOT_KEY, key);

                    this.Delete();
                    return;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        #endregion

        // ======================================================================================
        // Message
        // ======================================================================================

        /// <summary>
        /// 项目打开消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnProjectOpenMessage(ProjectOpenMessage msg)
        {
            this.IsEnabled = true;
            this.SceneTemplateModels = null;
            this.IsLoading = true;

            ThreadHelper.SafeRun(() =>
            {
                // 场景模板
                var sceneTemplateModels = this.pageService.LoadPageTemplates().ToObservableCollection();

                // 更新界面
                WPFHelper.BeginInvoke(() =>
                {
                    this.SceneTemplateModels = sceneTemplateModels;

                    this.IsLoading = false;
                });
            });
        }

        /// <summary>
        /// 项目关闭消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnProjectCloseMessage(ProjectCloseMessage msg)
        {
            this.IsEnabled = false;
            this.IsLoading = false;
            this.SceneTemplateModels = null;
        }

        /// <summary>
        /// 项目保存消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnProjectSaveMessage(ProjectSaveMessage msg)
        {
            this.pageService.SavePageTemplates(this.SceneTemplateModels);
        }

        /// <summary>
        /// 页打开消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnPageOpenMessage(PageOpenMessage msg)
        {
            this.IsWaitingPageOpen = true;
        }

        /// <summary>
        /// 是否等待页打开完成
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnPageOpenOverMessage(PageOpenOverMessage msg)
        {
            this.IsWaitingPageOpen = false;
        }

        // ======================================================================================
        // Public Function
        // ======================================================================================

        /// <summary>
        /// 添加场景模板
        /// </summary>
        /// <param name="fileModels">文件模型集合</param>
        public void AddSceneTemplate(List<GHResourceFileModel> fileModels)
        {
            // 记录操作日志
            string remark = string.Join(",", fileModels.Select(p => p.Name));
            this.recordLogService.AppendLog(ApplicationConstants.APPLICATION_GROUP_NAME, RecordLogOperate.Operate, RecordLogTrigger.Human, RecordLogConstants.OPERATE_TEMPLATE_ADD, remark);

            List<PageModelBase> list = new List<PageModelBase>();

            foreach (GHResourceFileModel fileModel in fileModels)
            {
                // 如果场景中已经拥有该模板，那么不处理
                if (this.SceneTemplateModels.Any(p => p.Scene == fileModel.Name))
                    continue;

                PageTemplateModel model = new PageTemplateModel();
                model.TemplateID = Guid.NewGuid();
                model.Scene = fileModel.Name;
                model.ScenePath = fileModel.Path;
                model.Layer = VizLayer.MAIN_LAYER;
                model.PageType = PageType.Scene;
                model.EngineType = EngineType.Viz;

                list.Add(model);
                this.SceneTemplateModels.Add(model);
            }

            // 开始下载控制对象
            this.pageModelController.BeginDownLoadControlObject(list, () =>
            {
                // 控制对象下载完成后打开最后一个模板
                PageModelBase last = list.LastOrDefault();
                if (last == null)
                    return;

                this.OpenScenePage(last);
            });
        }

        // ======================================================================================
        // Private Function
        // ======================================================================================
    }
}