using AutoMapper;
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;

namespace Performance.Services
{
    public class ConfigService : IAutoInjection
    {
        #region
        private PerforCofdirectorRepository _directorRepository;
        private PerforCofdrugpropRepository _drugpropRepository;
        private PerforCofincomeRepository _incomeRepository;
        private PerforCofworkyearRepository _workyearRepository;
        private PerforCofworkitemRepository _workitemRepository;
        private PerforCofagainRepository _againRepository;
        private PerforCofdrugtypeRepository _drugtypeRepository;
        private PerforPerallotRepository perforPerAllotRepository;
        private PerforPeragainallotRepository perforPeragainallotRepository;
        private PerforHospitalRepository perforHospitalRepository;
        private PerforPersheetRepository perforPersheetRepository;
        private PerforImheaderRepository perforImheaderRepository;
        //private PerforLogdbugRepository logdbug;
        private readonly LogManageService logManageService;
        public ConfigService(PerforCofdirectorRepository cofdirectorRepository,
            PerforCofdrugpropRepository cofdrugpropRepository,
            PerforCofincomeRepository cofincomeRepository,
            PerforCofworkyearRepository cofworkyearRepository,
            PerforCofagainRepository againRepository,
            PerforCofdrugtypeRepository drugtypeRepository,
            PerforPerallotRepository perforPerAllotRepository,
            PerforPeragainallotRepository perforPeragainallotRepository,
            PerforHospitalRepository perforHospitalRepository,
            PerforCofworkitemRepository workitemRepository,
            PerforPersheetRepository perforPersheetRepository,
            PerforImheaderRepository perforImheaderRepository,
            //PerforLogdbugRepository logdbug
            LogManageService logManageService)
        {
            this._directorRepository = cofdirectorRepository;
            this._drugpropRepository = cofdrugpropRepository;
            this._incomeRepository = cofincomeRepository;
            this._workyearRepository = cofworkyearRepository;
            this._workitemRepository = workitemRepository;
            this._againRepository = againRepository;
            this._drugtypeRepository = drugtypeRepository;
            this.perforPerAllotRepository = perforPerAllotRepository;
            this.perforPeragainallotRepository = perforPeragainallotRepository;
            this.perforHospitalRepository = perforHospitalRepository;
            this.perforPersheetRepository = perforPersheetRepository;
            this.perforImheaderRepository = perforImheaderRepository;
            //this.logdbug = logdbug;
            this.logManageService = logManageService;
        }
        #endregion

        #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_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 allotId)
        {
            var list = _drugtypeRepository.GetEntities(t => t.AllotID == allotId);
            return list;
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public cof_drugtype DrugtypeInsert(DrugpropRequest request)
        {
            var entity = new cof_drugtype
            {
                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_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

        #region cof_workitem  工作量绩效
        /// <summary>
        /// 获取cof_workitem列表
        /// </summary>
        /// <returns></returns>
        public List<cof_workitem> GetWorkItems(int allotId)
        {
            var list = _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;

            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 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);
            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 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 } };
                _drugpropRepository.AddRange(newDurgprops.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());
            }

            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 { AllotID = allot.ID, Charge = t.Charge, ChargeType = t.ChargeType });
                _drugtypeRepository.AddRange(newAgains.ToArray());
            }

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

            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());
            }
        }
        #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 清楚无效数据 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="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;
        }
    }
}
