using DeviceRepair.DataAccess.Data;
using DeviceRepair.Models;
using DeviceRepair.Models.Enum;
using DeviceRepair.Models.History;
using DeviceRepair.Models.Plan;
using DeviceRepair.Models.Preserve;
using DeviceRepair.Utils;
using NLog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;

namespace DeviceRepair.DataAccess.CheckForm
{
    public class CheckFormDa : BaseDa
    {
        private static readonly Logger log = LogManager.GetCurrentClassLogger();

        public CheckFormDa(IDictionary<string, string> apiParams) : base(apiParams)
        {

        }

        /// <summary>
        /// 获取点检表数据
        /// </summary>
        /// <returns></returns>
        public DataSet Get_PM_CheckForm_Datas()
        {
            DataSet dsDatas = new DataSet("Datas");
            try
            {
                string formName = GetParamString("FormName", "点检表名称");
                var exp = Expressionable.Create<MaintenanceFormVersionInfo>()
                    .AndIF(!formName.IsNull(), x => SqlFunc.Contains(x.FormName, SqlFunc.Trim(formName))).ToExpression();//拼接表达式

                List<MaintenanceFormVersionInfo> datas = devMain.Queryable<MaintenanceFormVersionInfo>().Where(exp).ToList();
                DataTable table = datas.OrderByDescending(x => x.ChangeDate).ThenByDescending(x => x.ChangeDate).ToList().ToDataTable();
                dsDatas.Tables.Add(table);

                return dsDatas;
            }
            catch (SqlException sqlEx)
            {
                throw sqlEx;
            }
            catch (Exception ex)
            {
                log.Error(ex);
                throw ex;
            }
        }

        /// <summary>
        /// 获取单条数据
        /// </summary>
        /// <returns></returns>
        public APIResponseData Get_CheckForm_Single(int planAutoId, out DataSet dsDatas)
        {
            dsDatas = new DataSet("Datas");

            try
            {
                DriveMaintencePlanInfo plan = devMain.Queryable<DriveMaintencePlanInfo>()
                    .Where(x => x.AutoID == planAutoId).First();
                DataTable table = new List<DriveMaintencePlanInfo> { plan }.ToDataTable();
                dsDatas.Tables.Add(table);

                if (plan == null)
                {
                    throw new ArgumentException($"获取数据失败,数据库不存在【主键编号】为【{planAutoId}】的数据！");
                }

                if (plan.Belong.Trim() == EnumDeviceBelong.AM.ToString())
                {
                    /* 判断当月AM是否存在点检记录 */
                    var record = devMain.Queryable<MaintenanceRecordInfo>().First(x => x.PlanPrimaryID == plan.AutoID);
                    MaintenanceFormVersionInfo formData;
                    if (record != null)
                    {
                        formData = devMain.Queryable<MaintenanceFormVersionInfo>().First(x => x.AutoID == record.FormPrimaryID);
                    }
                    else
                    {
                        formData = devMain.Queryable<DeviceInformationInfo, MaintenanceFormVersionInfo>((t1, t2) => new object[] { JoinType.Inner, t1.MaintenanceAMFormVersion == t2.AutoID })
                           .Where((t1, t2) => t1.AutoID == plan.EquipmentID).Select((t1, t2) => t2).First();
                    }

                    if (formData == null)
                    {
                        throw new ArgumentException("当前设备的点检表不存在！");
                    }
                    DataTable table2 = new List<MaintenanceFormVersionInfo> { formData }.ToDataTable();
                    dsDatas.Tables.Add(table2);
                    return new APIResponseData { Code = 1, Message = "操作成功！" };
                }
                else if (plan.Belong.Trim() == EnumDeviceBelong.PM.ToString())
                {
                    if (devMain.Queryable<MaintenanceRecordInfo, DeviceInformationInfo>((x1, x2) => new object[] { JoinType.Inner, x1.PlanPrimaryID == planAutoId && x1.EquipmentPrimaryID == x2.AutoID && x1.FormPrimaryID == x2.MaintenanceFormVersion }).Any())
                    {
                        MaintenanceFormVersionInfo formData = devMain.Queryable<MaintenanceRecordInfo, MaintenanceFormVersionInfo>((t1, t2) => new object[] { JoinType.Inner, t1.FormPrimaryID == t2.AutoID })
                              .Where((t1, t2) => t1.EquipmentPrimaryID == plan.EquipmentID).Select((t1, t2) => t2).First();
                        if (formData == null)
                        {
                            throw new ArgumentException("当前设备的点检表不存在！");
                        }
                        DataTable table2 = new List<MaintenanceFormVersionInfo> { formData }.ToDataTable();
                        dsDatas.Tables.Add(table2);
                    }
                    else
                    {
                        MaintenanceFormVersionInfo formData = devMain.Queryable<DeviceInformationInfo, MaintenanceFormVersionInfo>((t1, t2) => new object[] { JoinType.Inner, t1.MaintenanceFormVersion == t2.AutoID })
                            .Where((t1, t2) => t1.AutoID == plan.EquipmentID).Select((t1, t2) => t2).First();
                        if (formData == null)
                        {
                            throw new ArgumentException("当前设备的点检表不存在！");
                        }
                        DataTable table2 = new List<MaintenanceFormVersionInfo> { formData }.ToDataTable();
                        dsDatas.Tables.Add(table2);
                    }
                    return new APIResponseData { Code = 1, Message = "操作成功！" };
                }
                else
                {
                    throw new ArgumentException($"获取数据失败,计划中的保养类型(AM/PM)数据不正确！");
                }
            }
            catch (SqlException sqlEx)
            {
                throw sqlEx;
            }
            catch (Exception ex)
            {
                log.Error(ex);
                throw ex;
            }
        }

        /// <summary>
        /// 获取点检表表单信息
        /// </summary>
        /// <param name="PrimaryKey"></param>
        /// <returns></returns>
        public MaintenanceFormVersionInfo GetSingle(int PrimaryKey)
        {
            try
            {
                return devMain.Queryable<MaintenanceFormVersionInfo>().First(x => x.AutoID == PrimaryKey);
            }
            catch (SqlException sqlEx)
            {
                throw sqlEx;
            }
            catch (Exception ex)
            {
                log.Error(ex);
                throw ex;
            }
        }

        /// <summary>
        /// 修改点检表状态
        /// </summary>
        /// <returns></returns>
        public APIResponseData Change_PM_CheckForm_Status()
        {
            try
            {
                int formId = GetParamInt("FormID", "点检表编号");

                MaintenanceFormVersionInfo item = devMain.Queryable<MaintenanceFormVersionInfo>().First(x => x.AutoID == formId);
                if (item == null)
                {
                    throw new ArgumentException($"传入的点检表编号不正确,找不到编号为：{formId}的点检表！");
                }

                bool beStatus = GetParamString("BeStatus", "状态").Equals("A", StringComparison.CurrentCultureIgnoreCase);
                item.FormStatus = beStatus;
                devMain.BeginTran();
                if (devMain.Updateable(item).ExecuteCommand() > 0)
                {
                    devMain.CommitTran();
                    return new APIResponseData { Code = 1, Message = "操作成功！" };
                }
                else
                {
                    devMain.RollbackTran();
                    return new APIResponseData { Code = -1, Message = "操作失败！" };
                }
            }
            catch (SqlException sqlEx)
            {
                devMain.RollbackTran();
                throw sqlEx;
            }
            catch (Exception ex)
            {
                devMain.RollbackTran();
                log.Error(ex);
                throw ex;
            }
        }

        /// <summary>
        /// 分配点检表到指定设备
        /// </summary>
        /// <param name="lst"></param>
        /// <returns></returns>
        public APIResponseData AssigFormToDevice(List<SubmitAssignFormsToDevices> lst)
        {
            var apiResponseData = new APIResponseData { Code = -1, Message = $"新增失败或当前数据无更改，请重试！" };
            if (lst == null)
                throw new Exception("待修改的对象为空！");

            try
            {
                var currentDate = DateTime.Now;
                devMain.BeginTran();
                var execSuccess = true;

                //解除绑定
                if (lst.Any(x => x.OperationType == EnumOperationType.UnBind))
                {
                    var editData = lst.Where(x => x.OperationType == EnumOperationType.UnBind).Select(x => x.EquipmentAutoID).ToArray();

                    if (lst[0].Belong == Models.Enum.EnumDeviceBelong.AM)
                    {
                        execSuccess = devMain.Updateable<DeviceInformationInfo>()
                           .UpdateColumns(x => new { x.MaintenanceAMFormVersion, x.ChangeDate, x.ChangeUser })
                           .ReSetValue(x => x.MaintenanceAMFormVersion == 0)
                           .ReSetValue(x => x.ChangeUser == OperationInfo.TsSFCUserId)
                           .ReSetValue(x => x.ChangeDate == currentDate)
                           .Where(x => editData.Contains(x.AutoID)).ExecuteCommand() > 0;
                    }
                    else
                    {

                        execSuccess = devMain.Updateable<DeviceInformationInfo>()
                            .UpdateColumns(x => new { x.MaintenanceFormVersion, x.ChangeDate, x.ChangeUser })
                            .ReSetValue(x => x.MaintenanceFormVersion == 0)
                            .ReSetValue(x => x.ChangeUser == OperationInfo.TsSFCUserId)
                            .ReSetValue(x => x.ChangeDate == currentDate)
                            .Where(x => editData.Contains(x.AutoID)).ExecuteCommand() > 0;
                    }
                }

                //新增绑定
                if (execSuccess && lst.Any(x => x.OperationType == EnumOperationType.Bind))
                {
                    if (lst[0].Belong == Models.Enum.EnumDeviceBelong.AM)
                    {
                        var editData = lst.Where(x => x.OperationType == EnumOperationType.Bind).Select(x => x.EquipmentAutoID).ToArray();
                        execSuccess = devMain.Updateable<DeviceInformationInfo>()
                            .UpdateColumns(x => new { x.MaintenanceAMFormVersion, x.ChangeDate, x.ChangeUser })
                            .ReSetValue(x => x.MaintenanceAMFormVersion == lst[0].FormAutoID)
                            .ReSetValue(x => x.ChangeUser == OperationInfo.TsSFCUserId)
                            .ReSetValue(x => x.ChangeDate == currentDate)
                            .Where(x => editData.Contains(x.AutoID)).ExecuteCommand() > 0;
                    }
                    else
                    {
                        var editData = lst.Where(x => x.OperationType == EnumOperationType.Bind).Select(x => x.EquipmentAutoID).ToArray();
                        execSuccess = devMain.Updateable<DeviceInformationInfo>()
                            .UpdateColumns(x => new { x.MaintenanceFormVersion, x.ChangeDate, x.ChangeUser })
                            .ReSetValue(x => x.MaintenanceFormVersion == lst[0].FormAutoID)
                            .ReSetValue(x => x.ChangeUser == OperationInfo.TsSFCUserId)
                            .ReSetValue(x => x.ChangeDate == currentDate)
                            .Where(x => editData.Contains(x.AutoID)).ExecuteCommand() > 0;
                    }
                }

                if (execSuccess)
                {
                    apiResponseData.Code = 1;
                    apiResponseData.Message = "";
                    devMain.CommitTran();
                }

                List<DeviceHistory> logs = new List<DeviceHistory>();

                foreach (SubmitAssignFormsToDevices item in lst)
                {
                    logs.Add(new DeviceHistory
                    {
                        FormAutoID = item.FormAutoID,
                        FormCode = item.VersionCode,
                        FormName = item.FormName,
                        FormRev = item.VersionRev,
                        FormBelong = lst[0].Belong.ToString(),
                        EquipmentAutoID = item.EquipmentAutoID,
                        EquipmentID = item.EquipmentID,
                        EquipmentName = item.EquipmentName,
                        Specification = (item.Specification ?? ""),
                        OperationComputer = OperationInfo.ComputerName,
                        OperationDate = currentDate,
                        OperationIP = OperationInfo.IPAddress,
                        OperationType = item.OperationType == EnumOperationType.Bind ? "绑定" : "解除绑定",
                        OperationUser = OperationInfo.TsSFCUserId,
                        OperationUserName = OperationInfo.TsSFCUserName
                    });
                }

                devLog.Insertable(logs).ExecuteCommand();
            }
            catch (SqlException sqlEx)
            {
                devMain.RollbackTran();
                throw sqlEx;
            }
            catch (Exception ex)
            {
                devMain.RollbackTran();
                log.Error(ex);
                throw ex;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 判断数据是否存在
        /// </summary>
        /// <param name="Count"></param>
        /// <returns></returns>
        public APIResponseData Get_CheckForm_Exists(out int Count)
        {
            Count = 0;
            try
            {
                if (!ApiParameters.ContainsKey("VersionCode"))
                {
                    throw new ArgumentException("传入的点检表编码不能为空！");
                }

                if (!ApiParameters.ContainsKey("VersionRev"))
                {
                    throw new ArgumentException("传入的点检表版本不能为空！");
                }

                MaintenanceFormVersionInfo Data = devMain.Queryable<MaintenanceFormVersionInfo>().First(x =>
                 x.VersionCode.Equals(SqlFunc.Trim(ApiParameters["VersionCode"]), StringComparison.CurrentCultureIgnoreCase) &&
                 x.VersionRev.Equals(SqlFunc.Trim(ApiParameters["VersionRev"]), StringComparison.CurrentCultureIgnoreCase));

                Count = (Data == null ? 0 : 1);
                return new APIResponseData { Code = 1, Message = "操作成功！" };
            }
            catch (SqlException sqlEx)
            {
                throw sqlEx;
            }
            catch (Exception ex)
            {
                log.Error(ex);
                throw ex;
            }
        }

        /// <summary>
        /// 新增点检表
        /// </summary>
        /// <param name="Item"></param>
        /// <returns></returns>
        public APIResponseData Insert_CheckForm_Data(MaintenanceFormVersionInfo Item)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = $"新增失败或当前数据无更改，请重试！" };
            if (Item == null)
                throw new Exception("传入的参数对象为空！");

            try
            {
                if (!ApiParameters.ContainsKey("OPERATORAUTOID"))
                {
                    throw new ArgumentException("非法的操作,当前操作人参数不正确！");
                }

                int OperationID = Convert.ToInt32(ApiParameters["OPERATORAUTOID"] + "");
                DateTime CurrentDate = DateTime.Now;
                Item.CreatDate = CurrentDate;
                Item.CreatUser = OperationID;

                MaintenanceFormVersionInfo CurrentData = devMain.Insertable(Item).ExecuteReturnEntity();
                if (CurrentData.AutoID > 0)
                {
                    apiResponseData.Code = 1;
                    apiResponseData.Message = "";

                    FormLogInfo log = new FormLogInfo
                    {
                        FormID = CurrentData.AutoID,
                        FormName = Item.FormName,
                        FormVersionRev = Item.VersionRev,
                        OperationComputer = ApiParameters["CLIENTNAME"],
                        OperationDate = CurrentDate,
                        OperationIP = ApiParameters["CLIENTIP"],
                        OperationType = "新增",
                        OperationUser = OperationID,
                        OperationUserName = ApiParameters["OPERATORNAME"]
                    };
                    devLog.Insertable(log).ExecuteCommand();
                }
            }
            catch (SqlException sqlEx)
            {
                devMain.RollbackTran();
                throw sqlEx;
            }
            catch (Exception ex)
            {
                devMain.RollbackTran();
                log.Error(ex);
                throw ex;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 修改备注
        /// </summary>
        /// <param name="Item"></param>
        /// <returns></returns>
        public APIResponseData Change_CheckForm_Remark(MaintenanceFormVersionInfo Item)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = $"新增失败或当前数据无更改，请重试！" };
            if (Item == null)
                throw new Exception("传入的参数对象为空！");

            try
            {
                if (!ApiParameters.ContainsKey("OPERATORAUTOID"))
                {
                    throw new ArgumentException("非法的操作,当前操作人参数不正确！");
                }

                int OperationID = Convert.ToInt32(ApiParameters["OPERATORAUTOID"] + "");
                DateTime CurrentDate = DateTime.Now;

                devMain.BeginTran();
                MaintenanceFormVersionInfo oItem = devMain.Queryable<MaintenanceFormVersionInfo>().First(x => x.AutoID == Item.AutoID);
                if (oItem == null)
                    throw new Exception($"找不到主键编号为【{Item.AutoID}】的点检表信息！");

                bool IsSuccess = devMain.Updateable<MaintenanceFormVersionInfo>()
                .UpdateColumns(x => new { x.Remarks, x.ChangeDate, x.ChangeUser })
                .ReSetValue(x => x.Remarks == Item.Remarks)
                .ReSetValue(x => x.ChangeDate == CurrentDate)
                .ReSetValue(x => x.ChangeUser == OperationID)
                .Where(x => x.AutoID == Item.AutoID).ExecuteCommandHasChange();

                devMain.CommitTran();

                if (IsSuccess)
                {
                    apiResponseData.Code = 1;
                    apiResponseData.Message = "";

                    MaintenanceFormVersionHistoryInfo log = new MaintenanceFormVersionHistoryInfo
                    {
                        ClientMac = ApiParameters["CLIENTMAC"],
                        ClientName = ApiParameters["CLIENTNAME"],
                        CreatDate = CurrentDate,
                        CreatUser = OperationID,
                        FormName = oItem.FormName,
                        FormPath = oItem.FormPath,
                        FormStatus = oItem.FormStatus,
                        Guid = new Guid(),
                        IPAddress = ApiParameters["CLIENTIP"],
                        MaintenanceFormVersionAutoID = oItem.AutoID,
                        Remarks = oItem.Remarks,
                        VersionCode = oItem.VersionCode,
                        VersionRev = oItem.VersionRev
                    };
                    devLog.Insertable(log).ExecuteCommand();
                }
            }
            catch (SqlException sqlEx)
            {
                devMain.RollbackTran();
                throw sqlEx;
            }
            catch (Exception ex)
            {
                devMain.RollbackTran();
                log.Error(ex);
                throw ex;
            }
            return apiResponseData;
        }
    }
}
