using DC_A95;
using ExternalDataSync;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace MesWork
{
    /// <summary>
    /// 数据库操作
    /// </summary>
    public class B_DB_Opera
    {


        public static bool LoginState_Query(out LoginStateInfo loginState)
        {
            loginState = null;
            try
            {
                var sqlParameter = new SqlParameter[] {
                    new SqlParameter("@机器名", Environment.MachineName)
                };
                SqlOperation.ExecuteStoredProcedure("系统登录状态_查询", sqlParameter, out DataTable dt, out string err);
                if (dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1")
                {
                    loginState = new LoginStateInfo
                    {
                        LoginID = dt.Rows[0]["登录账号"]?.ToString() ?? "",
                        UserName = dt.Rows[0]["用户姓名"]?.ToString() ?? "",
                        Permission = dt.Rows[0]["权限"]?.ToString() ?? ""
                    };
                    return !string.IsNullOrWhiteSpace(loginState.LoginID) && !string.IsNullOrWhiteSpace(loginState.UserName);
                }
            }
            catch { }
            return false;
        }

        public static void LoginState_Save(string loginID, string userName, string permission)
        {
            try
            {
                var sqlParameter = new SqlParameter[] {
                    new SqlParameter("@机器名", Environment.MachineName),
                    new SqlParameter("@登录账号", loginID ?? ""),
                    new SqlParameter("@用户姓名", userName ?? ""),
                    new SqlParameter("@权限", permission ?? "")
                };
                SqlOperation.ExecuteStoredProcedure("系统登录状态_保存", sqlParameter, out string err);
            }
            catch { }
        }

        public static void LoginState_Clear()
        {
            try
            {
                var sqlParameter = new SqlParameter[] {
                    new SqlParameter("@机器名", Environment.MachineName)
                };
                SqlOperation.ExecuteStoredProcedure("系统登录状态_清空", sqlParameter, out string err);
            }
            catch { }
        }


        public static void Event_Signal_Log(string opName, int tagTypeCodeID, string signalName, string value)
        {
            var procedureName = "Event_Signal_Log";
            var sqlParameter = new SqlParameter[] {
                 new SqlParameter("@OpName", opName),
                 new SqlParameter("@TagTypeCodeID", tagTypeCodeID),
                 new SqlParameter("@SignalName", signalName),
                 new SqlParameter("@TagValue", value)
                };

            SqlOperation.ExecuteStoredProcedure(procedureName, sqlParameter, out string errorMessage);
        }


        public static void Event_Alarm_Start(string opName, int tagTypeCodeID, string alarmText, string alarmLevel, string tagID)
        {
            var ChangeTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var procedureName = "Event_Alarm_Start";
            var sqlParameter = new SqlParameter[] {
                 new SqlParameter("@OpName", opName),
                 new SqlParameter("@TagTypeCodeID", tagTypeCodeID),
                 new SqlParameter("@AlarmText", alarmText),
                 new SqlParameter("@AlarmLevel", alarmLevel),
                 new SqlParameter("@ChangeTime",ChangeTime),
                 new SqlParameter("@TagID", tagID)
                };

            SqlOperation.ExecuteStoredProcedure(procedureName, sqlParameter, out string errorMessage);

        }


        public static void Event_Alarm_End(string opName, int tagTypeCodeID, string alarmText, string alarmLevel, string tagID)
        {
            var ChangeTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var procedureName = "Event_Alarm_End";
            var sqlParameter = new SqlParameter[] {
                 new SqlParameter("@OpName", opName),
                 new SqlParameter("@TagTypeCodeID", tagTypeCodeID),
                 new SqlParameter("@AlarmText", alarmText),
                 new SqlParameter("@AlarmLevel", alarmLevel),
                 new SqlParameter("@ChangeTime",ChangeTime),
                 new SqlParameter("@TagID", tagID)
                };

            SqlOperation.ExecuteStoredProcedure(procedureName, sqlParameter, out string errorMessage);

        }

        public static void Query_AlarmData(string opName, out int count, out string text)
        {
            count = 0;
            text = "";

            var ChangeTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var procedureName = "Query_AlarmData";
            var sqlParameter = new SqlParameter[] {
                 new SqlParameter("@OpName", opName),
                };
            SqlOperation.ExecuteStoredProcedure(procedureName, sqlParameter, out DataTable dt, out string errorMessage);
            if (dt.Rows.Count > 0)
            {
                count = Convert.ToInt32(dt.Rows[0]["COUNT"].ToString());
                text = dt.Rows[0]["TEXT"].ToString();
            }

        }


        public static void Event_DeviceStatus_Change(string opName, string DeviceStatus)
        {
            var ChangeTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var procedureName = "Event_DeviceStatus_Change";
            var sqlParameter = new SqlParameter[] {
                 new SqlParameter("@OpName", opName),
                 new SqlParameter("@DeviceStatus", DeviceStatus),
                 new SqlParameter("@ChangeTime",ChangeTime),
                };

            SqlOperation.ExecuteStoredProcedure(procedureName, sqlParameter, out string errorMessage);

        }


        /// <summary>
        /// 请求日志记录
        /// </summary>
        public static void SaveLog_Request(string StationName, Log_Type LogType, string ReqCode, Log_FromAndTo ReqFrom, Log_FromAndTo ReqTo, string ReqStr, out long AID, string ReqStrSafe = "")
        {
            AID = -1;
            var CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            ReqStr = PLC_R.GetString_CleanGarbled(ReqStr);

            var param1 = new SqlParameter[] {
                new SqlParameter("@工位号", StationName),
                new SqlParameter("@日志类型", LogType.ToString()),
                new SqlParameter("@TaskID", ReqCode),
                new SqlParameter("@请求CMD",""),
                new SqlParameter("@请求FROM",ReqFrom.ToString()),
                new SqlParameter("@请求TO",ReqTo.ToString()),
                new SqlParameter("@请求时间",CreateTime),
                new SqlParameter("@请求内容",ReqStr),
                new SqlParameter("@请求内容安全",ReqStrSafe)
                };
            DataLinkMesWork.SQLCommon.ExecuteStoredProcedure("Event_Log_Request", MesWorkForm.ConnectionString, ref param1, out DataTable dt, out string errorMessage);
            if (dt.Rows.Count > 0)
            {
                AID = Convert.ToInt64(dt.Rows[0]["AID"]);
            }
        }
        /// <summary>
        /// 响应日志记录
        /// </summary>
        public static void SaveLog_Response(string result, long AID)
        {
            try
            {
                var CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                var param4 = new SqlParameter[]
                {
                        new SqlParameter("@AID",AID),
                        new SqlParameter("@响应时间",CreateTime),
                        new SqlParameter("@响应内容",JsonConvert.SerializeObject(result))
                };
                DataLinkMesWork.SQLCommon.ExecuteStoredProcedure("Event_Log_Respond", MesWorkForm.ConnectionString, ref param4, out string errorMessage);
            }
            catch (Exception err)
            {
            }

        }



        /// <summary>
        /// 根据订货号匹配工件管理规则，查询机型参数（加油量/抽油量/密度/残油量上下限）
        /// </summary>
        public static bool QueryWorkpieceByOrderNo(string orderNo, out string modelNo, out decimal addOilQty, out decimal extractOilQty, out decimal density,
            out decimal residualOilUpperLimit, out decimal residualOilLowerLimit)
        {
            modelNo = "";
            addOilQty = 0; extractOilQty = 0; density = 0; residualOilUpperLimit = 0; residualOilLowerLimit = 0;
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@订货号", orderNo)
            };
            SqlOperation.ExecuteStoredProcedure("称重_查询工件参数", sqlParameter, out DataTable dt, out string err);
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1")
            {
                var row = dt.Rows[0];
                modelNo = row["机型号"]?.ToString() ?? "";
                decimal.TryParse(row["加油量"]?.ToString(), out addOilQty);
                decimal.TryParse(row["抽油量"]?.ToString(), out extractOilQty);
                decimal.TryParse(row["密度"]?.ToString(), out density);
                decimal.TryParse(row["残油量上限"]?.ToString(), out residualOilUpperLimit);
                decimal.TryParse(row["残油量下限"]?.ToString(), out residualOilLowerLimit);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 查询指定工位和原始重量匹配的工具标定配置。
        /// </summary>
        public static bool QueryToolCalibration(string opName, decimal rawWeight, out string toolName, out string formula, out string description, out string msg)
        {
            toolName = "";
            formula = "";
            description = "";
            msg = "";

            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@工位号", opName ?? ""),
                new SqlParameter("@重量", rawWeight)
            };
            SqlOperation.ExecuteStoredProcedure("工具管理_查询匹配标定", sqlParameter, out DataTable dt, out string err);
            if (dt == null)
            {
                msg = string.IsNullOrWhiteSpace(err) ? $"查询[{opName}]工具标定配置失败" : err;
                return false;
            }

            if (dt.Rows.Count == 0)
            {
                msg = "";
                return false;
            }

            var row = dt.Rows[0];
            toolName = row["工具名称"]?.ToString() ?? "";
            formula = row["计算公式"]?.ToString() ?? "";
            description = row["说明"]?.ToString() ?? "";
            return true;
        }

        /// <summary>
        /// 插入称重记录
        /// </summary>
        /// <returns>新记录ID，失败返回-1</returns>
        public static long InsertWeighingRecord(
            string stationNo, string weighType, string engineNo, string modelNo,
            string orderNo, string palletNo,
            decimal inWeight, decimal outWeight,
            decimal addOilQty, decimal extractOilQty, decimal density,
            decimal residualOilUpperLimit, decimal residualOilLowerLimit,
            decimal oilRelease, decimal residualOil,
            int qualityFlag, decimal waterContent,
            string dataSource, string worker, int isComplete)
        {
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@工位号", stationNo),
                new SqlParameter("@称重类型", weighType),
                new SqlParameter("@发动机号", engineNo),
                new SqlParameter("@机型号", modelNo),
                new SqlParameter("@工单号", orderNo),
                new SqlParameter("@托盘号", palletNo),
                new SqlParameter("@进站重量", inWeight),
                new SqlParameter("@离站重量", outWeight),
                new SqlParameter("@加油量", addOilQty),
                new SqlParameter("@抽油量", extractOilQty),
                new SqlParameter("@密度", density),
                new SqlParameter("@残油量上限", residualOilUpperLimit),
                new SqlParameter("@残油量下限", residualOilLowerLimit),
                new SqlParameter("@放油量", oilRelease),
                new SqlParameter("@残油量", residualOil),
                new SqlParameter("@合格标志", qualityFlag),
                new SqlParameter("@水含量", waterContent),
                new SqlParameter("@数据来源", dataSource),
                new SqlParameter("@操作者", worker),
                new SqlParameter("@是否完成", isComplete)
            };
            SqlOperation.ExecuteStoredProcedure("称重记录_增加", sqlParameter, out DataTable dt, out string err);
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1")
            {
                return Convert.ToInt64(dt.Rows[0]["ID"]);
            }
            return -1;
        }

        /// <summary>
        /// 查询放油前记录（按发动机号匹配，称重类型='空中'且未完成）
        /// </summary>
        public static bool QueryWeighingBeforeOil(string engineNo, out long recordId, out decimal preWeight, out decimal addOilQty, out decimal extractOilQty, out decimal density)
        {
            recordId = 0; preWeight = 0; addOilQty = 0; extractOilQty = 0; density = 0;
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@发动机号", engineNo)
            };
            SqlOperation.ExecuteStoredProcedure("称重记录_查询放油前", sqlParameter, out DataTable dt, out string err);
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1")
            {
                var row = dt.Rows[0];
                recordId = Convert.ToInt64(row["ID"]);
                decimal.TryParse(row["进站重量"]?.ToString(), out preWeight);
                decimal.TryParse(row["加油量"]?.ToString(), out addOilQty);
                decimal.TryParse(row["抽油量"]?.ToString(), out extractOilQty);
                decimal.TryParse(row["密度"]?.ToString(), out density);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 查询指定工位最新的称重记录（不过滤完成状态）
        /// </summary>
        public static bool QueryLatestRecord(string stationNo, string engineNo,
            out long recordId, out decimal preWeight,
            out decimal addOilQty, out decimal extractOilQty, out decimal density)
        {
            recordId = 0; preWeight = 0; addOilQty = 0; extractOilQty = 0; density = 0;
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@工位号", stationNo),
                new SqlParameter("@发动机号", engineNo)
            };
            SqlOperation.ExecuteStoredProcedure("称重记录_查询最新", sqlParameter, out DataTable dt, out string err);
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1")
            {
                var row = dt.Rows[0];
                recordId = Convert.ToInt64(row["ID"]);
                decimal.TryParse(row["进站重量"]?.ToString(), out preWeight);
                decimal.TryParse(row["加油量"]?.ToString(), out addOilQty);
                decimal.TryParse(row["抽油量"]?.ToString(), out extractOilQty);
                decimal.TryParse(row["密度"]?.ToString(), out density);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 更新称重记录为完成状态（保存称重结果）
        /// </summary>
        public static bool UpdateWeighingComplete(long recordId, string weighType, string stationNo,
            decimal weight, decimal oilRelease, decimal residualOil, decimal waterContent, out int qualityFlag, out string msg)
        {
            qualityFlag = 2;
            msg = "";
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@ID", recordId),
                new SqlParameter("@称重类型", weighType),
                new SqlParameter("@工位号", stationNo),
                new SqlParameter("@称重重量", weight),
                new SqlParameter("@放油量", oilRelease),
                new SqlParameter("@残油量", residualOil),
                new SqlParameter("@水含量", waterContent)
            };
            SqlOperation.ExecuteStoredProcedure("称重记录_完成更新", sqlParameter, out DataTable dt, out string err);
            if (dt == null || dt.Rows.Count == 0)
            {
                msg = string.IsNullOrEmpty(err) ? "称重记录完成更新未返回结果" : err;
                return false;
            }

            qualityFlag = Convert.ToInt32(dt.Rows[0]["result"]);
            msg = dt.Rows[0]["msg"].ToString();
            return true;
        }

        // ====================================================================
        // 过站记录操作方法
        // ====================================================================

        /// <summary>
        /// 新增过站记录（case 44 请求工作时调用）
        /// </summary>
        public static long InsertStationRecord(string engineNo, string modelNo, string orderNo, string palletNo,
            string stationNo, string stationName, decimal addOilQty, decimal extractOilQty, decimal density, string worker)
        {
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@发动机号", engineNo),
                new SqlParameter("@机型号", modelNo),
                new SqlParameter("@工单号", orderNo),
                new SqlParameter("@托盘号", palletNo),
                new SqlParameter("@工位号", stationNo),
                new SqlParameter("@工位名称", stationName),
                new SqlParameter("@加油量", addOilQty),
                new SqlParameter("@抽油量", extractOilQty),
                new SqlParameter("@油密度", density),
                new SqlParameter("@操作者", worker)
            };
            SqlOperation.ExecuteStoredProcedure("过站记录_新增", sqlParameter, out DataTable dt, out string err);
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1")
                return Convert.ToInt64(dt.Rows[0]["ID"]);
            return -1;
        }

        /// <summary>
        /// 更新过站记录为完成（case 19 请求保存时调用）
        /// </summary>
        public static bool UpdateStationComplete(string engineNo, string stationNo, decimal weight,
            string modelNo = "", string orderNo = "", string palletNo = "", string stationName = "",
            decimal addOilQty = 0, decimal extractOilQty = 0, decimal density = 0, string worker = "")
        {
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@发动机号", engineNo),
                new SqlParameter("@工位号", stationNo),
                new SqlParameter("@称重重量", weight),
                new SqlParameter("@机型号", modelNo),
                new SqlParameter("@工单号", orderNo),
                new SqlParameter("@托盘号", palletNo),
                new SqlParameter("@工位名称", stationName),
                new SqlParameter("@加油量", addOilQty),
                new SqlParameter("@抽油量", extractOilQty),
                new SqlParameter("@油密度", density),
                new SqlParameter("@操作者", worker)
            };
            SqlOperation.ExecuteStoredProcedure("过站记录_完成", sqlParameter, out DataTable dt, out string err);
            return dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1";
        }

        // ====================================================================
        // 称重曲线数据操作方法
        // ====================================================================

        /// <summary>
        /// 创建紧凑曲线记录，点位值在保存时一次性写入。
        /// </summary>
        public static long CurveRecord_Start(string opName, string productNo, string modelNo, int sampleIntervalMs)
        {
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@工位号", opName),
                new SqlParameter("@产品编号", productNo),
                new SqlParameter("@机型号", modelNo ?? (object)DBNull.Value),
                new SqlParameter("@采样间隔ms", sampleIntervalMs)
            };
            SqlOperation.ExecuteStoredProcedure("称重曲线记录_开始", sqlParameter, out DataTable dt, out string err);
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1")
            {
                return Convert.ToInt64(dt.Rows[0]["ID"]);
            }
            return -1;
        }

        /// <summary>
        /// 保存紧凑曲线点位字符串，并关联最终称重记录。
        /// </summary>
        public static bool CurveRecord_Save(long curveId, long weighingRecordId, int sampleCount, string pointValues,
            decimal? finalWeight, int? finalStartSeq, int? finalEndSeq)
        {
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@ID", curveId),
                new SqlParameter("@称重记录ID", weighingRecordId > 0 ? (object)weighingRecordId : DBNull.Value),
                new SqlParameter("@采样点数", sampleCount),
                new SqlParameter("@点位值", string.IsNullOrEmpty(pointValues) ? (object)DBNull.Value : pointValues),
                new SqlParameter("@最终重量", finalWeight.HasValue ? (object)finalWeight.Value : DBNull.Value),
                new SqlParameter("@最终取点开始序号", finalStartSeq.HasValue ? (object)finalStartSeq.Value : DBNull.Value),
                new SqlParameter("@最终取点结束序号", finalEndSeq.HasValue ? (object)finalEndSeq.Value : DBNull.Value)
            };
            SqlOperation.ExecuteStoredProcedure("称重曲线记录_保存", sqlParameter, out DataTable dt, out string err);
            return dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1";
        }

        /// <summary>
        /// 查询指定产品最新紧凑曲线记录。
        /// </summary>
        public static bool CurveRecord_QueryLatest(string opName, string productNo, out string pointValues, out decimal finalWeight)
        {
            pointValues = "";
            finalWeight = 0;
            var sqlParameter = new SqlParameter[] {
                new SqlParameter("@工位号", opName),
                new SqlParameter("@产品编号", productNo)
            };
            SqlOperation.ExecuteStoredProcedure("称重曲线记录_查询最新", sqlParameter, out DataTable dt, out string err);
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0]["result"].ToString() == "1")
            {
                pointValues = dt.Rows[0]["点位值"]?.ToString() ?? "";
                decimal.TryParse(dt.Rows[0]["最终重量"]?.ToString(), out finalWeight);
                return true;
            }
            return false;
        }

    }

    public class LoginStateInfo
    {
        public string LoginID;
        public string UserName;
        public string Permission;
    }

    /// <summary>
    /// 曲线采样点数据结构
    /// </summary>
    public class CurveSamplePoint
    {
        public int SeqNo;
        public DateTime SampleTime;
        public decimal Weight;
    }
}
