using BasicData;
using DataLinkMesWork;
using MesDataFunction;
using MesServerFunctions;
using MesServerWork;
using MisDataFunDll;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using SystemFramework;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskBand;

namespace MisDataSaveDateMesRead
{
    public partial class Funtion
    {


        /// <summary>
        /// 允许保存(针对半自动和手动压装工位)
        /// </summary>
        /// <param name="OpName"></param>
        /// <param name="tagValue"></param>
        public static int MesRead(string opName, string tagValue, string tagid, bool isCheck = false)
        {
            return SaveQualityData(opName, Convert.ToInt32(tagValue), tagid, isCheck);
        }

        public static void MesRead_Cell(string[] engineIDList, string opName, string tagValue, string tagid, int qualityMask)
        {
            int id_tagCF;
            int engineTypeID = 0;

            string engineType = "";
            string partPallet = "";
            DataTable dt_WWW;
            Hashtable valueList;
            try
            {
                //读取工位全部数据
                var tagValues = MIS_BASE.ReadPLC_OpName(opName); 
                //过滤出来质量数据 //获得带合格标志的质量数据
                valueList = ReadPLC_OpName_Qd(tagValues);//已修改
                //获得带基本信息的质量数据表
                GetQualityDataTable(valueList, out dt_WWW);
                // 以下是排序
                DataView dv = new DataView(dt_WWW);
                dv.Sort = "TagID DESC";
                // 转换回 DataTable
                DataTable dt_WWW_Sort = dv.ToTable();

                for (int i = 0; i < engineIDList.Length; i++) 
                {
                    string engineID = engineIDList[i];
                    var dt_WWW_Sort_Filter = dt_WWW_Sort.Select($"测量位置 like '*${(i + 1)}*' or 测量位置 like '*$ALL*'").CopyToDataTable();

                    //保存质量数
                    MisDataFun.BaseData_tagTable_QualityData_B5A_IndexInsert_cell(engineID, tagid, engineType, engineTypeID, opName, qualityMask, partPallet, out id_tagCF);
                    MisDataFun.BaseData_tagTable_QualityData_B5A_Insert_cell(id_tagCF, engineTypeID, engineID, opName, dt_WWW_Sort_Filter, false);

                    if (MisDataFun.GetSpecialOpExist(opName, "存质量电芯条码工位")) MisDataFun.BaseData_tagTable_QualityData_B5A_Insert_OP170Status(id_tagCF, engineTypeID, engineID, $"72200001", engineID.ToString(), qualityMask, opName);
                }
            }
            catch (Exception err)
            {

            }

        }

        public static string GetRealTimeQualityData(string opName)
        {
            string message = "";
            DataTable dt1 = new DataTable();
            DataTable dt_WWW;
            DataTable dt_WWW_Copy1;
            DataTable dt_WWW_Copy2;
            Hashtable valueList;
            try
            {
                //读取工位全部数据
                var tagValues = MIS_BASE.ReadPLC_OpName(opName); 
                //过滤出来质量数据，获得带合格标志的质量数据
                valueList = ReadPLC_OpName_Qd(tagValues);

                //获得带基本信息的质量数据表
                GetQualityDataTable(valueList, out dt_WWW);

                dt_WWW_Copy1 = dt_WWW.Copy().Select("变量排序 = 1").CopyToDataTable();
                DataView dv1 = dt_WWW_Copy1.DefaultView;
                dv1.Sort = "列位置 DESC";
                dt_WWW_Copy1 = dv1.ToTable();

                dt_WWW_Copy2 = dt_WWW.Copy().Select("变量排序 = 2").CopyToDataTable();
                DataView dv2 = dt_WWW_Copy2.DefaultView;
                dv2.Sort = "列位置 DESC";
                dt_WWW_Copy2 = dv2.ToTable();

                dt1.Columns.Add("列位置", System.Type.GetType("System.String"));
                dt1.Columns.Add("测量项目1", System.Type.GetType("System.String"));
                dt1.Columns.Add("测量项目2", System.Type.GetType("System.String"));
                dt1.Columns.Add("合格标志", System.Type.GetType("System.String"));
                dt1.Columns.Add("名称", System.Type.GetType("System.String"));

                for (int i = 0; i < dt_WWW_Copy1.Rows.Count; i++)
                {
                    if (Convert.ToInt32(dt_WWW_Copy1.Rows[i]["TagValue"]) > 45 )
                    {
                        var dr = dt1.NewRow();
                        dr["列位置"] = dt_WWW_Copy1.Rows[i]["列位置"].ToString();
                        dr["测量项目1"] = dt_WWW_Copy1.Rows[i]["TagValue"].ToString();
                        dr["合格标志"] = "1";
                        dr["名称"] = dt_WWW_Copy1.Rows[i]["测量项目"].ToString();
                        dt1.Rows.Add(dr);
                    }
                }
                for (int i = 0; i < dt_WWW_Copy2.Rows.Count; i++)
                {
                    if (Convert.ToInt32(dt_WWW_Copy2.Rows[i]["TagValue"]) > 45)
                    {
                        var dr = dt1.NewRow();
                        dr["列位置"] = dt_WWW_Copy2.Rows[i]["列位置"].ToString();
                        dr["测量项目1"] = dt_WWW_Copy2.Rows[i]["TagValue"].ToString();
                        dr["合格标志"] = "1";
                        dr["名称"] = dt_WWW_Copy2.Rows[i]["测量项目"].ToString();
                        dt1.Rows.Add(dr);
                    }
                }
            }
            catch (Exception err)
            {
            }
            message = JsonConvert.SerializeObject(dt1);

            return message;
        }
        /// <summary>
        /// 返回合格标志
        /// </summary>
        /// <param name="opName"></param>
        /// <param name="tagValue"></param>
        /// <param name="tagID"></param>
        /// <returns></returns>
        private static int SaveQualityData(string opName, int tagValue, string tagID, bool isCheck = false)
        {
            int id_tagCF;
            int qualityMask = 0;
            int engineTypeID = 0;
            string engineID = "";
            string engineType = "";
            string partPallet = "";
            string orderFormPlc = "";
            DataTable dt_WWW;
            Hashtable valueList;
            try
            {
                //读取工位全部数据
                var tagValues = MIS_BASE.ReadPLC_OpName(opName);

                valueList = ReadPLC_OpName_Qd(tagValues);//已修改

                //获得带基本信息的质量数据表
                GetQualityDataTable(valueList, out dt_WWW);

                engineTypeID = Convert.ToInt32(GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineTypeID)));
                engineID = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineID)).ToString();
                //engineType = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineType)).ToString();
                //orderFormPlc = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.OrderFormPLC)).ToString();

                // PDC产线plc只写了发动机号和机型代码，其余要从数据库中读取
                MisDataFun.Moby_Select_PDC(engineID, out orderFormPlc, out engineType, out engineTypeID);

                // 判断是否存在首件标志
                if (MIS_BASE.Read_TagValueByTagTypeID(62, opName) == "1" && opName == "OP170")
                {
                    if (dt_WWW != null && dt_WWW.Rows.Count > 0)
                    {
                        DataRow[] filteredRows;
                        if (engineID == "FirstpartVisionData") filteredRows = dt_WWW.Select("测量项目 LIKE '*_首件'"); // 只取视觉首件数据
                        else  filteredRows = dt_WWW.Select("测量项目 NOT LIKE '*_首件'"); // 除了视觉首件外的其他数据
                        if (filteredRows.Length > 0)
                        {
                            dt_WWW = filteredRows.CopyToDataTable();
                        }
                    }
                }

                qualityMask = Convert.ToInt32(GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.QualityMask)));
                if(qualityMask != 1) MisDataFun.LogRecording_OP(opName, "ERROR", "MIS", $"{engineID}工位总合格标志不合格 产品不合格放行!");
                //保存质量数
                MisDataFun.BaseData_tagTable_QualityData_B5A_IndexInsert(engineID, tagID, engineType, engineTypeID, opName, qualityMask, partPallet, out id_tagCF);
                if(id_tagCF > 0)
                {
                    //MisDataFun.BaseData_tagTable_QualityData_B5A_Insert(id_tagCF, engineTypeID, engineID, opName, dt_WWW, isCheck);
                    MisDataFun.BaseData_tagTable_QualityData_B5A_Insert_table(id_tagCF, engineTypeID, engineID, opName, dt_WWW, isCheck);

                    if (MisDataFun.GetSpecialOpExist(opName, "焊接工位")) // 焊接工位需要存5个状态点
                    {
                        var keyValues = tagValues.Where(x => Convert.ToInt32(x.Value.TagTypeCodeID) == 106).OrderBy(x => x.Key).ToDictionary(k => k.Key, v => v.Value);
                        foreach (var item in keyValues)
                            MisDataFun.BaseData_tagTable_QualityData_B5A_Insert_OP170Status(id_tagCF, engineTypeID, engineID, item.Value.TagID.ToString(), item.Value.TagValue.ToString(), qualityMask, opName);
                    }

                    if (MisDataFun.GetSpecialOpExist(opName, "电芯堆叠工位")) // 电芯堆叠存四个电芯码
                    {
                        MisDataFun.SaveOP100_CellCode(opName, engineID);
                    }

                    // 判断是否需要手动选择OK/NG
                    if (MisDataFun.GetSpecialOpExist(opName, "手动OKNG放行"))
                    {
                        //MIS_BASE.Read_ConfirmOkGo(opName, out bool okGo);
                        //MIS_BASE.Read_FalseGo(opName, out bool falseGo);
                        string qualityStr = "0";
                        if (qualityMask == 1) qualityStr = "1";
                        MisDataFun.BaseData_tagTable_QualityData_B5A_Insert_OP170Status(id_tagCF, engineTypeID, engineID, "72210001", qualityStr, qualityMask, opName);
                    }

                    if(MisDataFun.GetSpecialOpExist(opName, "电芯清洗时间管控工位")) // 存电芯清洗管控时间差
                    {
                        bool isOk = MisDataFun.CheckCleanoutTime(opName, engineID, out int MaxUseTime);
                        if (!isOk) qualityMask = 2;
                        MisDataFun.BaseData_tagTable_QualityData_B5A_Insert_OP170Status(id_tagCF, engineTypeID, engineID, "72300031", MaxUseTime.ToString(), qualityMask, opName);
                    }

                    if(!((engineTypeID != 1 && engineTypeID != 1 ) && (opName == "OP120" || opName == "OP140" || opName == "OP160")))   // CC GQ UPS 固定架不涂胶 所以直接跳 PDC 和 W05 需要涂胶校验
                    {
                        if (MisDataFun.GetSpecialOpExist(opName, "涂胶时间差校验"))
                        {
                            int TJResult = MisDataFun.CheckTJTimeAndSave(opName, engineID, "", 1);
                            //if (TJResult != 1) qualityMask = 2;
                        }
                        if (MisDataFun.GetSpecialOpExist(opName, "涂胶时间差校验2"))
                        {
                            int TJResult = MisDataFun.CheckTJTimeAndSave(opName, engineID, "", 1, 2);
                            //if (TJResult != 1) qualityMask = 2;
                        }
                    }
                }
            }
            catch (Exception err)
            {
            }
            return qualityMask;
        }
        static public void GetQualityDataTable(Hashtable valuList,out DataTable dt)
        {
            //78 0：屏蔽MES；1：启用MES(必须MIS)
            //79 通过线体工位PC实现下达工位工作状态：工位有三种状态：在线、离线、屏蔽。在线;0正常状态，实现正常功能。1离线：2屏蔽。(必须MIS)
            //41 机体流向标志（1 BYTE）：0普通工位：1：上线（发动机上线）；2：下线（发动机下线）；(必须PLC)
            //51 返修工位，修改后的数据MES将数据写入PLC ，MES通知PLC数据修改完成。(YN)
            //8 只要返修，必须由mes发送此信号，plc接收此信号后才能放行
            //（暂时没用）用于有扳手拧紧工位。通知设备螺钉拧紧完成。PC已经将数据保存到数据库中。(B5A)
            // 创建 DataView 并排序


            //结果表
            dt = BuildDataTables_WWW();
            //测量位置
            string shaftID = "";
            //测量项目
            string item = "";
            //测量单位
            string unit = "";
            //上限值
            string tagValueUp = "";
            //下限值
            string tagValueDown = "";
            //理论值
            string tagValeNormal = "";

            foreach (DictionaryEntry valueItem in valuList) 
            {
                try
                {
                    var qualityData = (DeviceDriver_BasicData.CustomeEvetnArgs)valueItem.Value;

                    try
                    {
                        shaftID = qualityData.ShaftID.ToString();
                    }
                    catch{}
                    try
                    {
                        item = qualityData.ItemName.ToString();
                    }
                    catch{}
                    try
                    {
                        unit = qualityData.Unit.ToString();
                    }
                    catch{}
                    try
                    {
                        tagValueUp = qualityData.TagValueUp.ToString();
                    }
                    catch{}
                    try
                    {
                        tagValueDown = qualityData.TagValueDown.ToString();
                    }
                    catch{}
                    try
                    {
                        tagValeNormal = qualityData.TagValeNormal.ToString();
                    }
                    catch{}

                    var dr = dt.NewRow();

                    dr["TagID"] = qualityData.TagID;
                    dr["测量位置"] = shaftID;
                    dr["测量项目"] = item;
                    dr["测量单位"] = unit;
                    dr["上限值"] = tagValueUp;
                    dr["下限值"] = tagValueDown;
                    dr["理论值"] = tagValeNormal;
                    dr["工位号"] = qualityData.OpName;
                    dr["列位置"] = qualityData.TagItemOrderBy;
                    dr["变量排序"] = qualityData.TagOrderBy;

                    dr["IsGoodBad"] = qualityData.IsGoodBad;

                    switch (qualityData.TagTypeID)
                    {
                        //合格标志数组
                        case 8203:
                            dr["TagValue"] = GetQualityData_GoodBad_String((bool[])qualityData.TagValue);
                            break;
                        case 8209:
                            dr["TagValue"] = "";
                            break;
                        //非标准REAL
                        case 8210:
                            dr["TagValue"] = GetNoNormalReal(qualityData.TagValue);
                            dt.Rows.Add(dr);
                            break;
                        default:
                            dr["TagValue"] = Convert.ToString(qualityData.TagValue);
                            dt.Rows.Add(dr);
                            break;
                    }
                }
                catch (Exception err)
                {
                    //ApplicationLog.WriteLog(err, err.Message);
                }

            }
        }
        /// <summary>
        /// 数据表
        /// </summary>
        /// <returns></returns>
        private static object GetValueByTagTypeCodeID(ConcurrentDictionary<string, DeviceDriver_BasicData.CustomeEvetnArgs> opTagList, int TagTypeCodeID)
        {
            try
            {
                return opTagList.Where(x => Convert.ToInt32(x.Value.TagTypeCodeID) == TagTypeCodeID).ToList()[0].Value.TagValue;

            }
            catch (Exception err) { return "-3"; }
        }
        /// <summary>
        /// 根据工位名称，读取工位对应的质量数据，带合格标志
        /// </summary>
        /// <param name="opName"></param>
        /// <returns></returns>
        public static Hashtable ReadPLC_OpName_Qd(ConcurrentDictionary<string, DeviceDriver_BasicData.CustomeEvetnArgs> tagValues)
        {
            var ht = new Hashtable();
            try
            {
                var keyValues = tagValues.Where(x => Convert.ToInt32(x.Value.TagTypeCodeID) == 105).OrderBy(x => x.Key).ToDictionary(k => k.Key, v => v.Value);
                var groupCount = 4;
                for (int i = 0; i < keyValues.Count / groupCount; i++)
                {
                    var IsOK = Convert.ToInt32(keyValues.ElementAt(i * groupCount + 0).Value.TagValue);
                    var TagValue = keyValues.ElementAt(i * groupCount + 1).Value.TagValue.ToString();
                    var TagValueUp = keyValues.ElementAt(i * groupCount + 2).Value.TagValue.ToString();
                    var TagValueDown = keyValues.ElementAt(i * groupCount + 3).Value.TagValue.ToString();

                    var TF = keyValues.ElementAt(i * groupCount + 1).Value;
                    var qualityDataType = GetQualityDataType(TF);
                    qualityDataType.IsGoodBad = IsOK;
                    qualityDataType.TagValeNormal = TagValue;
                    qualityDataType.TagValueUp = TagValueUp;
                    qualityDataType.TagValueDown = TagValueDown;

                    ht.Add(qualityDataType.TagID, qualityDataType);
                }
            }
            catch (Exception errr)
            {
                ApplicationLog.WriteLog(errr, "ReadPLC_OpName_Qd1");
            }

            try
            {
                var keyValues_Str = tagValues.Where(x => Convert.ToInt32(x.Value.TagTypeCodeID) == 2005).OrderBy(x => x.Key).ToDictionary(k => k.Key, v => v.Value);
                foreach (var kv in keyValues_Str)
                {
                    var cea = kv.Value;
                    ht.Add(cea.TagID, cea);
                    //if (cea?.TagValue?.ToString()?.Length > 0)
                    //{
                    //    ht.Add(cea.TagID, cea);
                    //}
                }
            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, "ReadPLC_OpName_Qd2");
            }

            return ht;
        }


        public static Hashtable ReadPLC_OpName_Qd_OP170(ConcurrentDictionary<string, DeviceDriver_BasicData.CustomeEvetnArgs> tagValues)
        {
            var keyValues = tagValues.Where(x => Convert.ToInt32(x.Value.TagTypeCodeID) == 105).OrderBy(x => x.Key).ToDictionary(k => k.Key, v => v.Value);
            var ht = new Hashtable();
            for (int i = 0; i < keyValues.Count ; i++)
            {
                var TF = keyValues.ElementAt(i).Value;
                ht.Add(TF.TagID, TF);
            }
            return ht;
        }
        public static Hashtable ReadPLC_OpName_Qd_2025_07_15_LLX_BAK(ConcurrentDictionary<string, DeviceDriver_BasicData.CustomeEvetnArgs> tagValues)
        {
            //lock (l)
            {
                var keyValues = tagValues.Where(x => Convert.ToInt32(x.Value.TagTypeCodeID) == 105).OrderBy(x => x.Key).ToDictionary(k => k.Key, v => v.Value);

                int isOK = 0;
                string TagValeNormal = "";
                string TagValueDown = "";
                string TagValueUp = "";

                Hashtable ht = new Hashtable();

                for (int i = 0; i < keyValues.Count / 8; i++)
                {
                    isOK = Convert.ToInt32(keyValues.ElementAt(i * 8 + 0).Value.TagValue);
                    TagValeNormal = keyValues.ElementAt(i * 8 + 3).Value.TagValue.ToString();
                    TagValueUp = keyValues.ElementAt(i * 8 + 4).Value.TagValue.ToString();
                    TagValueDown = keyValues.ElementAt(i * 8 + 5).Value.TagValue.ToString();

                    var TF1 = keyValues.ElementAt(i * 8 + 1).Value;
                    DeviceDriver_BasicData.CustomeEvetnArgs qualityDataType1;
                    qualityDataType1 = GetQualityDataType(TF1);
                    qualityDataType1.IsGoodBad = isOK;
                    qualityDataType1.TagValeNormal = TagValeNormal;
                    qualityDataType1.TagValueDown = TagValueDown;
                    qualityDataType1.TagValueUp = TagValueUp;
                    ht.Add(qualityDataType1.TagID, qualityDataType1);
                    var TF2 = keyValues.ElementAt(i * 8 + 2).Value;

                    DeviceDriver_BasicData.CustomeEvetnArgs qualityDataType2;
                    qualityDataType2 = GetQualityDataType(TF2);
                    qualityDataType2.IsGoodBad = isOK;
                    qualityDataType2.TagValeNormal = TagValeNormal;
                    qualityDataType2.TagValueDown = TagValueDown;
                    qualityDataType2.TagValueUp = TagValueUp;
                    ht.Add(qualityDataType2.TagID, qualityDataType2);
                }
                return ht;
            }
        }

        public static DeviceDriver_BasicData.CustomeEvetnArgs GetQualityDataType(DeviceDriver_BasicData.CustomeEvetnArgs TF)
        {
            DeviceDriver_BasicData.CustomeEvetnArgs qualityDataType;

            qualityDataType = new DeviceDriver_BasicData.CustomeEvetnArgs();

            qualityDataType.TagID = TF.TagID.ToString();
            qualityDataType.TagTypeID = Convert.ToInt32(TF.TagTypeID);//变量类型
            qualityDataType.OpName = TF.OpName.ToString();
            int.TryParse(TF.TagQuality.ToString(), out int TagQuality);
            qualityDataType.TagQuality = TagQuality;
            qualityDataType.TagValueType = Convert.ToInt32(TF.TagTypeCodeID);
            int.TryParse(TF.TagOrderBy.ToString(), out int TagOrderBy);
            qualityDataType.TagOrderBy = TagOrderBy;
            int.TryParse(TF.TagItemOrderBy.ToString(), out int TagItemOrderBy);
            qualityDataType.TagItemOrderBy = TagItemOrderBy;
            qualityDataType.TagProperty = Convert.ToInt32(TF.TagProperty) ;//变量特点
            qualityDataType.TagValue = TF.TagValue;//变量值

            //2025.07.15.2232.LLX
            qualityDataType.ShaftID = TF.ShaftID;
            qualityDataType.ItemName = TF.ItemName;
            qualityDataType.Unit = TF.Unit;

            return qualityDataType;
        }



    }
}