using DC_A95;
using ExternalDataSync;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using SystemFramework;
using WebApi;

namespace MesWork
{
    /// <summary>
    /// 程式启动
    /// </summary>
    public partial class MesWorkForm
    {
        /// <summary>
        /// 从这里启动
        /// </summary>
        /// <param name="e"></param>
        protected override void OnShown(EventArgs e)
        {
        }

        public void OnStart(params object[] o)
        {
            //【1】系统基本参数设定
            ThreadPool.SetMaxThreads(workerThreads, completionPortThreads);
            Never_Know.Hello_You_All_Never_Know = Hello_You_All_Never_Know;

            // 加载信号表（按设备类型对应表展开多工位）
            var (dt_Tag_Mes, dt_Device) = BuildSignalTable(BasicDataTableFile);

            // 保存工位名称列表及显示名映射（供UC_Weighing标题使用）
            StationOpNames = new System.Collections.Generic.List<string>();
            StationDisplayNames = new System.Collections.Generic.Dictionary<string, string>(System.StringComparer.OrdinalIgnoreCase);
            int stIdx = 1;
            foreach (System.Data.DataRow row in dt_Device.Rows)
            {
                string opName = row["工位号"].ToString().Trim();
                string dataSource = row["数据来源"].ToString().Trim(); // 称重位1, 称重位2
                StationOpNames.Add(opName);
                // 显示格式："OP10-称重位1"
                StationDisplayNames[opName] = $"{opName}-{dataSource}";
                stIdx++;
            }
            ValidateStationConfig();

            LoadOPCData(dt_Tag_Mes, dt_Device, IsDemoMesServer, IsWriteMonitorLog, true, false, out string error);
            if (error.Length > 0)
            {
                MessageBox.Show($"加载信号产生错误,程序不能启动！！错误：{error}");
                Process.GetCurrentProcess().Kill();
            }

            Thread.Sleep(200);
            StartServer();
            Thread.Sleep(200);
            First_TagMonitor();

            var task1 = new Thread(new ThreadStart(Loop_SelectAlarmShow));
            task1.IsBackground = true;
            task1.Start();

            // Loop_ReadRealPageShow 已移除，PLC信号显示将在 UC_Weighing 中实现
            // var task2 = new Thread(new ThreadStart(Loop_ReadRealPageShow));
            // task2.IsBackground = true;
            // task2.Start();


            initServer = new InitServer(MesWorkForm.WebApi_Port);

            B_DB_Opera.SaveLog_Request(Curr_Station, Log_Type.ZK_Login, "", Log_FromAndTo.ZK, Log_FromAndTo.ZK, $"称重系统启动成功！WebPort:[{MesWorkForm.WebApi_Port}]", out long AID);
        }

        /// <summary>
        /// 校验App.config中的逻辑工位必须能匹配Excel启用工位，避免工位号配错后继续运行。
        /// </summary>
        private static void ValidateStationConfig()
        {
            string station1 = Station1OpName?.Trim();
            string station2 = Station2OpName?.Trim();
            if (string.IsNullOrWhiteSpace(station1) || string.IsNullOrWhiteSpace(station2))
            {
                MessageBox.Show("App.config未配置Station1OpName或Station2OpName，程序不能启动。");
                Process.GetCurrentProcess().Kill();
            }

            if (string.Equals(station1, station2, StringComparison.OrdinalIgnoreCase))
            {
                MessageBox.Show($"App.config中Station1OpName和Station2OpName不能相同，当前均为[{station1}]，程序不能启动。");
                Process.GetCurrentProcess().Kill();
            }

            bool hasStation1 = StationOpNames.Exists(x => string.Equals(x, station1, StringComparison.OrdinalIgnoreCase));
            bool hasStation2 = StationOpNames.Exists(x => string.Equals(x, station2, StringComparison.OrdinalIgnoreCase));
            if (!hasStation1 || !hasStation2)
            {
                string excelStations = string.Join("、", StationOpNames);
                MessageBox.Show($"App.config工位配置与SignalTable_CZ.xlsx不一致，程序不能启动。\r\nStation1OpName={station1}\r\nStation2OpName={station2}\r\nExcel启用工位={excelStations}");
                Process.GetCurrentProcess().Kill();
            }
        }




        /// <summary>
        /// 构建信号表：读取Excel模板，按「设备类型对应表」的工位配置展开
        /// 每个工位独立克隆一份模板，TagID加工位号前缀（如 OP10_TAG_0000001），
        /// 并填充对应的 工位号、数据来源、IP、DB
        /// </summary>
        /// <param name="excelFile">信号表Excel文件路径</param>
        /// <returns>(展开后的信号表, 设备类型对应表)</returns>
        private static (DataTable dtTagMes, DataTable dtDevice) BuildSignalTable(string excelFile)
        {
            // 读取设备类型对应表（所有启用的工位）
            var dtDevice = NPOITest.ExeclHelper.ExcelToDataTable(excelFile, "设备类型对应表", true)
                           .Select("是否启用='1'").CopyToDataTable();

            // 读取 MES_基本变量原始数据 模板（取全部启用行作为模板）
            var dtTemplate = NPOITest.ExeclHelper.ExcelToDataTable(excelFile, "MES_基本变量原始数据", true)
                             .Select("是否启用='1'").CopyToDataTable();

            // 按工位数量克隆模板
            var dtTagMes = dtTemplate.Clone();
            foreach (DataRow devRow in dtDevice.Rows)
            {
                string stationNo  = devRow["工位号"].ToString().Trim();     // OP10, OP20
                string dataSource = devRow["数据来源"].ToString().Trim();   // 称重位1, 称重位2
                string deviceIP   = devRow["设备IP"].ToString().Trim();     // 192.168.0.1
                string deviceDB   = devRow["DB"].ToString().Trim();        // DB1310, DB1311

                // 提取纯DB号 ("DB1310" → "1310"，若本身是数字则保持)
                //string dbNumber = deviceDB.StartsWith("DB", StringComparison.OrdinalIgnoreCase)
                //                  ? deviceDB.Substring(2) : deviceDB;
                string dbNumber = deviceDB;

                foreach (DataRow tplRow in dtTemplate.Rows)
                {
                    var newRow = dtTagMes.NewRow();
                    for (int c = 0; c < dtTemplate.Columns.Count; c++)
                        newRow[c] = tplRow[c];

                    // 覆盖关键字段
                    newRow["TagID"]   = $"{stationNo}_{tplRow["TagID"].ToString().Trim()}";
                    newRow["工位号"]   = stationNo;
                    newRow["数据来源"] = dataSource;
                    newRow["IP"]      = deviceIP;
                    newRow["DBName"]      = dbNumber;

                    dtTagMes.Rows.Add(newRow);
                }
            }

            return (dtTagMes, dtDevice);
        }

    }
}
