using AutoMapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Performance.EntityModels.Entity;
using Performance.Repository.Repository;
using System.Linq.Expressions;

namespace Performance.Services
{
    public class ConfigService : IAutoInjection
    {
        #region
        private readonly PerforCofdirectorRepository _directorRepository;
        //private readonly PerforCofdrugpropRepository _drugpropRepository;
        private readonly PerforCofworkitemRepository _workitemRepository;
        private readonly PerforCofagainRepository _againRepository;
        private readonly PerforCofdrugtypeRepository _drugtypeRepository;
        private readonly PerforPerallotRepository perforPerAllotRepository;
        private readonly PerforHospitalRepository perforHospitalRepository;
        private readonly PerforPersheetRepository perforPersheetRepository;
        private readonly PerforImheaderRepository perforImheaderRepository;
        private readonly PerforCofdepttypeRepository perforCofdepttypeRepository;
        private readonly PerforPerapramountRepository perapramountRepository;
        //private readonly PerforCofcmiRepository perforCofcmiRepository;
        private readonly PerforCofHrpDeptRepository perforCofHrpDeptRepository;
        private readonly PerforCofaliasRepository perforCofaliasRepository;
        private readonly PerforCofaccountingRepository cofaccountingRepository;
        private readonly PersonService personService;
        private readonly LogManageService logManageService;
        private readonly ILogger<ConfigService> logger;

        public ConfigService(PerforCofdirectorRepository cofdirectorRepository,
            //PerforCofdrugpropRepository cofdrugpropRepository,
            PerforCofagainRepository againRepository,
            PerforCofdrugtypeRepository drugtypeRepository,
            PerforPerallotRepository perforPerAllotRepository,
            PerforHospitalRepository perforHospitalRepository,
            PerforCofworkitemRepository workitemRepository,
            PerforPersheetRepository perforPersheetRepository,
            PerforImheaderRepository perforImheaderRepository,
            PerforCofdepttypeRepository perforCofdepttypeRepository,
            PerforPerapramountRepository perapramountRepository,
            //PerforCofcmiRepository perforCofcmiRepository,
            PerforCofHrpDeptRepository perforCofHrpDeptRepository,
            PerforCofaliasRepository perforCofaliasRepository,
            PerforCofaccountingRepository cofaccountingRepository,
            PersonService personService,
            LogManageService logManageService,
            ILogger<ConfigService> logger)
        {
            this._directorRepository = cofdirectorRepository;
            //this._drugpropRepository = cofdrugpropRepository;
            this._workitemRepository = workitemRepository;
            this._againRepository = againRepository;
            this._drugtypeRepository = drugtypeRepository;
            this.perforPerAllotRepository = perforPerAllotRepository;
            this.perforHospitalRepository = perforHospitalRepository;
            this.perforPersheetRepository = perforPersheetRepository;
            this.perforImheaderRepository = perforImheaderRepository;
            this.perforCofdepttypeRepository = perforCofdepttypeRepository;
            this.perapramountRepository = perapramountRepository;
            //this.perforCofcmiRepository = perforCofcmiRepository;
            this.perforCofHrpDeptRepository = perforCofHrpDeptRepository;
            this.perforCofaliasRepository = perforCofaliasRepository;
            this.cofaccountingRepository = cofaccountingRepository;
            this.personService = personService;
            this.logManageService = logManageService;
            this.logger = logger;
        }

        #endregion

        #region 弃用

        //#region cof_director  规模/效率绩效配置
        ///// <summary>
        ///// 获取cof_director列表
        ///// </summary>
        ///// <returns></returns>
        //public List<DirectorResponse> GetDireList(int allotId)
        //{
        //    var list = _directorRepository.GetEntities(t => t.AllotID == allotId);
        //    return Mapper.Map<List<DirectorResponse>>(list);
        //}

        ///// <summary>
        ///// 添加数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public DirectorResponse DireInsert(DirectorRequest request)
        //{
        //    var director = Mapper.Map<cof_director>(request);
        //    if (!_directorRepository.Add(director))
        //        throw new PerformanceException("保存失败");
        //    return Mapper.Map<DirectorResponse>(director);
        //}

        ///// <summary>
        ///// 更新数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public DirectorResponse DireUpdate(DirectorRequest request)
        //{
        //    var director = _directorRepository.GetEntity(t => t.ID == request.ID);
        //    if (null == director)
        //        throw new PerformanceException($"ID不存在 ：{request.ID}");

        //    director.TypeName = request.TypeName;
        //    director.JobTitle = request.JobTitle;
        //    director.Value = request.Value;

        //    if (!_directorRepository.Update(director))
        //        throw new PerformanceException("保存失败");
        //    return Mapper.Map<DirectorResponse>(director);
        //}

        ///// <summary>
        ///// 删除数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public bool DireDelete(DirectorRequest request)
        //{
        //    var director = _directorRepository.GetEntity(t => t.ID == request.ID);
        //    if (null == director)
        //        throw new PerformanceException($"ID不存在 ：{request.ID}");

        //    return _directorRepository.Remove(director);
        //}
        //#endregion

        //#region cof_income  ICU有效收入配置
        ///// <summary>
        ///// 获取cof_income列表
        ///// </summary>
        ///// <returns></returns>
        //public List<IncomeResponse> GetIncomeList(int allotId)
        //{
        //    var list = _incomeRepository.GetEntities(T => T.AllotID == allotId);
        //    return Mapper.Map<List<IncomeResponse>>(list);
        //}

        ///// <summary>
        ///// 添加数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public IncomeResponse IncomeInsert(IncomeRequest request)
        //{
        //    var income = Mapper.Map<cof_income>(request);
        //    if (!_incomeRepository.Add(income))
        //        throw new PerformanceException("保存失败");
        //    return Mapper.Map<IncomeResponse>(income);
        //}

        ///// <summary>
        ///// 更新数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public IncomeResponse IncomeUpdate(IncomeRequest request)
        //{
        //    var income = _incomeRepository.GetEntity(t => t.ID == request.ID);
        //    if (null == income)
        //        throw new PerformanceException($"ID不存在 ：{request.ID}");

        //    income.SheetNameKeyword = request.SheetNameKeyword;
        //    income.UnitName = request.UnitName;
        //    income.Value = request.Value;

        //    if (!_incomeRepository.Update(income))
        //        throw new PerformanceException("保存失败");
        //    return Mapper.Map<IncomeResponse>(income);
        //}

        ///// <summary>
        ///// 删除数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public bool IncomeDelete(IncomeRequest request)
        //{
        //    var income = _incomeRepository.GetEntity(t => t.ID == request.ID);
        //    if (null == income)
        //        throw new PerformanceException($"ID不存在 ：{request.ID}");

        //    return _incomeRepository.Remove(income);
        //}
        //#endregion

        //#region cof_workyear  年资系数配置
        ///// <summary>
        ///// 获取cof_drugprop列表
        ///// </summary>
        ///// <returns></returns>
        //public List<WorkyearResponse> GetWorkList(int allotId)
        //{
        //    var list = _workyearRepository.GetEntities(t => t.AllotID == allotId);
        //    return Mapper.Map<List<WorkyearResponse>>(list);
        //}

        ///// <summary>
        ///// 添加数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public WorkyearResponse WorkInsert(WorkyearRequest request)
        //{
        //    var workyear = Mapper.Map<cof_workyear>(request);
        //    if (!_workyearRepository.Add(workyear))
        //        throw new PerformanceException("保存失败");
        //    return Mapper.Map<WorkyearResponse>(workyear);
        //}

        ///// <summary>
        ///// 更新数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public WorkyearResponse WorkUpdate(WorkyearRequest request)
        //{
        //    var workyear = _workyearRepository.GetEntity(t => t.ID == request.ID);
        //    if (null == workyear)
        //        throw new PerformanceException($"ID不存在 ：{request.ID}");

        //    workyear.MaxRange = request.MaxRange;
        //    workyear.MinRange = request.MinRange;
        //    workyear.Value = request.Value;

        //    if (!_workyearRepository.Update(workyear))
        //        throw new PerformanceException("保存失败");
        //    return Mapper.Map<WorkyearResponse>(workyear);
        //}

        ///// <summary>
        ///// 删除数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public bool WorkDelete(WorkyearRequest request)
        //{
        //    var workyear = _workyearRepository.GetEntity(t => t.ID == request.ID);
        //    if (null == workyear)
        //        throw new PerformanceException($"ID不存在 ：{request.ID}");

        //    return _workyearRepository.Remove(workyear);
        //}
        //#endregion

        #endregion

        #region cof_drugprop  药占比系数配置

        ///// <summary>
        ///// 获取cof_drugprop列表
        ///// </summary>
        ///// <returns></returns>
        //public List<DrugpropResponse> GetDrugList(int allotId)
        //{
        //    var list = _drugpropRepository.GetEntities(t => t.AllotID == allotId);
        //    return Mapper.Map<List<DrugpropResponse>>(list);
        //}

        ///// <summary>
        ///// 添加数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public DrugpropResponse DrugInsert(DrugpropRequest request)
        //{
        //    var drugprop = Mapper.Map<cof_drugprop>(request);
        //    if (!_drugpropRepository.Add(drugprop))
        //        throw new PerformanceException("保存失败");
        //    return Mapper.Map<DrugpropResponse>(drugprop);
        //}

        ///// <summary>
        ///// 更新数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public DrugpropResponse DrugUpdate(DrugpropRequest request)
        //{
        //    var drugprop = _drugpropRepository.GetEntity(t => t.ID == request.ID);
        //    if (null == drugprop)
        //        throw new PerformanceException($"ID不存在 ：{request.ID}");

        //    drugprop.MaxRange = request.MaxRange;
        //    drugprop.MinRange = request.MinRange;
        //    drugprop.Value = request.Value;

        //    if (!_drugpropRepository.Update(drugprop))
        //        throw new PerformanceException("保存失败");
        //    return Mapper.Map<DrugpropResponse>(drugprop);
        //}

        ///// <summary>
        ///// 删除数据
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public bool DrugDelete(DrugpropRequest request)
        //{
        //    var drugprop = _drugpropRepository.GetEntity(t => t.ID == request.ID);
        //    if (null == drugprop)
        //        throw new PerformanceException($"ID不存在 ：{request.ID}");

        //    return _drugpropRepository.Remove(drugprop);
        //}

        #endregion

        #region cof_drugtype  药占比类别配置

        /// <summary>
        /// 获取cof_drugprop列表
        /// </summary>
        /// <returns></returns>
        public List<cof_drugtype> GetDrugtypeList(int HospitalId, int allotId)
        {
            var list = _drugtypeRepository.GetEntities(t => t.AllotID == allotId && t.HospitalId == HospitalId);
            return list;
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_drugtype DrugtypeInsert(DrugpropRequest request)
        {
            var entity = new cof_drugtype
            {
                HospitalId = request.HospitalId,
                AllotID = request.AllotID,
                Charge = request.Charge,
                ChargeType = request.ChargeType
            };
            if (!_drugtypeRepository.Add(entity))
                throw new PerformanceException("保存失败");
            return entity;
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_drugtype DrugtypeUpdate(DrugpropRequest request)
        {
            var entity = _drugtypeRepository.GetEntity(t => t.ID == request.ID);
            if (null == entity)
                throw new PerformanceException($"ID不存在 ：{request.ID}");

            entity.Charge = request.Charge;
            entity.ChargeType = request.ChargeType;

            if (!_drugtypeRepository.Update(entity))
                throw new PerformanceException("保存失败");
            return entity;
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool DrugtypeDelete(DrugpropRequest request)
        {
            var entity = _drugtypeRepository.GetEntity(t => t.ID == request.ID);
            if (null == entity)
                throw new PerformanceException($"ID不存在 ：{request.ID}");

            return _drugtypeRepository.Remove(entity);
        }

        #endregion

        #region cof_workitem  工作量绩效

        /// <summary>
        /// 获取cof_workitem列表
        /// </summary>
        /// <returns></returns>
        public List<cof_workitem> GetWorkItems(int allotId, int type)
        {
            var list = (type > 0)
                ? _workitemRepository.GetEntities(t => t.AllotID == allotId && t.Type == type)
                : _workitemRepository.GetEntities(t => t.AllotID == allotId);

            return Mapper.Map<List<cof_workitem>>(list);
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_workitem WorkItemInsert(WorkItemRequest request)
        {
            var workyear = Mapper.Map<cof_workitem>(request);
            if (!_workitemRepository.Add(workyear))
                throw new PerformanceException("保存失败");
            return Mapper.Map<cof_workitem>(workyear);
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_workitem WorkItemUpdate(WorkItemRequest request)
        {
            var workyear = _workitemRepository.GetEntity(t => t.ID == request.ID);
            if (null == workyear)
                throw new PerformanceException($"ID不存在 ：{request.ID}");

            workyear.Item = request.Item;
            workyear.Type = request.Type;

            if (!_workitemRepository.Update(workyear))
                throw new PerformanceException("保存失败");
            return Mapper.Map<cof_workitem>(workyear);
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool WorkItemkDelete(WorkItemRequest request)
        {
            var workyear = _workitemRepository.GetEntity(t => t.ID == request.ID);
            if (null == workyear)
                throw new PerformanceException($"ID不存在 ：{request.ID}");

            return _workitemRepository.Remove(workyear);
        }

        #endregion

        #region cof_depttype  科室别配置

        /// <summary>
        /// 获取cof_drugprop列表
        /// </summary>
        /// <returns></returns>
        public List<cof_depttype> GetDepttypeList(int allotId)
        {
            var list = perforCofdepttypeRepository.GetEntities(t => t.AllotID == allotId);
            return list;
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_depttype DepttypeInsert(DrugpropRequest request)
        {
            var entity = new cof_depttype
            {
                AllotID = request.AllotID,
                Charge = request.Charge,
                ChargeType = request.ChargeType
            };
            if (!perforCofdepttypeRepository.Add(entity))
                throw new PerformanceException("保存失败");
            return entity;
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_depttype DepttypeUpdate(DrugpropRequest request)
        {
            var entity = perforCofdepttypeRepository.GetEntity(t => t.ID == request.ID);
            if (null == entity)
                throw new PerformanceException($"ID不存在 ：{request.ID}");

            entity.Charge = request.Charge;
            entity.ChargeType = request.ChargeType;

            if (!perforCofdepttypeRepository.Update(entity))
                throw new PerformanceException("保存失败");
            return entity;
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool DepttypeDelete(DrugpropRequest request)
        {
            var entity = perforCofdepttypeRepository.GetEntity(t => t.ID == request.ID);
            if (null == entity)
                throw new PerformanceException($"ID不存在 ：{request.ID}");

            return perforCofdepttypeRepository.Remove(entity);
        }

        #endregion

        #region cof_cmi  cmi

        ///// <summary>
        ///// 获取 CMI配置
        ///// </summary>
        ///// <returns></returns>
        //public List<cof_cmi> GetCMIList(int allotId)
        //{
        //    var list = perforCofcmiRepository.GetEntities(t => t.AllotId == allotId);
        //    return list;
        //}

        ///// <summary>
        ///// 添加 CMI配置
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public cof_cmi HosCMIInsert(cof_cmi request)
        //{
        //    if (!perforCofcmiRepository.Add(request))
        //        throw new PerformanceException("保存失败");
        //    return request;
        //}

        ///// <summary>
        ///// 更新 CMI配置
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public cof_cmi HosCMIUpdate(cof_cmi request)
        //{
        //    var entity = perforCofcmiRepository.GetEntity(t => t.Id == request.Id);
        //    if (null == entity)
        //        throw new PerformanceException($"ID不存在 ：{request.Id}");

        //    entity.UnitType = request.UnitType;
        //    entity.AccountingUnit = request.AccountingUnit;
        //    entity.Value = request.Value;

        //    if (!perforCofcmiRepository.Update(entity))
        //        throw new PerformanceException("保存失败");
        //    return entity;
        //}

        ///// <summary>
        ///// 删除 CMI配置
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public bool HosCMIDelete(cof_cmi request)
        //{
        //    var entity = perforCofcmiRepository.GetEntity(t => t.Id == request.Id);
        //    if (null == entity)
        //        throw new PerformanceException($"ID不存在 ：{request.Id}");

        //    return perforCofcmiRepository.Remove(entity);
        //}

        #endregion

        #region cof_again

        /// <summary>
        /// 获取cof_drugprop列表
        /// </summary>
        /// <returns></returns>
        public List<cof_again> GetAgainList(int allotId)
        {
            var list = _againRepository.GetEntities(t => t.AllotID == allotId);
            return list;
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_again AgainInsert(CofAgainRequest request)
        {
            var again = Mapper.Map<cof_again>(request);
            if (!_againRepository.Add(again))
                throw new PerformanceException("保存失败");
            return again;
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_again AgainUpdate(CofAgainRequest request)
        {
            var again = _againRepository.GetEntity(t => t.ID == request.ID);
            if (null == again)
                throw new PerformanceException($"ID不存在 ：{request.ID}");

            again.Type = request.Type;
            again.Department = request.Department;
            again.TypeName = request.TypeName;
            again.Value = request.Value;

            if (!_againRepository.Update(again))
                throw new PerformanceException("保存失败");
            return again;
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool AgainDelete(CofAgainRequest request)
        {
            var again = _againRepository.GetEntity(t => t.ID == request.ID);
            if (null == again)
                throw new PerformanceException($"ID不存在 ：{request.ID}");

            return _againRepository.Remove(again);
        }

        #endregion

        #region cof_accounting  核算单元及类别（4.1）配置

        /// <summary>
        /// 获取cof_accounting列表
        /// </summary>
        /// <returns></returns>
        public List<cof_accounting> GetAccountingList(AccoungingRequest request)
        {
            Expression<Func<cof_accounting, bool>> exp = t => t.AllotId == request.AllotId;
            if (request.AllotId == 0)
            {
                var allots = perforPerAllotRepository.GetEntities(t => t.HospitalId == request.HospitalId);
                if (allots == null || !allots.Any())
                    throw new PerformanceException("请先配置科室信息");
                exp = t => allots.Select(a => a.ID).Contains(t.AllotId);
            }

            if (request.Type == (int)AccountTypeEnum.AccountingUnit && !string.IsNullOrEmpty(request.UnitType))
                exp = exp.And(t => t.UnitType == request.UnitType);

            return cofaccountingRepository.GetEntities(exp) ?? new List<cof_accounting>();
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_accounting AccountingInsert(cof_accounting request)
        {
            var entity = new cof_accounting
            {
                AllotId = request.AllotId,
                UnitType = request.UnitType,
                AccountingUnit = request.AccountingUnit
            };
            if (!cofaccountingRepository.Add(entity))
                throw new PerformanceException("保存失败");
            return entity;
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_accounting AccountingUpdate(cof_accounting request)
        {
            var entity = cofaccountingRepository.GetEntity(t => t.Id == request.Id);
            if (null == entity)
                throw new PerformanceException($"ID不存在 ：{request.Id}");

            entity.AllotId = request.AllotId;
            entity.UnitType = request.UnitType;
            entity.AccountingUnit = request.AccountingUnit;

            if (!cofaccountingRepository.Update(entity))
                throw new PerformanceException("保存失败");
            return entity;
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="accountingId"></param>
        /// <returns></returns>
        public bool AccountingDelete(int accountingId)
        {
            var entity = cofaccountingRepository.GetEntity(t => t.Id == accountingId);
            if (null == entity)
                throw new PerformanceException($"ID不存在 ：{accountingId}");

            return cofaccountingRepository.Remove(entity);
        }

        public HandsonTable GetBatchAccountingStructrue(int AllotId)
        {
            var result = new HandsonTable((int)SheetType.Unidentifiable, Accounting.Select(t => t.Value).ToArray(), Accounting.Select(t => new collect_permission
            {
                HeadName = t.Value,
                Visible = 1
            }).ToList());

            if (result.Columns != null && result.Columns.Any())
            {
                foreach (var column in result.Columns)
                {

                    if (column.Data == "核算组别")
                    {
                        column.Type = "autocomplete";
                        column.Source = EnumHelper.GetItems<UnitType>().Select(w => w.Description.Replace("行政后勤", "行政工勤")).ToArray();
                        column.Strict = true;
                    }
                }
            }
            return result;
        }

        public bool BatchSaveAccounting(int allotId, SaveCollectData request)
        {
            var dicData = CreateDataRow(0, allotId, request, Accounting);
            var getAccounts = cofaccountingRepository.GetEntities(t => t.AllotId == allotId);
            var unitType = EnumHelper.GetItems<UnitType>().Select(w => w.Description.Replace("行政后勤", "行政工勤")).ToArray();
            List<cof_accounting> accounts = new List<cof_accounting>();
            foreach (var item in dicData)
            {
                var json = JsonHelper.Serialize(item);
                var data = JsonHelper.Deserialize<cof_accounting>(json);

                if (!unitType.Contains(data?.UnitType) && !string.IsNullOrEmpty(data?.UnitType)) return false;
                if (getAccounts != null)
                    if (getAccounts.Any(t => t.AccountingUnit == data?.AccountingUnit && t.UnitType == data?.UnitType)) continue;
                var any = accounts.Any(t => t.AccountingUnit == data?.AccountingUnit && t.UnitType == data?.UnitType);

                if (!string.IsNullOrEmpty(data.AccountingUnit) && !string.IsNullOrEmpty(data.UnitType) && !any)
                {
                    accounts.Add(data);
                }
            }
            if (accounts.Any())
                cofaccountingRepository.AddRange(accounts.ToArray());
            return true;
        }

        public static Dictionary<string, string> Accounting { get; } = new Dictionary<string, string>
        {
            {nameof(cof_accounting.AccountingUnit), "核算单元"},
            {nameof(cof_accounting.UnitType), "核算组别"},
        };


        #endregion

        #region Copy

        /// <summary>
        /// 复制报表基础配置
        /// </summary>
        /// <param name="iD"></param>
        public void Copy(per_allot allot)
        {
            var list = perforPerAllotRepository.GetEntities(t => t.HospitalId == allot.HospitalId)
                         .OrderBy(t => t.Year).ThenBy(t => t.Month).ToList();
            int allotId = 0;
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].ID == allot.ID && (i - 1) >= 0)
                    allotId = list[i - 1].ID;
            }
            var hospital = perforHospitalRepository.GetEntity(t => t.ID == allot.HospitalId);

            logger.LogInformation($"apramount{allotId} {allot.ID}");
            //CopyAprData(allotId, allot.ID);

            personService.CreateAllotPersons(allot.HospitalId, allot.ID, allotId);

            //CopyCMIData(allotId, allot.ID);

            #region 弃用

            //var orgDirector = _directorRepository.GetEntities(t => t.AllotID == allot.ID);
            //if (orgDirector == null || orgDirector.Count == 0)
            //{
            //    var director = _directorRepository.GetEntities(t => t.AllotID == allotId) ?? _directorRepository.GetEntities(t => t.AllotID == -1);
            //    var newDirectors = director.Select(t => new cof_director { AllotID = allot.ID, JobTitle = t.JobTitle, TypeName = t.TypeName, Value = t.Value });
            //    if (hospital != null && hospital?.IsOpenDirector == 2)
            //        newDirectors = director.Select(t => new cof_director { AllotID = allot.ID, JobTitle = t.JobTitle, TypeName = t.TypeName, Value = 1 });
            //    _directorRepository.AddRange(newDirectors.ToArray());
            //}

            //var orgIncome = _incomeRepository.GetEntities(t => t.AllotID == allot.ID);
            //if (orgIncome == null || orgIncome.Count == 0)
            //{
            //    var income = _incomeRepository.GetEntities(t => t.AllotID == allotId) ?? _incomeRepository.GetEntities(t => t.AllotID == -1);
            //    var newIncomes = income.Select(t => new cof_income { AllotID = allot.ID, SheetNameKeyword = t.SheetNameKeyword, UnitName = t.UnitName, Value = t.Value });
            //    if (hospital != null && hospital?.IsOpenIncome == 2)
            //        newIncomes = income.Select(t => new cof_income { AllotID = allot.ID, SheetNameKeyword = t.SheetNameKeyword, UnitName = t.UnitName, Value = 1 });
            //    _incomeRepository.AddRange(newIncomes.ToArray());
            //}

            //var orgWorkyear = _workyearRepository.GetEntities(t => t.AllotID == allot.ID);
            //if (orgWorkyear == null || orgWorkyear.Count == 0)
            //{
            //    var workyear = _workyearRepository.GetEntities(t => t.AllotID == allotId) ?? _workyearRepository.GetEntities(t => t.AllotID == -1);
            //    var newWorkyears = workyear.Select(t => new cof_workyear { AllotID = allot.ID, MaxRange = t.MaxRange, MinRange = t.MinRange, Value = t.Value });
            //    if (hospital != null && hospital?.IsOpenWorkYear == 2)
            //        newWorkyears = new List<cof_workyear> { new cof_workyear { AllotID = allot.ID, MaxRange = 1000, MinRange = 0, Value = 1 } };
            //    _workyearRepository.AddRange(newWorkyears.ToArray());
            //}

            #endregion

            //logger.LogInformation($"orgDurgprop");
            //var orgDurgprop = _drugpropRepository.GetEntities(t => t.AllotID == allot.ID);
            //if (orgDurgprop == null || orgDurgprop.Count == 0)
            //{
            //    var durgprop = _drugpropRepository.GetEntities(t => t.AllotID == allotId) ?? _drugpropRepository.GetEntities(t => t.AllotID == -1);
            //    var newDurgprops = durgprop?.Select(t => new cof_drugprop { AllotID = allot.ID, MaxRange = t.MaxRange, MinRange = t.MinRange, Value = t.Value });
            //    //if (hospital != null && hospital?.IsOpenDrugprop == 2)
            //    //    newDurgprops = new List<cof_drugprop> { new cof_drugprop { AllotID = allot.ID, MaxRange = 1000, MinRange = 0, Value = 1 } };
            //    if (durgprop != null && durgprop.Any())
            //        _drugpropRepository.AddRange(newDurgprops.ToArray());
            //}

            logger.LogInformation($"workItem");
            var workItem = _workitemRepository.GetEntities(t => t.AllotID == allot.ID);
            if (workItem == null || workItem.Count == 0)
            {
                workItem = _workitemRepository.GetEntities(t => t.AllotID == allotId) ?? _workitemRepository.GetEntities(t => t.AllotID == -1);
                if (workItem != null && workItem.Count > 0)
                {
                    var newWorkItem = workItem.Select(t => new cof_workitem { AllotID = allot.ID, Type = t.Type, Item = t.Item });
                    _workitemRepository.AddRange(newWorkItem.ToArray());
                }
            }

            logger.LogInformation($"cofDrugtype");
            var cofDrugtype = _drugtypeRepository.GetEntities(t => t.AllotID == allot.ID);
            if (cofDrugtype == null || cofDrugtype.Count == 0)
            {
                var drugtype = _drugtypeRepository.GetEntities(t => t.AllotID == allotId) ?? _drugtypeRepository.GetEntities(t => t.AllotID == -1);
                var newAgains = drugtype.Select(t => new cof_drugtype { HospitalId = allot.HospitalId, AllotID = allot.ID, Charge = t.Charge, ChargeType = t.ChargeType });
                _drugtypeRepository.AddRange(newAgains.ToArray());
            }

            logger.LogInformation($"cofDepttype");
            var cofDepttype = perforCofdepttypeRepository.GetEntities(t => t.AllotID == allot.ID);
            if (cofDepttype == null || cofDepttype.Count == 0)
            {
                var depttype = perforCofdepttypeRepository.GetEntities(t => t.AllotID == allotId)
                    ?? perforCofdepttypeRepository.GetEntities(t => t.AllotID == -1);
                var newAgains = depttype?.Select(t => new cof_depttype { AllotID = allot.ID, Charge = t.Charge, ChargeType = t.ChargeType });
                if (newAgains != null && newAgains.Any())
                    perforCofdepttypeRepository.AddRange(newAgains.ToArray());
            }

            logger.LogInformation($"again");
            var data = _againRepository.GetEntities(t => t.AllotID == allot.ID);
            if (data == null || data.Count == 0)
            {
                var again = _againRepository.GetEntities(t => t.AllotID == allotId) ?? _againRepository.GetEntities(t => t.AllotID == -1);
                var days = DateTime.DaysInMonth(allot.Year, allot.Month);
                var newAgains = again.Select(t => new cof_again
                { AllotID = allot.ID, Type = t.Type, Department = t.Department, TypeName = t.TypeName, Value = t.TypeName == "满勤天数" ? days : t.Value });
                _againRepository.AddRange(newAgains.ToArray());
            }

            logger.LogInformation($"accounting");
            var accountings = cofaccountingRepository.GetEntities(t => t.AllotId == allot.ID);
            if (accountings == null || accountings.Count == 0)
            {
                var prevData = cofaccountingRepository.GetEntities(t => t.AllotId == allotId);
                var newData = prevData?.Select(t => new cof_accounting { AllotId = allot.ID, UnitType = t.UnitType, AccountingUnit = t.AccountingUnit });
                if (newData != null && newData.Any())
                    cofaccountingRepository.AddRange(newData.ToArray());
            }
        }

        #endregion

        #region 清楚无效数据 Clear

        /// <summary>
        /// 清楚无效数据
        /// </summary>
        /// <param name="allotId"></param>
        public void Clear(int allotId)
        {
            var count = _directorRepository.DeleteData(allotId);
            logManageService.WriteMsg("清理无效数据", $"清理无效数据，受影响行数：{count}", 1, allotId, "ReceiveMessage", true);
        }

        /// <summary>
        /// 删除绩效相关数据
        /// </summary>
        /// <param name="allotId"></param>
        public void ClearAllotData(int allotId)
        {
            var count = _directorRepository.DeleteAllotData(allotId);
            logManageService.WriteMsg("清理无效数据", $"清理无效数据，受影响行数：{count}", 1, allotId, "ReceiveMessage", true);
        }

        /// <summary>
        /// 清除核算数据
        /// </summary>
        /// <param name="allotId"></param>
        public void ClearResData(int allotId)
        {
            var count = _directorRepository.DeleteResData(allotId);
            logManageService.WriteMsg("清理无效数据", $"清理无效数据，受影响行数：{count}", 1, allotId, "ReceiveMessage", true);
        }

        /// <summary>
        /// 清除二次绩效中无效数据
        /// </summary>
        /// <param name="againId"></param>
        public void ClearAgain(int againId)
        {
            var count = _directorRepository.DelAgain(againId);
            logManageService.WriteMsg("清理无效数据", $"清除二次绩效中无效数据，受影响行数：{count}", 1, againId, "ReceiveMessage", true);
        }

        #endregion

        /// <summary>
        /// 获取工作量绩效列头
        /// </summary>
        /// <returns></returns>
        public List<TitleValue> WorkHeader(int allotId)
        {
            var sheets = perforPersheetRepository.GetEntities(t => t.AllotID == allotId && t.SheetName.Contains("工作量"));
            if (sheets == null)
                return new List<TitleValue>();
            var header = perforImheaderRepository.GetEntities(t => sheets.Select(s => s.ID).Contains(t.SheetID.Value) && !t.CellValue.Contains("核算单元") && t.CellValue != "科室名称")?.ToList();
            if (header != null && header.Count > 0)
            {
                var list = header.Select(t => t.CellValue).Where(t => !string.IsNullOrEmpty(t)).Distinct();
                return list?.Select(t => new TitleValue { Title = t, Value = t }).ToList();
            }
            return null;
        }

        /// <summary>
        /// 人员绩效额外金额
        /// </summary>
        private void CopyAprData(int prevAllotId, int allotId)
        {
            if (prevAllotId == 0) return;
            var list = perapramountRepository.GetEntities(t => new List<int> { prevAllotId, allotId }.Contains(t.AllotId));
            if (list == null || !list.Any(t => t.AllotId == prevAllotId)) return;

            if (list.Any(t => t.AllotId == allotId))
            {
                var prevData = list.Where(t => t.AllotId == prevAllotId);
                var existData = list.Where(t => t.AllotId == allotId);
                if (existData != null && existData.Any())
                    list = prevData.Where(t => !existData.Select(w => w.PersonnelNumber).Contains(t.PersonnelNumber)).ToList();
            }
            if (list.Any())
            {
                var data = list.Select(t => new per_apr_amount
                {
                    Status = 2,
                    AllotId = allotId,
                    PersonnelNumber = t.PersonnelNumber,
                    DoctorName = t.DoctorName,
                    PerforType = t.PerforType,
                    Amount = t.Amount,
                    CreateDate = DateTime.Now
                });
                perapramountRepository.AddRange(data.ToArray());
            }
        }


        #region HRP人员科室

        public HandsonTable GetHrpDeptHands(int HospitalId, int AllotId)
        {
            var result = new HandsonTable((int)SheetType.Unidentifiable, HrpDept.Select(t => t.Value).ToArray(), HrpDept.Select(t => new collect_permission
            {
                HeadName = t.Value,
                Visible = 1
            }).ToList());

            var data = perforCofHrpDeptRepository.GetEntities(t => t.HospitalId == HospitalId && t.AllotId == AllotId);
            if (data == null)
                return result;

            List<HandsonRowData> rowDatas = new List<HandsonRowData>();
            int i = 1;
            foreach (var item in data)
            {
                var json = JsonHelper.Serialize(item);
                var firstDic = JsonHelper.Deserialize<Dictionary<string, string>>(json);

                var cells = (from conf in HrpDept join fst in firstDic on conf.Key.ToUpper() equals fst.Key.ToUpper() select new HandsonCellData(conf.Value, fst.Value)).ToList();

                rowDatas.Add(new HandsonRowData(i, cells));
                i++;
            }
            result.SetRowData(rowDatas, rowDatas != null);
            return result;
        }

        public void SaveDepttypeHands(int hospitalId, int allotId, SaveCollectData request)
        {
            var dicData = CreateDataRow(hospitalId, allotId, request, HrpDept);

            List<cof_hrp_department> depts = new List<cof_hrp_department>();
            foreach (var item in dicData)
            {
                var json = JsonHelper.Serialize(item);
                var data = JsonHelper.Deserialize<cof_hrp_department>(json);
                if (!string.IsNullOrEmpty(data.HRPDepartment) && !string.IsNullOrEmpty(data.AccountingUnit))
                {
                    data.HospitalId = hospitalId;
                    data.AllotId = allotId;
                    depts.Add(data);
                }
            }

            perforCofHrpDeptRepository.Execute("delete from cof_hrp_department where HospitalId=@hospitalId and allotid = @allotid"
                , new { hospitalId, allotId });
            perforCofHrpDeptRepository.AddRange(depts.ToArray());
        }

        public static Dictionary<string, string> HrpDept { get; } = new Dictionary<string, string>
        {
            {nameof(cof_hrp_department.HRPDepartment), "hrp人员科室"},
            {nameof(cof_hrp_department.AccountingUnit), "核算单元"},
        };

        #endregion

        #region 二次分配别名配置

        public HandsonTable GetSecondaryAlias()
        {
            var result = new HandsonTable((int)SheetType.Unidentifiable, Alias.Select(t => t.Value).ToArray(), Alias.Select(t => new collect_permission
            {
                HeadName = t.Value,
                Visible = 1
            }).ToList());

            if (result.Columns != null && result.Columns.Any())
            {
                foreach (var column in result.Columns)
                {
                    if (column.Data == "状态")
                    {
                        column.Type = "autocomplete";
                        column.Source = new[] { "可用", "禁用" };
                        column.Strict = true;
                    }
                }
            }
            var data = perforCofaliasRepository.GetEntities()?.OrderBy(t => t.Route);
            if (data == null) return result;

            List<HandsonRowData> rowDatas = new List<HandsonRowData>();
            int i = 0;
            foreach (var item in data)
            {
                var json = JsonHelper.Serialize(item);
                var firstDic = JsonHelper.Deserialize<Dictionary<string, string>>(json);
                firstDic["states"] = firstDic["states"] == "1" ? "可用" : "禁用";
                var cells = (from conf in Alias join fst in firstDic on conf.Key.ToUpper() equals fst.Key.ToUpper() select new HandsonCellData(conf.Value, fst.Value)).ToList();

                rowDatas.Add(new HandsonRowData(i, cells));
                i++;
            }
            result.SetRowData(rowDatas, rowDatas != null);
            return result;
        }

        public void SaveSecondaryAlias(SaveCollectData request)
        {
            var dicData = CreateDataRow(0, 0, request, Alias);

            List<cof_alias> aliases = new List<cof_alias>();
            foreach (var item in dicData)
            {
                var states = new[] { "可用", "禁用" };
                if (item["States"] != null && states.Contains(item["States"]))
                {
                    item["States"] = item["States"] == "可用" ? "1" : "0";
                }
                else continue;

                var json = JsonHelper.Serialize(item);
                var data = JsonHelper.Deserialize<cof_alias>(json);
                if (!string.IsNullOrEmpty(data.Name) && !string.IsNullOrEmpty(data.OriginalName) && !string.IsNullOrEmpty(data.Route) && !string.IsNullOrEmpty(data.Alias))
                {
                    aliases.Add(data);
                }
            }

            perforCofaliasRepository.Execute("delete from cof_alias", null);
            perforCofaliasRepository.AddRange(aliases.ToArray());
        }

        public static Dictionary<string, string> Alias { get; } = new Dictionary<string, string>
        {
            {nameof(cof_alias.Route), "前端路由地址"},
            {nameof(cof_alias.Name), "描述名称"},
            {nameof(cof_alias.OriginalName), "原始名"},
            {nameof(cof_alias.Alias), "别名"},
            {nameof(cof_alias.States), "状态"},
        };
        #endregion

        private List<Dictionary<string, string>> CreateDataRow(int hospitalId, int allotId, SaveCollectData request, Dictionary<string, string> config)
        {
            List<Dictionary<string, string>> allData = new List<Dictionary<string, string>>();

            for (int r = 0; r < request.Data.Length; r++)
            {
                // 创建固定数据列
                Dictionary<string, string> baseData = CreateBaseData(request, config, r);
                baseData.Add(nameof(cof_hrp_department.AllotId), allotId.ToString());
                baseData.Add(nameof(cof_hrp_department.HospitalId), hospitalId.ToString());
                allData.Add(baseData);

            }
            return allData;
        }

        private Dictionary<string, string> CreateBaseData(SaveCollectData request, Dictionary<string, string> config, int rownumber)
        {
            Dictionary<string, string> result = new Dictionary<string, string>();
            for (int c = 0; c < request.ColHeaders.Length; c++)
            {
                var header = request.ColHeaders[c];
                var first = config.FirstOrDefault(w => w.Value == header);
                if (!default(KeyValuePair<string, string>).Equals(first)
                    && !result.ContainsKey(header)
                    && request.Data[rownumber].Length > c)
                {
                    result.Add(first.Key, request.Data[rownumber][c]);
                }
            }

            return result;
        }


        ///// <summary>
        ///// CMI值
        ///// </summary>
        ///// <param name="prevAllotId"></param>
        ///// <param name="allotId"></param>
        //private void CopyCMIData(int prevAllotId, int allotId)
        //{
        //    if (prevAllotId == 0) return;
        //    var list = perforCofcmiRepository.GetEntities(t => new List<int> { prevAllotId, allotId }.Contains(t.AllotId));
        //    if (list == null || !list.Any(t => t.AllotId == prevAllotId)) return;

        //    if (list.Any(t => t.AllotId == allotId))
        //    {
        //        var prevData = list.Where(t => t.AllotId == prevAllotId);
        //        var existData = list.Where(t => t.AllotId == allotId);
        //        if (existData != null && existData.Any())
        //            list = prevData.Where(t => !existData.Select(w => w.UnitType + w.AccountingUnit).Contains(t.UnitType + t.AccountingUnit)).ToList();
        //    }
        //    if (list.Any())
        //    {
        //        var data = list.Select(t => new cof_cmi
        //        {
        //            AllotId = allotId,
        //            UnitType = t.UnitType,
        //            AccountingUnit = t.AccountingUnit,
        //            Value = t.Value,
        //        });
        //        perforCofcmiRepository.AddRange(data.ToArray());
        //    }
        //}
    }
}
