using Newtonsoft.Json;
using SYNC_SAP_MES;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

/// <summary>
/// SlMesDbIterface
/// </summary>
namespace SYNC_SAP_MES
{
    /// <summary>
    /// SyncFunc_From_SAP
    /// </summary>
    public class SyncFunc_From_SAP
    {
        /// <summary>
        /// 同步的年月日
        /// </summary>
        public static string SyncDate = "";
        /// <summary>
        /// 同步的变更时间
        /// </summary>
        public static string SyncTime = "";
        /// <summary>
        /// 发动机要生成流水号的起始流水号
        /// </summary>
        public static int EngineFlowNo = 0;
        /// <summary>
        /// 发动机要生成流水号的起始流水号
        /// 的变更时间
        /// </summary>
        public static string EngineFlowNoTime = "";
        /// <summary>
        /// 当前次数，用于刷新计数
        /// </summary>
        public static int CurrCount = 0;
        /// <summary>
        /// 同步中...
        /// </summary>
        public static bool IsSyncing = false;
        /// <summary>
        /// 同步执行任务
        /// </summary>
        public static void SyncTask_SAP()
        {
            //new Thread(new ThreadStart(delegate ()
            //{
            //    while (true)
            //    {
            //        try
            //        {
            //            if (CurrCount <= 0)
            //            {
            //                SyncFunc_From_SAP.SyncDataOperationTask("设定时间");
            //                CurrCount = PP.ReachSyncCount;
            //            }
            //            CurrCount--;
            //        }
            //        catch (Exception) { }
            //        Thread.Sleep(1000 * 60 * 60); //10分钟
            //    }
            //}))
            //{ IsBackground = true }.Start();

            new Thread(new ThreadStart(delegate ()
            {
                while (true)
                {
                    try
                    {
                        SyncFunc_From_SAP.SyncBarCodeDataOperationTask("周期执行");
                    }
                    catch (Exception) { }
                    Thread.Sleep(1000 * 1); //1秒
                }
            }))
            { IsBackground = true }.Start();
        }


        /// <summary>
        /// SyncGuide
        /// </summary>
        /// <param name="call"></param>
        public static void SyncDataOperationTask(object call)
        {
            var mode = (string)call;
            if (IsSyncing == false)
            {
                IsSyncing = true;
                try
                {
                    var dt_01 = DateTime.Now;
                    PP.main.ShowError($"[{mode}]AMS开始同步...");
                    Move_Mes_DataOperation();
                    var dt_02 = DateTime.Now;
                    PP.main.ShowError($"[{mode}]AMS已完成一次同步！！总耗时：{(dt_02 - dt_01).TotalMilliseconds.ToString("0.")} （ms）");
                    PP.main.ShowError($"");
                    PP.main.ShowError($"\r\n");
                }
                catch (Exception  err)
                {
                    PP.main.ShowError($"AMS数据同步出错！{err.Message}");
                }
                IsSyncing = false;
            }
            else
            {
                PP.main.ShowError("您正在同步操作，不能重复操作！");
            }
        }

        /// <summary>
        /// SyncBarCodeGuide
        /// </summary>
        /// <param name="call"></param>
        public static void SyncBarCodeDataOperationTask(object call)
        {
            var mode = (string)call;
            if (IsSyncing == false)
            {
                IsSyncing = true;
                try
                {
                    var dt_01 = DateTime.Now;
                    //PP.main.ShowError($"[{mode}]AMS开始同步...");
                    Move_Mes_BarCode_DataOperation();
                    var dt_02 = DateTime.Now;
                    //PP.main.ShowError($"[{mode}]AMS已完成一次同步！！总耗时：{(dt_02 - dt_01).TotalMilliseconds.ToString("0.")} （ms）");
                    //PP.main.ShowError($"");
                    //PP.main.ShowError($"\r\n");
                }
                catch (Exception err)
                {
                    PP.main.ShowError($"AMS扫码数据同步出错！{err.Message}");
                }
                IsSyncing = false;
            }
            else
            {
                PP.main.ShowError("您正在扫码数据同步操作，不能重复操作！");
            }
        }

        /// <summary>
        /// SyncBarCode
        /// </summary>
        private static void Move_Mes_BarCode_DataOperation()
        {
            //OnLineStatus_Check();

            //lineId，计划产线id，string，必填，如一号厂总装线：120000001
            //startDate，计划开始时间，date，必填
            //isLocked，计划状态（是否已锁定），1代表未锁定，3代表已锁定，非必填
            var LineID = "120000001";
            //var StartDate = "2022-06-28";
            var StartDate = SyncDate;
            var isLocked = "3";
            try
            {
                //StartDate = "2024-09-06";
                var PlanData_From_SAP = CALL_Interfalce_WebAPI.Get_BarCode_Plans_ByWebAPI(LineID, StartDate);
                var res = Sync_BarCode_ProductPlan_To_AMS(LineID, StartDate, PlanData_From_SAP);
            }
            catch (Exception err)
            {
                PP.main.ShowError($"【{LineID}_{StartDate}】生产计划读取失败，{err.Message}");
            }
        }

        /// <summary>
        /// Sync
        /// </summary>
        private static void Move_Mes_DataOperation()
        {
            //OnLineStatus_Check();

            //lineId，计划产线id，string，必填，如一号厂总装线：120000001
            //startDate，计划开始时间，date，必填
            //isLocked，计划状态（是否已锁定），1代表未锁定，3代表已锁定，非必填
            var LineID = "120000001";
            //var StartDate = "2022-06-28";
            var StartDate = SyncDate;
            var isLocked = "3";
            try
            {
                //StartDate = "2024-09-09";
                var PlanData_From_SAP = CALL_Interfalce_WebAPI.Get_Plans_ByWebAPI(LineID, StartDate, isLocked);
                var res = Sync_ProductPlan_To_AMS(LineID, StartDate, PlanData_From_SAP);
            }
            catch (Exception err)
            {
                PP.main.ShowError($"【{LineID}_{StartDate}】生产计划读取失败，{err.Message}");
            }
        }

        public static bool Sync_ProductPlan_To_AMS(string LineID,string startDate, SyncPlan_WebAPI_ResponseBody PlanData)
        {
            var res_success = PlanData.code == "200" ? true : false;
            var res_Message = PlanData.message;
            if (res_success)
            {
                /*
                (name = "productCode", value = "发动机编号")
                (name = "itemCode", value = "订货号")
                (name = "itemId", value = "订货号Id")
                (name = "productType", value = "机型")
                (name = "wipEntityId", value = "工单ID")
                (name = "wipEntityName", value = "工单号")
                (name = "bomHeaderId", value = "bom头id")
                (name = "mesPlanOrder", value = "mes计划顺序")
                (name = "erpStartDate", value = "计划开始时间")
                (name = " mesStartDate", value = "总装上线扫描时间")
                (name = "isLocked", value = "计划状态")
                */
                var min_EngineNo = PlanData.Data.Min(s=>s.productCode);
                var max_EngineNo = PlanData.Data.Max(s=>s.productCode);

                var sql_AMS_Plan = $" SELECT [发动机编号],[订货号],[订货号ID],[机型号],[工单ID],[工单号],[BOM头ID],[MES计划顺序],[计划开始时间]," +
                    $"[总装上线扫描时间],[计划状态],[计划同步时间],[执行状态],[LineID],[AMS计划顺序] FROM [潍柴_接口_生产计划_执行计划] " +
                    $" where [发动机编号] >='{min_EngineNo}' and [发动机编号] <='{max_EngineNo}' order by AID";
                SqlOperation.ExecuteSql(sql_AMS_Plan, out DataTable dt_PlanInAMS, out string err1);
                DataTable dt_NewPlans = dt_PlanInAMS.Clone();
                dt_NewPlans.TableName = "潍柴_接口_生产计划_执行计划";

                int maxSort = Get_AMS_MaxSort();

                for (int i = 0; i < PlanData.Data.Count; i++)
                {
                    var check_ifExist = dt_PlanInAMS.Select($"发动机编号='{PlanData.Data[i].productCode}'");
                    if (check_ifExist.Length > 0)
                    {
                        continue;
                    }
                    DataRow newPlan= dt_NewPlans.NewRow();
                    newPlan["发动机编号"] = PlanData.Data[i].productCode;
                    newPlan["订货号"] = PlanData.Data[i].itemCode;
                    newPlan["订货号ID"] = PlanData.Data[i].itemId;
                    newPlan["机型号"] = PlanData.Data[i].productType;
                    newPlan["工单ID"] = PlanData.Data[i].wipEntityId;
                    newPlan["工单号"] = PlanData.Data[i].wipEntityName;
                    newPlan["BOM头ID"] = PlanData.Data[i].bomHeaderId;
                    newPlan["MES计划顺序"] = PlanData.Data[i].mesPlanOrder;
                    newPlan["计划开始时间"] = PlanData.Data[i].erpStartDate;
                    if(PlanData.Data[i].mesStartDate != null) newPlan["总装上线扫描时间"] = PlanData.Data[i].mesStartDate;
                    newPlan["计划状态"] = PlanData.Data[i].isLocked;
                    newPlan["计划同步时间"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    newPlan["执行状态"] = 1;
                    newPlan["LineID"] = LineID;
                    newPlan["AMS计划顺序"] = maxSort + i;

                    dt_NewPlans.Rows.Add(newPlan);
                }

                if (dt_NewPlans.Rows.Count > 0)
                {
                    SqlOperation.SqlbulkcopyInsert(dt_NewPlans, out string err);
                    SqlOperation.ExecuteSql($"update 潍柴_接口_生产计划_标记 set [日期]='{startDate}',[更新时间]='{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}'", out string err2);

                    if (err.Length==0) PP.main.ShowError($"【{LineID}_{startDate}】计划数据读取成功！新增数量【{dt_NewPlans.Rows.Count}】\r\n");
                    else PP.main.ShowError($"【{LineID}_{startDate}】计划数据读取失败，{res_Message}");
                }
                else PP.main.ShowError($"【{LineID}_{startDate}】计划数据读取成功！新增数量【{dt_NewPlans.Rows.Count}】\r\n");
                return true;

            }
            else
            {
                PP.main.ShowError($"【{LineID}_{startDate}】生产计划读取失败，{res_Message}");
                return false;
            }
        }

        public static int Get_AMS_MaxSort()
        {
            var sql = $" SELECT max(AMS计划顺序 + 1) as maxSort FROM 潍柴_接口_生产计划_执行计划";
            SqlOperation.ExecuteSql(sql, out DataTable maxSortDt, out string err1);
            int maxSort = Convert.ToInt32(maxSortDt.Rows[0]["maxSort"]);
            return maxSort;
        }

        public static bool Sync_BarCode_ProductPlan_To_AMS(string LineID, string startDate, SyncPlan_WebAPI_ResponseBody PlanData)
        {
            var res_success = PlanData.code == "200" ? true : false;
            var res_Message = PlanData.message;
            if (res_success)
            {
                /*
                (name = "productCode", value = "发动机编号")
                (name = "itemCode", value = "订货号")
                (name = "itemId", value = "订货号Id")
                (name = "productType", value = "机型")
                (name = "wipEntityId", value = "工单ID")
                (name = "wipEntityName", value = "工单号")
                (name = "bomHeaderId", value = "bom头id")
                (name = "mesPlanOrder", value = "mes计划顺序")
                (name = "erpStartDate", value = "计划开始时间")
                (name = "mesStartDate", value = "总装上线扫描时间段的开始时间")
                (name = "isLocked", value = "计划状态")
                */

                var min_EngineNo = PlanData.Data.Min(s => s.productCode);
                var max_EngineNo = PlanData.Data.Max(s => s.productCode);

                string inWhere = "(";
                if (PlanData.Data.Count > 0) {
                    PlanData.Data.ForEach(item =>
                    {
                        inWhere = inWhere += $"'{item.productCode}',";
                    });
                    inWhere = inWhere.Remove(inWhere.Length - 1) + ")";
                }

                int maxSort = Get_AMS_MaxSort();

                var sql_AMS_Plan = $" SELECT [发动机编号],[订货号],[订货号ID],[机型号],[工单ID],[工单号],[BOM头ID],[MES计划顺序],[计划开始时间]," +
                    $"[总装上线扫描时间],[计划状态],[计划同步时间],[执行状态],[LineID],[AMS计划顺序] FROM [潍柴_接口_生产计划_执行计划] " +
                    $" where [发动机编号] in {inWhere} order by AID";
                SqlOperation.ExecuteSql(sql_AMS_Plan, out DataTable dt_PlanInAMS, out string err1);
                DataTable dt_NewPlans = dt_PlanInAMS.Clone();
                dt_NewPlans.TableName = "潍柴_接口_生产计划_执行计划";


                for (int i = 0; i < PlanData.Data.Count; i++)
                {
                    var check_ifExist = dt_PlanInAMS.Select($"发动机编号='{PlanData.Data[i].productCode}'");
                    if (check_ifExist.Length > 0)
                    {
                        continue;
                    }
                    DataRow newPlan = dt_NewPlans.NewRow();
                    newPlan["发动机编号"] = PlanData.Data[i].productCode;
                    newPlan["订货号"] = PlanData.Data[i].itemCode;
                    newPlan["订货号ID"] = PlanData.Data[i].itemId;
                    newPlan["机型号"] = PlanData.Data[i].productType;
                    newPlan["工单ID"] = PlanData.Data[i].wipEntityId;
                    newPlan["工单号"] = PlanData.Data[i].wipEntityName;
                    newPlan["BOM头ID"] = PlanData.Data[i].bomHeaderId;
                    newPlan["MES计划顺序"] = PlanData.Data[i].mesPlanOrder;
                    newPlan["计划开始时间"] = PlanData.Data[i].erpStartDate;
                    if (PlanData.Data[i].mesStartDate != null) newPlan["总装上线扫描时间"] = PlanData.Data[i].mesStartDate;
                    newPlan["计划状态"] = PlanData.Data[i].isLocked;
                    newPlan["计划同步时间"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    newPlan["执行状态"] = 1;
                    newPlan["LineID"] = LineID;
                    newPlan["AMS计划顺序"] = maxSort;
                    maxSort++;
                    dt_NewPlans.Rows.Add(newPlan);
                }

                if (dt_NewPlans.Rows.Count > 0)
                {
                    SqlOperation.SqlbulkcopyInsert(dt_NewPlans, out string err);
                    SqlOperation.ExecuteSql($"update 潍柴_接口_生产计划_标记 set [日期]='{startDate}',[更新时间]='{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}'", out string err2);

                    if (err.Length == 0)
                    {
                        PP.main.ShowError($"【{LineID}_{startDate}】计划数据读取成功！新增数量【{dt_NewPlans.Rows.Count}】");
                        // 发送给MisFun接口 重新申请上线 接受反馈值记录到日志
                        SyncPlan_WebAPI_ResponseBody res = CALL_Interfalce_WebAPI.Put_MisFun_ByWebAPI("1","OP3020");
                        if(res.code == "200") PP.main.ShowError($"【自动申请上线成功】Code:{res.code} msg:{res.message}\r\n");
                        else PP.main.ShowError($"【自动申请上线失败】Code:{res.code} msg:{res.message}\r\n");

                    }
                    else PP.main.ShowError($"【{LineID}_{startDate}】计划数据读取失败，{res_Message}");
                }
                //else PP.main.ShowError($"【{LineID}_{startDate}】计划数据读取成功！新增数量【{dt_NewPlans.Rows.Count}】\r\n");
                return true;

            }
            else
            {
                PP.main.ShowError($"【{LineID}_{startDate}】生产计划读取失败，{res_Message}");
                return false;
            }
        }



        /// <summary>
        /// 检查在线状态
        /// </summary>
        public static void OnLineStatus_Check()
        {
            try
            {
                PP.OnLine_Sql = SqlOperation.ExecuteSql("select getdate()", out DataTable dt, out string error);
            }
            catch (Exception err)
            {
                PP.OnLine_Sql = false;
            }
            
            try
            {
                //PP.OnLine_SAP = READ_SAP.GetMCode().Rows.Count > 0 ? true : false;
                PP.OnLine_SAP = Ping("mes4api.weichai.com"); 
            }
            catch (Exception err)
            {
                PP.OnLine_SAP = false;
            }
        }

        private static bool Ping(string ip)
        {
            return new Ping().Send(ip).Status == IPStatus.Success ? true : false;
        }



    }
}
