using log4net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Storage;

namespace VIZ.Package.Service
{
    /// <summary>
    /// Viz控制对象下载服务
    /// </summary>
    public class VizControlObjectDownloadService
    {
        /// <summary>
        /// 日志
        /// </summary>
        private readonly static ILog log = LogManager.GetLogger(typeof(VizControlObjectDownloadService));

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

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

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

        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="pageBases"></param>
        public void Load(List<PageModelBase> pageBases)
        {
            // 停止更新
            this.vizCommandService.SetEnabledUpdate(ApplicationDomainEx.PreviewConn, false);

            // 更新场景
            foreach (PageModelBase page in pageBases)
            {
                try
                {
                    Debug.WriteLine($"加载场景 开始 [ {page.Scene} ]");

                    // 执行加载
                    this.ExecuteLoadOnePage(page);

                    // 执行创建切换逻辑Geom
                    this.ExecuteCreateGeom(page);

                    Debug.WriteLine($"加载场景 结束 [ {page.Scene} ]");
                }
                catch (Exception ex)
                {
                    log.Error(ex);
                }
            }

            // 启用更新
            this.vizCommandService.SetEnabledUpdate(ApplicationDomainEx.PreviewConn, true);
        }

        /// <summary>
        /// 执行加载
        /// </summary>
        /// <param name="pageBase">模板或页</param>
        private void ExecuteLoadOnePage(PageModelBase pageBase)
        {
            if (pageBase == null)
                return;

            // 切换场景
            this.vizCommandService.SetObject(ApplicationDomainEx.PreviewConn, pageBase.ScenePath, pageBase.Layer);

            // 获取场景缩略图
            pageBase.ThumbnailBitmap = this.vizCommandService.GetSceneImage(ApplicationDomainEx.PreviewConn, pageBase.ScenePath);

            // 获取控制对象
            ControlObjectModel controlObject = this.vizCommandControlObjectService.GetControlObject(ApplicationDomainEx.PreviewConn);

            // 更新控制对象属性至页对象
            this.UpdateControlObject2PageModelBase(pageBase, controlObject);

            // 保存控制对象到本地
            this.controlObjectService.SaveControlObject(pageBase, controlObject);

            // 保存控制对象字段到本地
            this.controlObjectService.SaveControlFields(pageBase, controlObject.AllFiledNodes);
        }

        /// <summary>
        /// 执行创建切换逻辑Geom
        /// </summary>
        /// <remarks>
        /// 所有场景均生成GEOM
        /// </remarks>
        /// <param name="pageBase">模板或页</param>
        private void ExecuteCreateGeom(PageModelBase pageBase)
        {
            if (pageBase == null)
                return;

            ConnModel conn = ApplicationDomainEx.PreviewConn;

            // 获取控制对象ID
            List<string> ids = this.vizCommandControlObjectService.GetControlObjectIds(conn, VizScene.MAIN_SCENE);
            string objectId = ids.FirstOrDefault();

            if (string.IsNullOrWhiteSpace(objectId))
                return;

            objectId = objectId.Substring(1, objectId.Length - 1);

            // SCENE*TITLES/2022/YC/YC_CUP2*TREE*#32915 ADD BOTTOM
            string groupPath = this.vizCommandService.GroupAdd(conn, pageBase.ScenePath, objectId, VizGroupMoveDirection.BOTTOM);

            // SCENE*TITLES/2022/YC/YC_CUP2*TREE GET
            List<VizTreeNodeInfo> treeNodeList = this.vizCommandControlObjectService.GetTreeNodeList(conn, VizScene.MAIN_SCENE);
            VizTreeNodeInfo groupNode = treeNodeList.FirstOrDefault(p => p.Path == groupPath);
            if (groupNode == null)
                return;

            // #33608*NAME SET root
            this.vizCommandService.GroupSetName(conn, groupNode.Num, "root");
            // SCENE*TITLES/2022/YC/YC_CUP2*TREE*#32915 MOVE SCENE*TITLES/2022/YC/YC_CUP2*TREE*#33608 RIGHT
            this.vizCommandService.GroupMove(conn, pageBase.ScenePath, objectId, groupNode.Num, VizGroupMoveDirection.RIGHT);
            // #32915*FUNCTION*ControlObject*store_stops INVOKE
            this.vizCommandControlObjectService.ControlObjectStoreStops(conn, objectId);
            // SCENE*TITLES/2022/YC/YC_CUP2*TREE*#33608*GEOM GROUP
            this.vizCommandService.GeomGroup(conn, pageBase.ScenePath, groupNode.Num);
            // SCENE*TITLES/2022/YC/YC_CUP2*TREE*#33608*GEOM GET
            string geomID = this.vizCommandService.GeomGet(conn, pageBase.ScenePath, groupNode.Num);
            // GEOM*#33616 COPY GEOM*TITLES/2022/YC/YC_CUP2
            if (!this.vizCommandService.GeomCopy(conn, geomID, pageBase.ScenePath))
                return;
            // SCENE*TITLES/2022/YC/YC_CUP2*TREE*#33608*GEOM UNGROUP
            this.vizCommandService.GeomUnGroup(conn, pageBase.ScenePath, groupNode.Num);
            // SCENE*TITLES/2022/YC/YC_CUP2*TREE*#32915 MOVE SCENE*TITLES/2022/YC/YC_CUP2*TREE*#33608 BOTTOM
            this.vizCommandService.GroupMove(conn, pageBase.ScenePath, objectId, groupNode.Num, VizGroupMoveDirection.BOTTOM);
            // SCENE*TITLES/2022/YC/YC_CUP2*TREE*#33608 DELETE ALL
            this.vizCommandService.GroupDelete(conn, pageBase.ScenePath, groupNode.Num);
        }

        /// <summary>
        /// 更新控制对象属性至页对象
        /// </summary>
        /// <param name="pageBase">页对象</param>
        /// <param name="controlObject">控制对象</param>
        private void UpdateControlObject2PageModelBase(PageModelBase pageBase, ControlObjectModel controlObject)
        {
            pageBase.TransitionLogic = controlObject.TransitionLogic;
            pageBase.LayerIdentifier = controlObject.LayerIdentifier;
            pageBase.StateIdentifier = controlObject.StateIdentifier;
            pageBase.BackgroundScene = controlObject.BackgroundScene;
        }
    }
}
