using DeviceRepair.DataAccess.Data;
using DeviceRepair.Models;
using DeviceRepair.Models.OperationHistory.Tag;
using DeviceRepair.Models.Tag;
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.Tag
{
    public class TagDa : BaseDa
    {
        private static readonly Logger log = LogManager.GetCurrentClassLogger();

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

        }

        public DataSet GetDatas()
        {
            DataSet dsDatas = new DataSet("Datas");
            try
            {
                DateTime sDate = DateTime.Today.AddMonths(-1);
                if (ApiParameters.ContainsKey("sDate"))
                {
                    sDate = base.GetParamDateTime("sDate", "开始时间");
                    if (sDate < new DateTime(1900, 01, 01))
                    {
                        sDate = new DateTime(1900, 01, 01);
                    }
                }

                DateTime eDate = DateTime.Today.AddDays(1).AddMilliseconds(-1);
                if (ApiParameters.ContainsKey("eDate"))
                {
                    eDate = base.GetParamDateTime("eDate", "结束时间");
                    if (eDate.Date > DateTime.Today)
                    {
                        sDate = DateTime.Today.AddDays(1).AddMilliseconds(-1);
                    }
                }

                string EquipmentDisPlayID = string.Empty;
                if (ApiParameters.ContainsKey("EquipmentDisPlayID"))
                {
                    EquipmentDisPlayID = base.GetParamString("EquipmentDisPlayID", "设备编号");
                }

                string TagFormStatus = string.Empty;
                if (ApiParameters.ContainsKey("TagFormStatus"))
                {
                    TagFormStatus = base.GetParamString("TagFormStatus", "表单状态");
                }

                var exp = Expressionable.Create<TagRecordInfo>()
                      .And(t1 => t1.CreatOn >= sDate)
                      .And(t1 => t1.CreatOn <= eDate)
                      .AndIF(!string.IsNullOrWhiteSpace(EquipmentDisPlayID), t1 => t1.EquipmentDisPlayID == EquipmentDisPlayID)
                      .AndIF(!string.IsNullOrWhiteSpace(TagFormStatus), t1 => t1.TagFormStatus == TagFormStatus).ToExpression();//拼接表达式

                var Datas = devMain.Queryable<TagRecordInfo>().Where(exp).ToList();
                dsDatas.Tables.Add(Datas.ToDataTable());

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

        /// <summary>
        /// 数据新增
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="dtData"></param>
        /// <returns></returns>
        public APIResponseData Creat(DataTable Data, out DataTable dtData)
        {
            dtData = null;
            try
            {
                DateTime CurrentDate = DateTime.Now;
                EnumOperationType operationType = EnumOperationType.Add;

                if (Data == null || Data.Rows.Count == 0)
                    throw new ArgumentException($"待插入的数据库对象不能为空");

                int Operation = base.GetParamInt("OPERATORAUTOID", "操作员");

                devMain.BeginTran();
                TagRecordInfo Model = DTOHelper<TagRecordInfo>.DataTableToList(Data)?.FirstOrDefault();
                if (Model.AutoID != 0)
                {
                    // tag 表单修改
                    TagRecordInfo tag = devMain.Queryable<TagRecordInfo>().First(x => x.AutoID == Model.AutoID);
                    if (tag == null)
                        throw new Exception($"TagNo.{Model.AutoID}的数据不存在,修改失败!");

                    if (tag.TagFormStatus == "C")
                        throw new Exception($"TagNo.{Model.AutoID}的数据已被修改!");

                    Dictionary<string, string> dc1 = ObjectToMap(Model);
                    Dictionary<string, string> dc2 = ObjectToMap(tag);
                    if (dc1.ContainsKey("CreateBy"))
                        dc1.Remove("CreateBy");
                    if (dc1.ContainsKey("CreatOn"))
                        dc1.Remove("CreatOn");
                    if (dc2.ContainsKey("CreateBy"))
                        dc2.Remove("CreateBy");
                    if (dc2.ContainsKey("CreatOn"))
                        dc2.Remove("CreatOn");
                    if (dc2.ContainsKey("CreatorName"))
                        dc2.Remove("CreatorName");
                    if (dc2.ContainsKey("ModifyBy"))
                        dc2.Remove("ModifyBy");
                    if (dc2.ContainsKey("ModifyOn"))
                        dc2.Remove("ModifyOn");
                    if (dc2.ContainsKey("ModifyName"))
                        dc2.Remove("ModifyName");
                    if (dc2.ContainsKey("TagFormStatus"))
                        dc2.Remove("TagFormStatus");

                    if (CompareDictionaries(dc1, dc2))
                    {
                        throw new Exception("当前操作无更改！");
                    }


                    operationType = EnumOperationType.Change;

                    /* 插入历史记录 */
                    var his = new TagRecordHistory
                    {
                        TagAutoID = tag.AutoID,
                        TagGuid = Guid.NewGuid(),
                        OperationUser = base.OperationInfo.TsSFCUserId,
                        OperationOn = CurrentDate,
                        OperationClient = base.OperationInfo.ComputerName,
                        OperateIP = base.OperationInfo.IPAddress,
                        OperateMAC = base.OperationInfo.Mac,
                        EquipmentID = tag.EquipmentID,
                        EquipmentDisPlayID = tag.EquipmentDisPlayID,
                        EquipmentName = tag.EquipmentName,
                        BrokenDamaged = tag.BrokenDamaged,
                        Access = tag.Access,
                        Clean = tag.Clean,
                        Inspect = tag.Inspect,
                        SourceOfContamination = tag.SourceOfContamination,
                        NotInUse = tag.NotInUse,
                        NotNeeded = tag.NotNeeded,
                        UnsafeConditions = tag.UnsafeConditions,
                        MissingComponents = tag.MissingComponents,
                        DetailsOfIssue = tag.DetailsOfIssue,
                        TagFormStatus = tag.TagFormStatus,
                        CreateBy = tag.CreateBy,
                        CreatOn = tag.CreatOn,
                        CreatorName = tag.CreatorName,
                        ModifyBy = tag.ModifyBy,
                        ModifyOn = tag.ModifyOn,
                        ModifyName = tag.ModifyName,
                        ReceiptBy = tag.ReceiptBy,
                        ReceiptOn = tag.ReceiptOn,
                        ReceiptDetailsOfIssue = tag.ReceiptDetailsOfIssue,
                        ReceiptName = tag.ReceiptName
                    };

                    tag.BrokenDamaged = Model.BrokenDamaged;
                    tag.Access = Model.Access;
                    tag.Clean = Model.Clean;
                    tag.Inspect = Model.Inspect;
                    tag.SourceOfContamination = Model.SourceOfContamination;
                    tag.NotInUse = Model.NotInUse;
                    tag.NotNeeded = Model.NotNeeded;
                    tag.UnsafeConditions = Model.UnsafeConditions;
                    tag.MissingComponents = Model.MissingComponents;
                    tag.DetailsOfIssue = Model.DetailsOfIssue;
                    tag.ModifyBy = Operation;
                    tag.ModifyName = ApiParameters["OPERATORNAME"];
                    tag.ModifyOn = CurrentDate;
                    if (devMain.Updateable(tag).ExecuteCommand() > 0)
                    {
                        devMain.CommitTran();
                        dtData = tag.toDataTable();

                        try
                        {
                            devLog.Insertable(his).ExecuteCommand();
                            // 操作日志
                            OperationHistory(new TagRecordLog
                            {
                                HisAutoID = Model.AutoID,
                                HisGuid = Guid.Empty,
                                Note = ""
                            }, operationType, "TagRecordLog", CurrentDate);
                        }
                        catch
                        {

                        }

                        return new APIResponseData { Code = 1 };
                    }
                }

                DeviceInformationInfo dev = devMain.Queryable<DeviceInformationInfo>().First(x => x.EquipmentID == Model.EquipmentDisPlayID && x.EquipmentStatus == 1);
                if (dev == null)
                    throw new Exception("传入的设备信息出错或设备未启用!");

                Model.EquipmentDisPlayID = dev.EquipmentID;
                Model.EquipmentName = dev.EquipmentName;
                Model.EquipmentID = dev.AutoID;
                Model.CreateBy = Operation;
                Model.CreatOn = CurrentDate;
                Model.CreatorName = ApiParameters["OPERATORNAME"];
                Model.TagFormStatus = "N";

                TagRecordInfo Rtn = devMain.Insertable(Model).ExecuteReturnEntity();
                if (Rtn == null)
                {
                    throw new Exception("数据库写入出错!");
                }
                devMain.CommitTran();

                // 操作日志
                OperationHistory(new TagRecordLog
                {
                    HisAutoID = Model.AutoID,
                    HisGuid = Guid.Empty,
                    Note = ""
                }, operationType, "TagRecordLog", CurrentDate);

                dtData = Model.toDataTable();
                return new APIResponseData { Code = 1 };
            }
            catch (SqlException sqlEx)
            {
                devMain.RollbackTran();
                throw sqlEx;
            }
            catch (Exception ex)
            {
                devMain.RollbackTran();
                log.Error(ex);
                throw ex;
            }
        }

        /// <summary>
        /// 接受/维修
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="dtData"></param>
        /// <returns></returns>
        public APIResponseData Receipt(DataTable Data, out DataTable dtData)
        {
            try
            {
                dtData = null;
                DateTime CurrentTime = DateTime.Now;

                if (Data == null || Data.Rows.Count == 0)
                    throw new ArgumentException($"待插入的数据库对象不能为空");

                TagRecordInfo Model = DTOHelper<TagRecordInfo>.DataTableToList(Data)?.FirstOrDefault();

                TagRecordInfo tagRecordInfo = devMain.Queryable<TagRecordInfo>().First(x => x.AutoID == Model.AutoID);
                if (tagRecordInfo == null)
                    throw new Exception($"找不到Tag编号为【{Model.AutoID}】的Tag表单!");

                int Operation = base.GetParamInt("TagOperation", "电子签操作员");
                CurrentTime = base.GetParamDateTime("TagOperationDate", "电子签操作时间");

                string TagOperationName = base.GetParamString("TagOperationName", "电子签操作人名称");

                TagOperationName = ApiParameters["TagOperationName"];

                tagRecordInfo.ReceiptBy = Operation;
                tagRecordInfo.ReceiptName = TagOperationName;
                tagRecordInfo.ReceiptOn = CurrentTime;
                tagRecordInfo.ReceiptDetailsOfIssue = Model.ReceiptDetailsOfIssue;
                tagRecordInfo.TagFormStatus = "C";

                devMain.BeginTran();
                int Rtn = devMain.Updateable(tagRecordInfo).ExecuteCommand();
                if (Rtn > 0)
                {
                    devMain.CommitTran();

                    // 操作日志
                    OperationHistory(new TagRecordLog
                    {
                        HisAutoID = Model.AutoID,
                        HisGuid = Guid.Empty,
                        Note = "电子签"
                    }, EnumOperationType.UserConfirm, "TagRecordLog", CurrentTime);

                    dtData = tagRecordInfo.toDataTable();
                    return new APIResponseData { Code = 1 };
                }
                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;
            }
        }
    }
}
