using DevExpress.Xpf.Grid.TreeList;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Service;
using VIZ.Package.Storage;

namespace VIZ.Package.Module
{
    /// <summary>
    /// 字段树视图模型
    /// </summary>
    public class FieldTreeViewModel : ViewModelBase, IFieldTreeService
    {
        public FieldTreeViewModel()
        {
            // 初始化命令
            this.InitCommand();

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

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

        /// <summary>
        /// 初始化命令
        /// </summary>
        private void InitCommand()
        {

        }

        /// <summary>
        /// 初始化消息
        /// </summary>
        private void InitMessage()
        {
            ApplicationDomainEx.MessageManager.Register<PageInitedMessage>(this, this.OnPageInitedMessage);
            ApplicationDomainEx.MessageManager.Register<ProjectCloseMessage>(this, this.OnProjectCloseMessage);
        }

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

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

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

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

        #region IsLoading -- 是否正在加载

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

        #endregion

        #region ControlObject -- 控制对象

        private ControlObjectModel controlObject;
        /// <summary>
        /// 控制对象
        /// </summary>
        public ControlObjectModel ControlObject
        {
            get { return controlObject; }
            set { controlObject = value; this.RaisePropertyChanged(nameof(ControlObject)); }
        }

        #endregion

        #region SelectedControlField -- 当前选中的控制字段

        private ControlFieldNodeModel selectedControlField;
        /// <summary>
        /// 当前选中的控制字段
        /// </summary>
        public ControlFieldNodeModel SelectedControlField
        {
            get { return selectedControlField; }
            set
            {
                // 尝试更新List的值
                this.TryUpdateControlFieldListValue();

                selectedControlField = value;
                this.RaisePropertyChanged(nameof(SelectedControlField));

                // 发送切换消息
                ControlFieldChangedMessage msg = new ControlFieldChangedMessage();
                msg.ControlObject = this.ControlObject;
                msg.ControlField = value;

                ApplicationDomainEx.MessageManager.Send(msg);
            }
        }

        #endregion

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

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

        /// <summary>
        /// 页初始化完成消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnPageInitedMessage(PageInitedMessage msg)
        {
            this.IsLoading = true;

            ThreadHelper.SafeRun(action: () =>
            {
                // 从本地数据库获取控制对象
                ControlObjectEntity entity = this.controlObjectService.GetControlObject(msg.Page)?.FirstOrDefault();
                ControlObjectModel controlObject = new ControlObjectModel();
                this.vizCommandControlObjectService.UpdateControlObjectModel(controlObject, entity);

                // 从本地数据库中获取字段值
                List<ControlFieldEntity> fields = this.controlObjectService.GetControlFields(msg.Page);
                controlObjectService.UpdateControlFieldValue(controlObject.AllFiledNodes, fields);

                WPFHelper.Invoke(() =>
                {
                    this.ControlObject = controlObject;
                });

                // 将当前值上至预览
                this.vizCommandControlObjectService.SetControlObject(ApplicationDomainEx.PreviewConn, this.ControlObject);

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

        /// <summary>
        /// 项目关闭时触发
        /// </summary>
        /// <param name="msg"></param>
        private void OnProjectCloseMessage(ProjectCloseMessage msg)
        {
            this.ControlObject = null;
            this.SelectedControlField = null;
        }

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

        /// <summary>
        /// 获取控制对象
        /// </summary>
        /// <returns>获取控制对象</returns>
        public ControlObjectModel GetControlObject()
        {
            return this.ControlObject;
        }

        /// <summary>
        /// 尝试更新控制字段List的值
        /// </summary>
        public void TryUpdateControlFieldListValue()
        {
            if (this.SelectedControlField == null || this.SelectedControlField.Type != VizControlFieldType.list)
                return;

            IFieldEditService service = ApplicationDomainEx.ServiceManager.GetService<IFieldEditService>(ViewServiceKeys.FIELD_EDIT_SERVICE);
            if (service != null)
            {
                this.SelectedControlField.Value = service.GetCurrentEditFieldValue();
            }
        }
    }
}