using DevExpress.Xpf.Core;
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.Controls.Primitives;
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);
        }

        /// <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);
        }

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

        /// <summary>
        /// 页视图模型辅助类
        /// </summary>
        private PageViewModelHelper pageViewModelHelper = new PageViewModelHelper();

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

        // ======================================================================================
        // 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 SceneTemplateModels -- 场景模板模型集合

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

        #endregion

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

        private IList selectedSceneTemplateModels;
        /// <summary>
        /// 当前选中的场景模板集合
        /// </summary>
        public IList SelectedSceneTemplateModels
        {
            get { return selectedSceneTemplateModels; }
            set { selectedSceneTemplateModels = value; this.RaisePropertyChanged(nameof(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.SelectedSceneTemplateModels == null || this.SelectedSceneTemplateModels.Count == 0)
                return;

            PageTemplateModel template = this.SelectedSceneTemplateModels[0] as PageTemplateModel;
            this.OpenScenePage(template);
        }

        /// <summary>
        /// 打开模板
        /// </summary>
        /// <param name="page">页</param>
        private void OpenScenePage(PageModelBase page)
        {
            ApplicationDomainEx.CurrentPage = page;

            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 = new List<PageModelBase>();
            foreach (PageTemplateModel template in this.SelectedSceneTemplateModels)
            {
                templates.Add(template);
            }

            // 开始下载图片
            this.pageViewModelHelper.BeginDownLoadIamge(templates);

            // 开始下载控制对象
            this.pageViewModelHelper.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;

            if (DXMessageBox.Show($"是否删除模板?", "提示", System.Windows.MessageBoxButton.YesNo) != System.Windows.MessageBoxResult.Yes)
                return;

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

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

                // 获取场景模板缩略图
                this.pageViewModelHelper.BeginDownLoadIamge(sceneTemplateModels.ToList<PageModelBase>());
            });
        }

        /// <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);
        }

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

        /// <summary>
        /// 添加场景模板
        /// </summary>
        /// <param name="fileModels">文件模型集合</param>
        public void AddSceneTemplate(List<GHResourceFileModel> fileModels)
        {
            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;
                model.ThumbnailUri = fileModel.Thumbnail;
                model.ThumbnailBitmap = fileModel.ThumbnailBitmap;

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

            // 开始下载缩略图
            this.pageViewModelHelper.BeginDownLoadIamge(list);

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

                this.OpenScenePage(last);
            });
        }

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