using AutoMapper;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;

namespace Performance.Services
{
    public class CostTransferService : IAutoInjection
    {
        private readonly IMapper _mapper;
        private readonly ILogger<CostTransferService> logger;
        private readonly Application application;
        private readonly PerforCosttransferRepository costtransferRepository;
        private readonly PerforCosttransferitemRepository costtransferitemRepository;
        private readonly PerforCofdrugtypeRepository cofdrugtypeRepository;
        private readonly PerforPersheetRepository persheetRepository;
        private readonly PerforCofaccountingRepository cofaccountingRepository;
        private readonly PerforPerdeptdicRepository perdeptdicRepository;
        private readonly PerforPerallotRepository perallotRepository;
        private readonly PerforImdataRepository imdataRepository;
        private readonly PerforCofdrugtypefactorRepository perforCofdrugtypefactor;
        private readonly PerforExmoduleRepository perforExmodule;

        public CostTransferService(
            IMapper mapper,
            ILogger<CostTransferService> logger,
            IOptions<Application> application,
            PerforCosttransferRepository costtransferRepository,
            PerforCosttransferitemRepository costtransferitemRepository,
            PerforCofdrugtypeRepository cofdrugtypeRepository,
            PerforPersheetRepository persheetRepository,
            PerforCofaccountingRepository cofaccountingRepository,
            PerforPerdeptdicRepository perdeptdicRepository,
            PerforPerallotRepository perallotRepository,
            PerforImdataRepository imdataRepository,
            PerforCofdrugtypefactorRepository perforCofdrugtypefactor,
            PerforExmoduleRepository perforExmodule
            )
        {
            _mapper = mapper;
            this.logger = logger;
            this.application = application.Value;
            this.costtransferRepository = costtransferRepository;
            this.costtransferitemRepository = costtransferitemRepository;
            this.cofdrugtypeRepository = cofdrugtypeRepository;
            this.persheetRepository = persheetRepository;
            this.cofaccountingRepository = cofaccountingRepository;
            this.perdeptdicRepository = perdeptdicRepository;
            this.perallotRepository = perallotRepository;
            this.imdataRepository = imdataRepository;
            this.perforCofdrugtypefactor = perforCofdrugtypefactor;
            this.perforExmodule = perforExmodule;
        }

        /// <summary>
        /// 审核页面
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="menuType">1:申请 2:审核</param>
        /// <param name="roleType"></param>
        /// <param name="Department"></param>
        /// <returns></returns>
        public List<CostTransferResponse> GetAuditList(int allotId, int menuType, int roleType, string Department)
        {
            var roleTypes = new[] { 1, 2, 5 }.Contains(roleType);
            var account = GetAccounting(allotId, roleType, Department);

            Expression<Func<cost_transfer, bool>> exp = t => t.AllotId == allotId;
            if (roleType == (int)Role.科主任)
                if (menuType == 1)
                    exp = exp.And(t => new List<string> { UnitType.医生组.ToString(), UnitType.医技组.ToString() }.Contains(t.ApplicantUnitType));
                else
                    exp = exp.And(t => new List<string> { UnitType.医生组.ToString(), UnitType.医技组.ToString() }.Contains(t.AdoptedUnitType));
            else if (roleType == (int)Role.护士长)
                if (menuType == 1)
                    exp = exp.And(t => t.ApplicantUnitType == UnitType.护理组.ToString());
                else
                    exp = exp.And(t => t.AdoptedUnitType == UnitType.护理组.ToString());
            /*
            else if (roleType == application.SpecialRole)
                exp = exp.And(t => t.AdoptedUnitType == UnitType.特殊核算组.ToString());
            else if (roleType == application.OfficeRole)
                exp = exp.And(t => t.AdoptedUnitType == UnitType.行政后勤.ToString()); */

            var costTransfers = costtransferRepository.GetEntities(exp);

            if (!roleTypes)
                if (menuType == 1)
                    costTransfers = costTransfers?.FindAll(t => t.ApplicantDepartment == Department);
                else
                    costTransfers = costTransfers?.FindAll(t => t.AdoptedDepartment == Department);

            if (costTransfers == null || !costTransfers.Any())
                return new List<CostTransferResponse>();

            var response = new List<CostTransferResponse>();
            var costsId = costTransfers?.Select(w => w.Id);
            //var transfer = costTransfers.FirstOrDefault();
            var costItem = costtransferitemRepository.GetEntities(t => costsId.Contains(t.TransferId));
            if (menuType != 1)
                costItem = costItem?.FindAll(t => t.Status != 4);
            //如果是绩效办显示已经被科室同意的数据

            //if (roleTypes)
            //    costItem = costItem?.FindAll(t => t.Status == 1);

            foreach (var item in costTransfers)
            {
                var result = new CostTransferResponse();
                result = _mapper.Map<CostTransferResponse>(item);
                result.Items = costItem?.Where(t => t.TransferId == item.Id)?.Select(t => new Option
                {
                    Id = t.Id,
                    TransferId = t.TransferId,
                    Source = t.Source,
                    Category = t.Category,
                    Amount = t.Amount,
                    Ratio = t.Ratio,
                    IsUseRatio = t.IsUseRatio,
                    CalculationAmount = t.CalculationAmount,
                    Status = t.Status,
                    AdminStatus = t.AdminStatus,
                    ApplicationRemark = t.ApplicationRemark,
                    DepartmentRemark = t.DepartmentRemark,
                    AdminRemark = t.AdminRemark,
                    options = new string[] { },
                    ApplicantDepartment = result.ApplicantDepartment,
                    AdoptedDepartment = result.AdoptedDepartment

                }).OrderBy(t => t.Status).ThenBy(t => t.AdminStatus).ToList();
                response.Add(result);
            }

            return response.OrderBy(t => t.Status).ThenBy(t => t.AdminStatus).ToList();
        }


        public cof_accounting GetAccounting(int allotId, int roleType, string Department = null)
        {
            var unitTpes = UnitTypeUtil.GetMaps(roleType);
            Expression<Func<cof_accounting, bool>> exp = t => t.AllotId == allotId && t.AccountingUnit == Department;

            if (UnitTypeUtil.Maps.ContainsKey(roleType))
                exp = exp.And(t => unitTpes.Contains(t.UnitType));

            var account = cofaccountingRepository.GetEntity(exp);

            return account;
        }

        /// <summary>
        /// 申请页面下拉选项
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="hospitalId"></param>
        /// <param name="roleType"></param>
        /// <param name="deparment"></param>
        /// <param name="detail"></param>
        /// <returns></returns>
        public CommonResponse Common(int allotId, int hospitalId, int roleType, string deparment, DepartmentDetail detail)
        {
            var common = new CommonResponse();

            common.account = cofaccountingRepository.GetEntities(t => t.AllotId == allotId)
                ?.Select(t => new TitleValue { Title = t.AccountingUnit, Value = t.AccountingUnit }).ToDistinct().ToList();

            var (prevAllotList, deptDetail) = DeptDetial(allotId, hospitalId, roleType, deparment);

            common.unitType = deptDetail.UnitType ?? "";
            if (string.IsNullOrEmpty(detail.UnitType)) return common;

            var drugFactor = perforCofdrugtypefactor.GetEntities(t => t.HospitalId == hospitalId && t.AllotID == allotId);
            if (drugFactor == null || !drugFactor.Any()) return common;

            var exModule = perforExmodule.GetEntities(t => drugFactor.Select(c => c.ExModuleId).Contains(t.Id) && t.SheetType == (int)SheetType.Income);

            common.Data = drugFactor.Select(t => new Common
            {
                Source = Regex.Replace(exModule.Find(w => w.Id == t.ExModuleId).ModuleName, @"\d.", ""),
                Category = t.Charge,
                Ratio = (detail.UnitType == "医生组" ? t.YSZ : detail.UnitType == "医技组" ? t.YJZ : t.HLZ) ?? 0
            }).ToList();

            #region 注释

            /*
            var sheets = persheetRepository.GetEntities(t => t.AllotID == allotId && t.SheetType == (int)SheetType.Income);
            if (sheets != null && sheets.Any())
            {
                var sheetId = sheets.Select(t => t.ID);

                int imDataAllotId = prevAllotList.FirstOrDefault(t => new int[] { 6, 8, 10 }.Contains(t.States))?.ID ?? 0;

                var unitValue = EnumHelper.GetItems<UnitType>().Find(t => t.Name == detail.UnitType)?.Value;
                var imData = imdataRepository.GetEntities(t => t.AllotID == imDataAllotId && sheetId.Contains(t.SheetID.Value) && t.UnitType == unitValue);

                if (imData == null || !imData.Any()) return common;

                var commons = new List<Common>();
                
                if (imData != null && imData.Any())
                {
                    var datas = from im in imData
                                group im by new { im.SheetID, im.TypeName, im.FactorValue } into i
                                select new { i.Key, i };
                    commons = datas.Select(t => new Common
                    {
                        Source = Regex.Replace(sheets.Find(w => w.ID == t.Key.SheetID).SheetName, @"\d.", ""),
                        Category = t.Key.TypeName,
                        Ratio = t.Key.FactorValue.Value
                    }).ToList();
                }
                common.Data = commons;
            } */

            #endregion
            return common;
        }

        public (List<per_allot>, DepartmentDetail) DeptDetial(int allotId, int hospitalId, int roleType, string deparment)
        {
            var detail = new DepartmentDetail();
            var prevAllotList = PrevAllotList(hospitalId, allotId);
            if (prevAllotList != null && prevAllotList.Any())
            {
                foreach (var prevAllot in prevAllotList)
                {
                    string unittype = GetAccounting(prevAllot.ID, roleType, deparment)?.UnitType;
                    if (!string.IsNullOrEmpty(unittype))
                    {
                        detail.UnitType = unittype;
                        break;
                    }
                }
            }
            return (prevAllotList, detail);
        }

        /// <summary>
        /// 申请划拨
        /// </summary>
        public bool Applicat(CostTransferRequest request)
        {
            if (request.AllotId == 0)
                throw new PerformanceException("参数错误，绩效记录不存在");

            if (request.Applicant == null || request.Adopted == null)
                throw new PerformanceException("参数错误，申请/被划拨科室信息缺失");

            if (string.IsNullOrEmpty(request.Applicant.UnitType) || string.IsNullOrEmpty(request.Applicant.Department))
                throw new PerformanceException("当前科室未配置科室类别，无法提交申请");

            if (string.IsNullOrEmpty(request.Adopted.UnitType) || string.IsNullOrEmpty(request.Adopted.Department))
                throw new PerformanceException("参数错误，被划拨科室信息缺失");

            if (request.Items == null || !request.Items.Any())
                throw new PerformanceException("参数错误，申请条目为空");

            if (request.Adopted.Department == request.Applicant.Department && request.Adopted.UnitType == request.Applicant.UnitType)
                throw new PerformanceException("参数错误，提交科室相同");

            if (request.Items.Any(t => string.IsNullOrEmpty(t.Category))
                || request.Items.Any(t => t.IsUseRatio == 1 && string.IsNullOrEmpty(t.Source))) throw new PerformanceException("参数错误，申请信息填写不完整");

            var allot = perallotRepository.GetEntity(t => t.ID == request.AllotId);
            var allotStatus = new[] { (int)AllotStates.绩效下发, (int)AllotStates.归档 };

            if (allotStatus.Contains(allot.States))
                throw new PerformanceException("绩效已下发或归档");

            var transfer = new cost_transfer
            {
                AllotId = request.AllotId,
                ApplicantDepartment = request.Applicant.Department,
                ApplicantUnitType = request.Applicant.UnitType,
                AdoptedDepartment = request.Adopted.Department,
                AdoptedUnitType = request.Adopted.UnitType,
                Status = 0,
                AdminStatus = 0
            };

            var result = costtransferRepository.Add(transfer);
            if (!result)
                throw new PerformanceException("提交申请失败，请重试");

            var items = request.Items?.Select(t => new cost_transfer_item
            {
                TransferId = transfer.Id,
                Source = t.Source ?? "",
                Category = t.Category,
                Amount = t.Amount,
                Ratio = t.Ratio,
                CalculationAmount = t.CalculationAmount,
                IsUseRatio = t.IsUseRatio,
                ApplicationRemark = t.ApplicationRemark,
                Status = 0,
                AdminStatus = 0
            }).ToArray();

            result = costtransferitemRepository.AddRange(items);
            if (!result)
                costtransferRepository.Remove(transfer);

            return result;
        }
        /// <summary>
        /// 撤回提交
        /// </summary>
        /// <param name="itemId"></param>
        public void WithdrawSubmit(int itemId)
        {
            var item = costtransferitemRepository.GetEntity(t => t.Id == itemId);
            if (item == null) throw new PerformanceException("申请记录不存在");

            item.Status = 4;
            item.AdminStatus = 4;
            costtransferitemRepository.Update(item);
        }

        /// <summary>
        /// 申请划拨信息修改
        /// </summary>
        public void UpdateApplicat(CostTransferUpdateRequest request)
        {
            var transfer = costtransferRepository.GetEntity(t => t.Id == request.TransferId);
            if (transfer == null)
                throw new PerformanceException("划拨申请记录不存在");
            /*
            transfer.AllotId = request.AllotId;
            transfer.ApplicantDepartment = request.Applicant.Department;
            transfer.ApplicantUnitType = request.Applicant.UnitType;
            transfer.AdoptedDepartment = request.Adopted.Department;
            transfer.AdoptedUnitType = request.Adopted.UnitType;

            var result = costtransferRepository.Update(transfer);
            if (!result)
                throw new PerformanceException("修改划拨申请记录失败");*/

            var items = costtransferitemRepository.GetEntities(t => t.TransferId == request.TransferId);
            if (items == null)
            {
                if (request.Items != null && request.Items.Any())
                {
                    request.Items.ForEach(t =>
                    {
                        t.Id = 0;
                        t.TransferId = request.TransferId;
                        t.Status = 0;
                    });
                    costtransferitemRepository.AddRange(request.Items.ToArray());
                }
            }
            else
            {
                if (request.Items == null || !request.Items.Any())
                    costtransferitemRepository.RemoveRange(items.ToArray());
                else
                {
                    if (request.Items.Any(t => t.Id > 0))
                    {
                        var hasPrimaryValueItmes = request.Items.Where(t => t.Id > 0).ToList();
                        /*
                        // 删除
                        var notExistItems = items.Where(item => !hasPrimaryValueItmes.Select(t => t.Id).Contains(item.Id));
                        if (notExistItems != null && notExistItems.Any())
                            costtransferitemRepository.RemoveRange(notExistItems.ToArray());*/

                        // 更新
                        var updateItems = items.Where(item => hasPrimaryValueItmes.Select(t => t.Id).Contains(item.Id));
                        foreach (var update in updateItems)
                        {
                            var item = hasPrimaryValueItmes.FirstOrDefault(t => t.Id == update.Id);

                            update.Source = item.Source;
                            update.Category = item.Category;
                            update.Amount = item.Amount;
                            update.Ratio = item.Ratio;
                            update.CalculationAmount = item.CalculationAmount;
                            update.IsUseRatio = item.IsUseRatio;
                            update.ApplicationRemark = item.ApplicationRemark;
                            update.Status = 0;
                            update.AdminStatus = 0;
                            hasPrimaryValueItmes.Remove(item);
                        }
                        costtransferitemRepository.UpdateRange(updateItems.ToArray());
                        /*
                        // 添加
                        if (hasPrimaryValueItmes != null && hasPrimaryValueItmes.Any())
                        {
                            hasPrimaryValueItmes.ForEach(t =>
                            {
                                t.Id = 0;
                                t.TransferId = request.TransferId;
                                t.Status = 0;
                            });
                            costtransferitemRepository.AddRange(hasPrimaryValueItmes.ToArray());
                        } */
                    }
                    /*
                    if (request.Items.Any(t => t.Id == 0))  // 添加
                    {
                        costtransferitemRepository.AddRange(request.Items.Where(t => t.Id == 0).ToArray());
                    } */
                }
            }

            UpdateCostTransferStatus(request.TransferId);
        }

        /// <summary>
        /// 删除划拨申请记录
        /// </summary>
        public void DeleteApplicat(int transferId)
        {
            var transfer = costtransferRepository.GetEntity(t => t.Id == transferId);
            if (transfer == null)
                throw new PerformanceException("划拨申请记录不存在");

            var result = costtransferRepository.Update(transfer);
            if (!result)
                throw new PerformanceException("删除划拨申请记录失败");

            var items = costtransferitemRepository.GetEntities(t => t.TransferId == transferId);
            if (items != null && items.Any())
            {
                costtransferitemRepository.RemoveRange(items.ToArray());
            }
        }

        /// <summary>
        /// 划拨审核
        /// </summary>
        public bool CostTransferAudit(AuditRequest request, bool isAdmin)
        {
            if (request.TransferItemId.Length <= 0)
                throw new PerformanceException("科室未审核或已驳回，不能一键通过");

            var costItems = costtransferitemRepository.GetEntities(t => request.TransferItemId.Contains(t.Id));
            var transferId = costItems?.Select(t => t.TransferId).Distinct();
            var transfers = costtransferRepository.GetEntities(t => transferId.Contains(t.Id));
            if (transfers.Any(t => t.AllotId != request.AllotId)) return false;

            if (isAdmin)
            {
                costItems.ForEach(t =>
                {
                    t.AdminStatus = request.Status;
                    t.AdminRemark = request.Remake;
                });
            }
            else
            {
                costItems.ForEach(t =>
                {
                    if (request.Status == 2 && t.AdminStatus != 0)
                        t.AdminStatus = 2;
                    t.Status = request.Status;
                    t.DepartmentRemark = request.Remake;
                });
            }

            //if (costItems == null || !costItems.Any()) return;
            var result = costtransferitemRepository.UpdateRange(costItems.ToArray());
            if (result)
                foreach (var item in transferId)
                {
                    UpdateCostTransferStatus(item);
                }

            return result;
        }

        /// <summary>
        /// 下发驳回
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="transferId"></param>
        /// <param name="issue"></param>
        /// <returns></returns>
        public bool RejectedApplicat(int allotId)
        {
            var costTransfers = costtransferRepository.GetEntities(t => t.AllotId == allotId && new[] { 0, 2 }.Contains(t.AdminStatus));
            if (costTransfers == null || !costTransfers.Any()) return true;

            var costId = costTransfers?.Select(t => t.Id);
            var costItems = costtransferitemRepository.GetEntities(t => costId.Contains(t.TransferId) && t.AdminStatus == 0);

            costItems.ForEach(t =>
            {
                t.Status = 3;
                t.AdminStatus = 3;
            });

            costTransfers.ForEach(t =>
            {
                t.Status = 4;
                t.AdminStatus = 4;
            });

            costtransferitemRepository.UpdateRange(costItems.ToArray());
            costtransferRepository.UpdateRange(costTransfers.ToArray());
            return true;
        }

        /// <summary>
        /// 带入下个月数据
        /// </summary>
        /// <param name="hospitalId"></param>
        /// <param name="allotId"></param>
        public void IntoLastTiemData(int hospitalId, int allotId)
        {
            var allotList = perallotRepository.GetEntities(w => w.HospitalId == hospitalId)?.OrderBy(s => s.Year).ThenBy(s => s.Month).ToList();
            if (allotList == null || !allotList.Any()) return;

            var allot = allotList.FirstOrDefault(w => w.ID == allotId);
            if (allot == null) return;

            var index = allotList.IndexOf(allot);
            if (index == 0) return;

            var prevAllot = allotList[index - 1];
            if (prevAllot == null) return;

            var transfers = costtransferRepository.GetEntities(t => t.AllotId == prevAllot.ID);
            if (transfers == null || !transfers.Any()) return;

            var transferLastId = transfers.Select(t => t.Id);
            var costItems = costtransferitemRepository.GetEntities(t => transferLastId.Contains(t.TransferId) && (t.Status == 3 || t.AdminStatus == 3));
            if (costItems == null || !costItems.Any()) return;

            var costItemLastId = costItems.Select(t => t.TransferId).Distinct();
            var transferLast = transfers.Where(t => costItemLastId.Contains(t.Id));

            foreach (var item in transferLast)
            {
                var newTransfers = new cost_transfer();
                newTransfers = _mapper.Map<cost_transfer>(item);
                newTransfers.AllotId = allotId;
                newTransfers.Status = 0;
                newTransfers.AdminStatus = 0;
                costtransferRepository.Add(newTransfers);

                var newCostItem = costItems.Where(t => t.TransferId == item.Id).Select(t => new cost_transfer_item
                {
                    TransferId = newTransfers.Id,
                    Source = t.Source,
                    Category = t.Category,
                    Amount = t.Amount,
                    Ratio = t.Ratio,
                    CalculationAmount = t.CalculationAmount,
                    IsUseRatio = t.IsUseRatio,
                    ApplicationRemark = t.ApplicationRemark,
                    Status = 0,
                    AdminStatus = 0,
                    IsWrited = 0
                }).ToArray();
                costtransferitemRepository.AddRange(newCostItem);
            }


        }

        private List<per_allot> PrevAllotList(int hospitalId, int allotId)
        {
            var allotList = perallotRepository.GetEntities(w => w.HospitalId == hospitalId)?.OrderByDescending(s => s.Year).ThenByDescending(s => s.Month).ToList();
            if (allotList == null || !allotList.Any()) return new List<per_allot>();

            var allot = allotList.FirstOrDefault(w => w.ID == allotId);
            if (allot == null) return new List<per_allot>();

            return allotList.Where(t => t.Year <= allot.Year && t.Month <= allot.Month)?.ToList();
        }

        /// <summary>
        /// 修改申请记录的状态
        /// </summary>
        /// <param name="transferId"></param>
        public void UpdateCostTransferStatus(int transferId)
        {
            try
            {
                var transfer = costtransferRepository.GetEntity(t => t.Id == transferId);
                if (transfer == null) return;

                var items = costtransferitemRepository.GetEntities(t => t.TransferId == transferId);
                switch (items)
                {
                    case var data when data == null || !data.Any():
                        transfer.Status = 3;
                        transfer.AdminStatus = 0;
                        break;
                    //科室部分通过，绩效办部分通过
                    case var data when data.Any(t => t.Status == 1) && data.Any(t => t.Status != 1) && data.Any(t => t.AdminStatus == 1) && data.Any(t => t.AdminStatus != 1):
                        transfer.Status = 2;
                        transfer.AdminStatus = 2;
                        break;
                    //科室部分通过，绩效办全部驳回
                    case var data when data.Any(t => t.Status == 1) && data.Any(t => t.Status != 1) && data.Any(t => t.AdminStatus == 2):
                        transfer.Status = 2;
                        transfer.AdminStatus = 3;
                        break;
                    //科室部分通过，绩效办待审核
                    case var data when data.Any(t => t.Status == 1) && data.Any(t => t.Status != 1) && data.Any(t => t.AdminStatus == 0):
                        transfer.Status = 2;
                        transfer.AdminStatus = 0;
                        break;
                    //科室全部通过，绩效办待审核
                    case var data when data.Any(t => t.Status == 1) && data.Any(t => t.AdminStatus == 0):
                        transfer.Status = 1;
                        transfer.AdminStatus = 0;
                        break;
                    //科室全部通过，绩效办部分通过
                    case var data when data.Any(t => t.Status == 1) && data.Any(t => t.AdminStatus == 1) && data.Any(t => t.AdminStatus != 1):
                        transfer.Status = 1;
                        transfer.AdminStatus = 2;
                        break;
                    //科室全部通过，绩效办全部通过
                    case var data when data.Any(t => t.Status == 1) && data.Any(t => t.AdminStatus == 1):
                        transfer.Status = 1;
                        transfer.AdminStatus = 1;
                        break;
                    //科室全部通过，绩效办全部驳回
                    case var data when data.Any(t => t.Status == 1) && data.Any(t => t.AdminStatus == 2):
                        transfer.Status = 1;
                        transfer.AdminStatus = 3;
                        break;
                    //科室全部驳回，绩效办待审核
                    case var data when data.Any(t => t.Status == 2) && data.Any(t => t.AdminStatus == 0):
                        transfer.Status = 3;
                        transfer.AdminStatus = 0;
                        break;
                    //科室全部驳回，绩效办全部驳回
                    case var data when data.Any(t => t.Status == 2) && data.Any(t => t.AdminStatus == 2):
                        transfer.Status = 3;
                        transfer.AdminStatus = 3;
                        break;
                    //科室待审核，绩效办待审核
                    case var data when data.Any(t => t.Status == 0) && data.Any(t => t.AdminStatus == 0):
                        transfer.Status = 0;
                        transfer.AdminStatus = 0;
                        break;

                    default:
                        break;
                }
                costtransferRepository.Update(transfer);
            }
            catch (Exception ex)
            {
                logger.LogError($"修改申请记录的状态异常：{ex}");
            }
        }


        #region 划拨报表

        public TransferReportResponse TransferContent(int allotId, int auditType, DepartmentDetail detail)
        {
            var transfers = costtransferRepository.GetEntities(t => t.AllotId == allotId && t.Status != 3 && t.AdminStatus != 3);
            if (transfers == null || !transfers.Any()) return new TransferReportResponse();

            switch (auditType)
            {
                case 1:
                    transfers = transfers.Where(t => t.ApplicantDepartment == detail.Department && t.ApplicantUnitType == detail?.UnitType).ToList();
                    break;
                case 2:
                    transfers = transfers.Where(t => t.AdoptedDepartment == detail.Department && t.AdoptedUnitType == detail?.UnitType).ToList();
                    break;
                default:
                    break;
            }

            var transferItems = costtransferitemRepository.GetEntities(t => transfers.Select(w => w.Id).Contains(t.TransferId));
            if (transferItems == null || !transferItems.Any()) return new TransferReportResponse();

            var allItems = transferItems.Where(t => t.Status == 1 && t.AdminStatus == 1);

            var finalTransfer = transfers.Where(t => allItems.Select(w => w.TransferId).Distinct().Contains(t.Id));

            var result = new TransferReportResponse();

            result.Transfers = finalTransfer.Select(t => new Transfer
            {
                ApplicantDepartment = t.ApplicantDepartment,
                ApplicantUnitType = t.ApplicantUnitType,
                AmountSum = transferItems.Where(w => w.TransferId == t.Id)?.Sum(w => w.CalculationAmount.Value),
                AdoptedDepartment = t.AdoptedDepartment,
                AdoptedUnitType = t.AdoptedUnitType,
                PassAmountSum = allItems.Where(w => w.TransferId == t.Id)?.Sum(w => w.CalculationAmount.Value),

            }).ToList();

            result.Items = allItems.Select(c => new TransferItem
            {
                ApplicantDepartment = transfers.FirstOrDefault(t => t.Id == c.TransferId)?.ApplicantDepartment,
                ApplicantUnitType = transfers.FirstOrDefault(t => t.Id == c.TransferId)?.ApplicantUnitType,
                AdoptedDepartment = transfers.FirstOrDefault(t => t.Id == c.TransferId)?.AdoptedDepartment,
                AdoptedUnitType = transfers.FirstOrDefault(t => t.Id == c.TransferId)?.AdoptedUnitType,
                IsUseRatio = c.IsUseRatio,
                Source = c.Source,
                Category = c.Category,
                Ratio = c.Ratio,
                CalculationAmount = c.CalculationAmount
            }).OrderBy(c => c.TransferId).ToList();


            return result;
        }


        #endregion

    }
}
