using DevExpress.Xpf.Core;
using DevExpress.Xpf.Grid;
using DevExpress.Xpf.Bars;
using log4net;
using Newtonsoft.Json.Serialization;
using System;
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 VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Common;
using VIZ.Package.Service;
using VIZ.Package.Storage;
using DevExpress.Xpf.Editors.Helpers;
using System.Windows.Input;
using VIZ.Framework.Common;
using System.Windows.Controls.Primitives;

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

        public PageCommandViewModel()
        {
            ApplicationDomainEx.ServiceManager.AddService(ViewServiceKeys.PAGE_COMMAND_SERVICE, this);

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

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

        /// <summary>
        /// 初始化命令
        /// </summary>
        private void InitCommand()
        {
            this.SaveCommand = new VCommand(this.Save);
        }

        /// <summary>
        /// 初始化消息
        /// </summary>
        private void InitMessage()
        {
            ApplicationDomainEx.MessageManager.Register<PageOpenMessage>(this, this.OnPageOpenMessage);
            ApplicationDomainEx.MessageManager.Register<PageSaveMessage>(this, this.OnPageSaveMessage);
            ApplicationDomainEx.MessageManager.Register<PageSaveAsMessage>(this, this.OnPageSaveAsMessage);
            ApplicationDomainEx.MessageManager.Register<HotkeyMessage>(this, this.OnHotkeyMessage);
        }

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

        /// <summary>
        /// 页命令控制器
        /// </summary>
        public PageCommandController pageCommandController = new PageCommandController();

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

        #region TakeCommand -- 上板命令

        private string takeCommand;
        /// <summary>
        /// 上板命令
        /// </summary>
        public string TakeCommand
        {
            get { return takeCommand; }
            set { takeCommand = value; this.RaisePropertyChanged(nameof(TakeCommand)); }
        }

        #endregion

        #region TakeContinueCommand -- 上版继续命令

        private string takeContinueCommand;
        /// <summary>
        /// 上版继续命令
        /// </summary>
        public string TakeContinueCommand
        {
            get { return takeContinueCommand; }
            set { takeContinueCommand = value; this.RaisePropertyChanged(nameof(TakeContinueCommand)); }
        }

        #endregion

        #region TakeOutCommand -- 下板命令

        private string takeOutCommand;
        /// <summary>
        /// 下板命令
        /// </summary>
        public string TakeOutCommand
        {
            get { return takeOutCommand; }
            set { takeOutCommand = value; this.RaisePropertyChanged(nameof(TakeOutCommand)); }
        }

        #endregion

        #region TakeUpdateCommand -- 更新命令

        private string takeUpdateCommand;
        /// <summary>
        /// 更新命令
        /// </summary>
        public string TakeUpdateCommand
        {
            get { return takeUpdateCommand; }
            set { takeUpdateCommand = value; this.RaisePropertyChanged(nameof(TakeUpdateCommand)); }
        }

        #endregion

        #region PageID -- 页ID

        private string pageID;
        /// <summary>
        /// 页ID
        /// </summary>
        public string PageID
        {
            get { return pageID; }
            set { pageID = value; this.RaisePropertyChanged(nameof(PageID)); }
        }

        #endregion

        #region Scene -- 场景

        private string scene;
        /// <summary>
        /// 场景
        /// </summary>
        public string Scene
        {
            get { return scene; }
            set { scene = value; this.RaisePropertyChanged(nameof(Scene)); }
        }

        #endregion

        #region PageType -- 页类型

        private string pageType;
        /// <summary>
        /// 页类型
        /// </summary>
        public string PageType
        {
            get { return pageType; }
            set { pageType = value; this.RaisePropertyChanged(nameof(pageType)); }
        }

        #endregion

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

        #region SaveCommand -- 保存命令

        /// <summary>
        /// 保存命令
        /// </summary>
        public VCommand SaveCommand { get; set; }

        /// <summary>
        /// 保存
        /// </summary>
        private void Save()
        {
            if (ApplicationDomainEx.CurrentPage == null)
                return;

            Guid templateIdOrPageId = ApplicationDomainEx.CurrentPage.GetTemplateIdOrPageId();

            PageCommandEntity entity = ApplicationDomainEx.ProjectDbContext.PageCommand.Find(p => p.PageID == templateIdOrPageId).FirstOrDefault();
            entity = entity ?? new PageCommandEntity();
            entity.PageID = templateIdOrPageId;
            entity.TakeCommand = this.TakeCommand;
            entity.TakeContinueCommand = this.TakeContinueCommand;
            entity.TakeOutCommand = this.TakeOutCommand;
            entity.TakeUpdateCommand = this.TakeUpdateCommand;

            ApplicationDomainEx.ProjectDbContext.PageCommand.Upsert(entity);

            // 发送弹出提示
            AlertMessage alertMessage = new AlertMessage();
            alertMessage.Message = "保存成功";
            ApplicationDomainEx.MessageManager.Send(alertMessage);
        }

        #endregion

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

        /// <summary>
        /// 页打开消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnPageOpenMessage(PageOpenMessage msg)
        {
            if (msg.Page is PageModel page)
            {
                this.PageID = page.GetPageNumString();
            }
            else
            {
                this.PageID = string.Empty;
            }

            this.Scene = msg.Page.Scene;
            this.PageType = msg.Page.PageType.GetDescription();

            Guid templateIdOrPageId = msg.Page.GetTemplateIdOrPageId();

            PageCommandEntity entity = ApplicationDomainEx.ProjectDbContext.PageCommand.Find(p => p.PageID == templateIdOrPageId).FirstOrDefault();

            this.TakeCommand = entity?.TakeCommand ?? string.Empty;
            this.TakeContinueCommand = entity?.TakeContinueCommand ?? string.Empty;
            this.TakeOutCommand = entity?.TakeOutCommand ?? string.Empty;
            this.TakeUpdateCommand = entity?.TakeUpdateCommand ?? string.Empty;
        }

        /// <summary>
        /// 页保存消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnPageSaveMessage(PageSaveMessage msg)
        {
            Guid templateIdOrPageId = msg.Page.GetTemplateIdOrPageId();

            PageCommandEntity entity = ApplicationDomainEx.ProjectDbContext.PageCommand.Find(p => p.PageID == templateIdOrPageId).FirstOrDefault();
            entity = entity ?? new PageCommandEntity();
            entity.PageID = templateIdOrPageId;
            entity.TakeCommand = this.TakeCommand;
            entity.TakeContinueCommand = this.TakeContinueCommand;
            entity.TakeOutCommand = this.TakeOutCommand;
            entity.TakeUpdateCommand = this.TakeUpdateCommand;

            ApplicationDomainEx.ProjectDbContext.PageCommand.Upsert(entity);
        }

        /// <summary>
        /// 页另存为消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnPageSaveAsMessage(PageSaveAsMessage msg)
        {
            Guid templateIdOrPageId = msg.Page.GetTemplateIdOrPageId();

            PageCommandEntity entity = ApplicationDomainEx.ProjectDbContext.PageCommand.Find(p => p.PageID == templateIdOrPageId).FirstOrDefault();
            entity = entity ?? new PageCommandEntity();
            entity.PageID = templateIdOrPageId;
            entity.TakeCommand = this.TakeCommand;
            entity.TakeContinueCommand = this.TakeContinueCommand;
            entity.TakeOutCommand = this.TakeOutCommand;
            entity.TakeUpdateCommand = this.TakeUpdateCommand;

            ApplicationDomainEx.ProjectDbContext.PageCommand.Upsert(entity);
        }

        /// <summary>
        /// 处理热键
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnHotkeyMessage(HotkeyMessage msg)
        {
            if (msg.Key == ApplicationDomainEx.HotKeyConfig.SaveOpendPageOrTemplateAndProject)
            {
                this.Save();
            }
        }

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

        /// <summary>
        /// 开始执行上板命令
        /// </summary>
        /// <param name="pageBase">页或模板</param>
        /// <param name="conn">连接</param>
        public void BeginExecuteTakeCommand(PageModelBase pageBase, ConnModel conn)
        {
            this.pageCommandController.BeginExecute(pageBase, conn, this.TakeCommand);
        }

        /// <summary>
        /// 开始执行继续命令
        /// </summary>
        /// <param name="pageBase">页或模板</param>
        /// <param name="conn">连接</param>
        public void BeginExecuteTakeContinueCommand(PageModelBase pageBase, ConnModel conn)
        {
            this.pageCommandController.BeginExecute(pageBase, conn, this.TakeContinueCommand);
        }

        /// <summary>
        /// 开始执行下板命令
        /// </summary>
        /// <param name="pageBase">页或模板</param>
        /// <param name="conn">连接</param>
        public void BeginExecuteTakeOutCommand(PageModelBase pageBase, ConnModel conn)
        {
            this.pageCommandController.BeginExecute(pageBase, conn, this.TakeOutCommand);
        }

        /// <summary>
        /// 开始执行更新命令
        /// </summary>
        /// <param name="pageBase">页或模板</param>
        /// <param name="conn">连接</param>
        public void BeginExecuteTakeUpdateCommand(PageModelBase pageBase, ConnModel conn)
        {
            this.pageCommandController.BeginExecute(pageBase, conn, this.TakeUpdateCommand);
        }

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