using DevExpress.Xpf.Core;
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.Service;
using VIZ.Package.Storage;

namespace VIZ.Package.Module
{
    /// <summary>
    /// Viz预览控制器
    /// </summary>
    public class VizPreviewController
    {
        /// <summary>
        /// 日志
        /// </summary>
        private readonly static ILog log = LogManager.GetLogger(typeof(VizPreviewController));

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

        /// <summary>
        /// Viz预览重启等待时间（单位：毫秒）
        /// </summary>
        private int VIZ_PREVIEW_RESTART_WAIT = ApplicationDomainEx.IniStorage.GetValue<VizConfig, int>(p => p.VIZ_PREVIEW_RESTART_WAIT);

        /// <summary>
        /// Viz预览控制器
        /// </summary>
        /// <param name="viewModel">视图模型</param>
        public VizPreviewController(VizPreviewViewModel viewModel)
        {
            this.ViewModel = viewModel;
        }

        /// <summary>
        /// 视图
        /// </summary>
        public VizPreviewViewModel ViewModel { get; private set; }

        /// <summary>
        /// 启动VIZ引擎
        /// </summary>
        /// <param name="view">视图</param>
        /// <param name="path">引擎路径</param>
        /// <param name="conn">连接模型</param>
        public void StartVizEngine(VizPreviewView view, string path, ConnModel conn)
        {
            // 操作日志
            this.recordLogService.AppendLog(ApplicationConstants.APPLICATION_GROUP_NAME, RecordLogOperate.System, RecordLogTrigger.System, RecordLogConstants.SYSTEM_SET_UP_PREVIEW);

            var dpi = WPFHelper.GetDpiByGraphics();
            int width = (int)(view.host.ActualWidth * (dpi.X / 96d));
            int height = (int)(view.host.ActualHeight * (dpi.Y / 96d));

            ImageHelper.AdjustSize(width, height, 1920, 1080, out width, out height);

            IntPtr hWnd = view.host.ContainerFormHandle;
            IntPtr vizHandle = IntPtr.Zero;

            ThreadHelper.SafeRun(() =>
            {
                VizConfigEntity vizConfig = ApplicationDomainEx.VizConfig;

                // Step 1. 启动进程
                ApplicationDomainEx.VizPreviewProcess = new Process();
                ApplicationDomainEx.VizPreviewProcess.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(path);
                ApplicationDomainEx.VizPreviewProcess.StartInfo.FileName = System.IO.Path.GetFileName(path);
                //VIZ3:  " -o -P -db Guest:@localhost/VizDbServer:19396"
                //VIZ4:  "-u1 -n -M -e Guest:@localhost/VizDbServer:19396"

                if (vizConfig.EngineFullType == EngineFullType.VIZ_Eng3)
                {
                    ApplicationDomainEx.VizPreviewProcess.StartInfo.Arguments = $" -o -P -db {vizConfig.VIZ_UserName}:@{vizConfig.VIZ_IP}/{vizConfig.GH_ServerName}:{vizConfig.GH_Port}";
                }
                if (vizConfig.EngineFullType == EngineFullType.VIZ_Eng4)
                {
                    ApplicationDomainEx.VizPreviewProcess.StartInfo.Arguments = $" -o -P -db {vizConfig.VIZ_UserName}:@{vizConfig.VIZ_IP}/{vizConfig.GH_ServerName}:{vizConfig.GH_Port}";
                    //ApplicationDomainEx.VizPreviewProcess.StartInfo.Arguments = $" -u1 -n -M -e {vizConfig.VIZ_UserName}:@{vizConfig.VIZ_IP}/{vizConfig.GH_ServerName}:{vizConfig.GH_Port}";
                }

                ApplicationDomainEx.VizPreviewProcess.StartInfo.UseShellExecute = true;
                ApplicationDomainEx.VizPreviewProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                ApplicationDomainEx.VizPreviewProcess.Start();

                // Step 2. 连接VIZ
                do
                {
                    System.Threading.Thread.Sleep(1000);

                } while (!conn.EndpointManager.Connect());

                // Step 3. 切换配置
                System.Threading.Thread.Sleep(VIZ_PREVIEW_RESTART_WAIT);

                conn.EndpointManager.Request($"CONFIGURATION*DATABASE*NAMESERVER SET {vizConfig.GH_IP}");
                conn.EndpointManager.Request($"CONFIGURATION*DATABASE*SERVER SET {vizConfig.GH_ServerName}");
                conn.EndpointManager.Request($"CONFIGURATION*DATABASE*USER SET {vizConfig.VIZ_UserName}");
                conn.EndpointManager.Request($"CONFIGURATION*DATABASE*PW SET {vizConfig.VIZ_Password}");
                conn.EndpointManager.Request($"CONFIGURATION SAVE");

                conn.EndpointManager.Request($"DATABASE CONNECT {vizConfig.VIZ_UserName}: {vizConfig.GH_ServerName} {vizConfig.GH_IP}");

                // Step 3. 发送渲染命令
                do
                {
                    System.Threading.Thread.Sleep(VIZ_PREVIEW_RESTART_WAIT);

                    if (vizConfig.EngineFullType == EngineFullType.VIZ_Eng3)
                    {
                        string cmd = $"RENDERER WINDOW_OPEN_ON_PARENT 0x{hWnd.ToString("X6")} {width} {height} ONAIR";
                        string result = conn.EndpointManager.Request(cmd);
                    }
                    else if (string.IsNullOrWhiteSpace(ApplicationDomainEx.VizPreviewRenderer) && vizConfig.EngineFullType == EngineFullType.VIZ_Eng4)
                    {
                        // 创建 EDITOR
                        ApplicationDomainEx.VizPreviewRenderer = conn.EndpointManager.Request("EDITOR CREATE RENDERER");
                        string cmd = $"{ApplicationDomainEx.VizPreviewRenderer} WINDOW_OPEN_ON_PARENT 0x{hWnd.ToString("X6")} {width} {height} ONAIR";
                        string result = conn.EndpointManager.Request(cmd);
                    }

                    WPFHelper.Invoke(() =>
                    {
                        vizHandle = view.host.TargetWindowHandle;
                    });

                } while (vizHandle == IntPtr.Zero);

                // Step 4. 启动完成
                this.BeginSendVizEngineReadlyMessage();
            });
        }

        /// <summary>
        /// 开始，采用其他引擎
        /// </summary>
        /// <param name="view">视图</param>
        /// <param name="path">引擎路径</param>
        /// <param name="conn">连接模型</param>
        public void StartVizEngineWithOther(VizPreviewView view, string path, ConnModel conn)
        {
            ThreadHelper.SafeRun(() =>
            {
                VizConfigEntity vizConfig = ApplicationDomainEx.VizConfig;

                // Step 1. 连接VIZ
                conn.EndpointManager.Connect();

                // Step 2. 启动完成
                this.BeginSendVizEngineReadlyMessage();
            });
        }

        /// <summary>
        /// 发送Viz引擎准备完毕消息
        /// </summary>
        private void BeginSendVizEngineReadlyMessage()
        {
            WPFHelper.BeginInvoke(() =>
            {
                // 设置
                ApplicationDomainEx.IsVizPreviewReadly = true;

                // 发送引擎嵌入完成消息
                VizPreviewReadyMessage msg = new VizPreviewReadyMessage();
                ApplicationDomainEx.MessageManager.Send(msg);
            });
        }
    }
}