using DeviceRepair.DataAccess.Data;
using DeviceRepair.Models;
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.SysCommon
{
    public class CustomFieldDa : BaseDa
    {
        private static readonly Logger log = LogManager.GetCurrentClassLogger();
        
        public CustomFieldDa(IDictionary<string, string> apiParams) : base(apiParams)
        {

        }

        /// <summary>
        /// 根据字段编码获取数据
        /// </summary>
        /// <returns></returns>
        public DataSet GetDatas()
        {
            DataSet dsDatas = new DataSet("Datas");
            string[] FieldCodes = new string[] { };
            try
            {
                if (ApiParameters.ContainsKey("FieldCode"))
                {
                    FieldCodes = ApiParameters["FieldCode"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                }

                var exp = Expressionable.Create<FieldsInfo>()
                     .AndIF(FieldCodes.Length > 0, x => SqlFunc.ContainsArray(FieldCodes, x.FieldCode)).ToExpression();//拼接表达式

                List<FieldsInfo> Datas = devMain.Queryable<FieldsInfo>().Where(exp).ToList();
                DataTable table = Datas.ToDataTable();
                dsDatas.Tables.Add(table);

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

        /// <summary>
        /// 检验数据是否存在
        /// </summary>
        /// <param name="BeExists"></param>
        /// <returns></returns>
        public APIResponseData Get_Field_Exists(out bool BeExists)
        {
            try
            {
                BeExists = true;

                if (!ApiParameters.ContainsKey("Code"))
                    throw new ArgumentException("传入的字段名称不能为空！");

                if (!ApiParameters.ContainsKey("Text"))
                    throw new ArgumentException("传入的字段值不能为空！");

                string Code = ApiParameters["Code"]?.Trim() ?? "";
                string Text = ApiParameters["Text"]?.Trim() ?? "";

                if (Code.IsNull() || Text.IsNull())
                    throw new ArgumentException("传入的字段名称或字段值不能为空！");

                BeExists = devMain.Queryable<FieldsInfo>().Any(x => x.FieldCode.Equals(Code, StringComparison.CurrentCultureIgnoreCase) && x.FieldText.Equals(Text, StringComparison.CurrentCultureIgnoreCase));

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

        /// <summary>
        /// 修改状态
        /// </summary>
        /// <returns></returns>
        public APIResponseData Change_Field_Status()
        {
            try
            {
                DateTime CurrentDate = DateTime.Now;

                if (!ApiParameters.ContainsKey("OPERATORAUTOID"))
                    throw new ArgumentException("传入的操作员对象参数不正确,操作员不能为空！");

                int Operation = 0;
                if (!int.TryParse(ApiParameters["OPERATORAUTOID"], out Operation))
                    throw new ArgumentException("传入的操作员对象参数不正确！");

                if (!ApiParameters.ContainsKey("AutoID"))
                    throw new ArgumentException("传入的主键编号参数不能为空！");

                if (!ApiParameters.ContainsKey("Description"))
                    throw new ArgumentException("传入的字段说明参数不能为空！");

                if (!ApiParameters.ContainsKey("Status"))
                    throw new ArgumentException("传入的状态字段不能为空！");

                int AutoId = 0;
                if (!int.TryParse(ApiParameters["AutoID"], out AutoId))
                    throw new ArgumentException("传入的主键编号参数不正确！");

                bool Status = false;
                if (!bool.TryParse(ApiParameters["Status"], out Status))
                    throw new ArgumentException("传入的字段状态参数不正确！");

                string Description = ApiParameters["Description"] ?? "";

                devMain.BeginTran();
                FieldsInfo data = devMain.Queryable<FieldsInfo>().Single(x => x.AutoID == AutoId);
                if (data == null)
                    throw new Exception($"{(Status ? "解锁" : "锁定")}出错，主键编号为【{AutoId}】的数据不存在！");

                int Count = devMain.Updateable<FieldsInfo>().UpdateColumns(x => new { x.Status, x.Description, x.ModifyBy, x.ModifyOn })
                         .SetColumns(x => new FieldsInfo() { Status = Status, Description = Description, ModifyBy = Operation, ModifyOn = CurrentDate })
                         .Where(x => x.AutoID == AutoId)
                         .ExecuteCommand();
                bool isSuccess = Count > 0;
                if (!isSuccess)
                    throw new Exception("修改字段状态失败！");

                devMain.CommitTran();
                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>
        /// <returns></returns>
        public APIResponseData InsertOrEdit_Field_Data(DataTable Data)
        {
            try
            {
                DateTime CurrentDate = DateTime.Now;

                if (!ApiParameters.ContainsKey("OPERATORAUTOID"))
                    throw new ArgumentException("传入的操作员对象参数不正确,操作员不能为空！");

                int Operation = 0;
                if (!int.TryParse(ApiParameters["OPERATORAUTOID"], out Operation))
                    throw new ArgumentException("传入的操作员对象参数不正确！");

                devMain.BeginTran();
                /* 自定义字段对象 */
                FieldsInfo Item = DTOHelper<FieldsInfo>.DataTableToList(Data)?.FirstOrDefault();

                if (Item.AutoID == 0)
                {
                    /* 新增 */
                    Item.GUID = Guid.NewGuid();
                    Item.CreatBy = Operation;
                    Item.CreatOn = CurrentDate;
                    Item.Status = true;

                    if (devMain.Queryable<FieldsInfo>().Any(x => x.FieldCode.Equals(Item.FieldCode, StringComparison.CurrentCultureIgnoreCase)
                        && x.FieldText.Equals(Item.FieldText, StringComparison.CurrentCultureIgnoreCase)))
                        throw new Exception($"已存在名称为【{Item.FieldText}】的数据，无法重复添加！");

                    if (devMain.Insertable(Item).ExecuteCommand() != 1)
                        throw new Exception($"执行自定义字段新增失败！");
                }
                else
                {
                    /* 修改 */
                    var old = devMain.Queryable<FieldsInfo>().Single(x => x.AutoID == Item.AutoID);
                    if (old == null)
                        throw new Exception($"传入的修改对象出错，主键编号为【{Item.AutoID}】的数据不存在！");


                    ////记录历史信息
                    //FieldsHistory his = new FieldsHistory
                    //{
                    //    FieldID = Item.AutoID,
                    //    GUID = Item.GUID,
                    //    FieldCode = Item.FieldCode,
                    //    FieldText = Item.FieldText,
                    //    FieldValue = Item.FieldValue,
                    //    FieldType = Item.FieldType,
                    //    Status = Item.Status,
                    //    Description = Item.Description,
                    //    CreatBy = Item.CreatBy,
                    //    CreatOn = Item.CreatOn,
                    //    ModifyBy = Item.ModifyBy,
                    //    ModifyOn = Item.ModifyOn,
                    //    Operator = Operation,
                    //    OperationDate = CurrentDate
                    //};

                    if (devMain.Updateable<FieldsInfo>().UpdateColumns(x => new { x.FieldText, x.FieldValue, x.FieldType, x.ModifyBy, x.ModifyOn })
                         .SetColumns(x => new FieldsInfo() { FieldText = Item.FieldText, FieldValue = Item.FieldValue, FieldType = Item.FieldType, ModifyBy = Operation, ModifyOn = CurrentDate })
                         .Where(x => x.AutoID == Item.AutoID)
                         .ExecuteCommand() != 1)
                        throw new Exception($"执行自定义字段修改失败！");
                }

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