using AutoMapper;
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
{
    /// <summary>
    /// 提供sheet数据查询服务
    /// </summary>
    public class SheetSevice : IAutoInjection
    {
        private PerforPerallotRepository _perforAllotRepository;
        private PerforPersheetRepository _perforImSheetRepository;
        private PerforImdataRepository _perforImDataRepository;
        private PerforImheaderRepository _perforImHeaderRepository;
        private PerforImemployeeRepository _perforImEmployeeRepository;
        private PerforImaccountbasicRepository _perforImaccountbasicRepository;
        private PerforResaccountRepository _perforResaccountRepository;
        //private PerforResaccountnurseRepository _perforImaccountnurseRepository;
        private PerforImspecialunitRepository _perforImspecialunitRepository;
        private PerforImemployeeclinicRepository _perforImemployeeclinicRepository;
        private readonly PerforImemployeelogisticsRepository _perforImemployeelogisticsRepository;
        private readonly string[] percentparam = new string[] { "预算比例", "考核得分率", "调节系数" };

        public SheetSevice(PerforPerallotRepository perforAllotRepository,
            PerforPersheetRepository perforImSheetRepository,
            PerforImdataRepository perforImDataRepository,
            PerforImheaderRepository perforImHeaderRepository,
            PerforImemployeeRepository perforImEmployeeRepository,
            PerforImaccountbasicRepository perforImaccountbasicRepository,
            PerforResaccountRepository perforResaccountRepository,
            //PerforResaccountnurseRepository perforImaccountnurseRepository,
            PerforImspecialunitRepository perforImspecialunitRepository,
            PerforImemployeeclinicRepository perforImemployeeclinicRepository,
            PerforImemployeelogisticsRepository perforImemployeelogisticsRepository)
        {
            _perforAllotRepository = perforAllotRepository;
            _perforImSheetRepository = perforImSheetRepository;
            _perforImDataRepository = perforImDataRepository;
            _perforImHeaderRepository = perforImHeaderRepository;
            _perforImEmployeeRepository = perforImEmployeeRepository;
            _perforResaccountRepository = perforResaccountRepository;
            //_perforImaccountnurseRepository = perforImaccountnurseRepository;
            _perforImaccountbasicRepository = perforImaccountbasicRepository;
            _perforImspecialunitRepository = perforImspecialunitRepository;
            _perforImemployeeclinicRepository = perforImemployeeclinicRepository;
            this._perforImemployeelogisticsRepository = perforImemployeelogisticsRepository;
        }

        /// <summary>
        /// sheet 列表查询
        /// </summary>
        /// <param name="allotID"></param>
        /// <returns></returns>
        public List<SheetResponse> SheetList(int allotID, int source)
        {
            var allot = _perforAllotRepository.GetEntity(t => t.ID == allotID);
            if (allot == null)
                throw new PerformanceException("参数allotid无效");
            int[] arr = new int[] { 1, 2 };
            if (!arr.Contains(source))
                throw new PerformanceException("参数source无效");

            var sheetList = _perforImSheetRepository.GetEntities(t => t.AllotID == allotID && t.Source == source);
            return Mapper.Map<List<SheetResponse>>(sheetList);
        }

        /// <summary>
        /// sheet数据查询
        /// </summary>
        /// <param name="sheetID"></param>
        /// <returns></returns>
        public SheetExportResponse SheetExport(int sheetID)
        {
            var sheet = _perforImSheetRepository.GetEntity(t => t.ID == sheetID);
            if (sheet == null)
                throw new PerformanceException("参数sheetid无效");

            SheetExportResponse response = new SheetExportResponse(sheet.ID, sheet.SheetName, sheet.SheetType.Value);
            if (sheet.SheetType == (int)SheetType.Employee)
            {
                EmployeeExport(sheetID, response);
            }
            else if (sheet.SheetType == (int)SheetType.ClinicEmployee)
            {
                ClinicEmployeeExport(sheetID, response);
            }
            else if (sheet.SheetType == (int)SheetType.LogisticsEmployee)
            {
                LogisticsEmployeeExport(sheetID, response);
            }
            else if (sheet.SheetType == (int)SheetType.SpecialUnit)
            {
                SpecialUnitExport(sheetID, response);
            }
            //else if (sheet.SheetType == (int)SheetType.AccountBasic)
            //{
            //    AccountBaiscExport(sheetID, response);
            //}
            else if (sheet.SheetType == (int)SheetType.ComputeDoctorAccount)
            {
                AccountDoctorExport(sheetID, response);
            }
            else if (sheet.SheetType == (int)SheetType.ComputeNurseAccount)
            {
                AccountNurseExport(sheetID, response);
            }
            else
            {
                CommonExport(sheetID, response,sheet.SheetType);
                //response.Header = response.Header.Select(t => t.Data.ToDistinct(c => c.CellValue)).ToList();
                if (new int[] { (int)SheetType.Income, (int)SheetType.OtherIncome, (int)SheetType.Expend, (int)SheetType.Workload }.Contains(sheet.SheetType.Value))
                {
                    var point = 0;
                    if (new int[] { (int)SheetType.Income, (int)SheetType.OtherIncome, (int)SheetType.Expend }.Contains(sheet.SheetType.Value))
                        point = -3;
                    else
                        point = -1;

                    response.Header.ForEach(t => t.Data.ForEach(data =>
                    {
                        if (data.PointCell != 0)
                            data.PointCell += point;
                    }));
                    response.Row.ForEach(t => t.Data.ForEach(data =>
                    {
                        if (data.PointCell != 0)
                            data.PointCell += point;
                    }));
                }
            }

            if (response.Row != null && response.Row.Any())
                response.Row = response.Row.OrderBy(t => t.Rownumber).ToList();

            return response;
        }

        private void CommonExport(int sheetID, SheetExportResponse response,int? sheetType)
        {
            var headList = _perforImHeaderRepository.GetEntities(t => t.SheetID == sheetID)?.OrderBy(t => t.PointCell);
            if (headList == null) return;

            if (sheetType == (int)SheetType.AccountBasic)
                headList = headList.ToDistinct(t => t.CellValue).OrderBy(t => t.PointCell);
            

            var dataList = _perforImDataRepository.GetEntities(t => t.SheetID == sheetID)?.OrderByDescending(t => t.AccountingUnit).ToList();
                   
            var sheet = _perforImSheetRepository.GetEntity(t => t.ID == sheetID);

            //添加系数值
            #region 添加系数值
            int merge = 4;
            if (sheet.SheetType == (int)SheetType.Income && !headList.Select(t => t.CellValue).Contains("核算单元（医技组）"))
                merge = 3;

            var factorhead = new Row(0);
            if (sheet.SheetType == (int)SheetType.Workload)
            {
                factorhead.Data.Add(new Cell(0, "单元工作量绩效标准：", 1, 2, false, false, cellType: "header"));
                response = AddFactor(response, factorhead, headList.ToList(), dataList);
            }
            else if (sheet.SheetType == (int)SheetType.OtherIncome || sheet.SheetType == (int)SheetType.Income || sheet.SheetType == (int)SheetType.Expend)
            {
                factorhead.Data.Add(new Cell(0, "护理组分割比例", 1, merge, false, false, cellType: "header"));
                response = AddFactor(response, factorhead, headList.ToList(), dataList, UnitType.护理组);
                var factorhead1 = new Row(1);
                factorhead1.Data.Add(new Cell(0, "医生组分割比例", 1, merge, false, false, cellType: "header"));
                response = AddFactor(response, factorhead1, headList.ToList(), dataList, UnitType.医生组);
                var factorhead2 = new Row(2);
                factorhead2.Data.Add(new Cell(0, "医技组分割比例", 1, merge, false, false, cellType: "header"));
                response = AddFactor(response, factorhead2, headList.ToList(), dataList, UnitType.医技组);
            }

            if (sheet.SheetType == (int)SheetType.Income && !headList.Select(t => t.CellValue).Contains("核算单元（医技组）"))
            {
                //var technicianvalue = new Row(response.Header.Count()); technicianvalue.Data.Add(new Cell(0, "医技组核算收入", 1, 4, false, false));
                //response.Header.Add(technicianvalue);
                var technicianhead = new Row(response.Header.Count());
                technicianhead.Data.Add(new Cell(0, "医技组核算单元", 1, merge, false, false));
                response.Header.Add(technicianhead);
                foreach (var header in headList)
                {
                    if (new List<string> { "核算单元（医技组）", "核算单元（医生组）", "核算单元（护理组）", "科室名称" }.Contains(header.CellValue)) continue;
                    var technician = dataList.FirstOrDefault(t => t.UnitType == 3 && t.TypeName == header.CellValue);
                    //technicianvalue.Data.Add(new Cell(header.PointCell.Value, technician.CellValue, header.MergeRow.Value, header.MergeCell.Value, header.IsTotal == 1, false));
                    technicianhead.Data.Add(new Cell(header.PointCell.Value, technician?.AccountingUnit ?? null, 1, 1, header.IsTotal == 1, false));
                }
            }

            #endregion

            //创建列头行
            #region 创建列头行
            var rowhead = new Row(response.Header.Count());
            response.Header.Add(rowhead);
            foreach (var header in headList.Where(t => !t.ParentID.HasValue || t.ParentID.Value == 0))
            {
                rowhead.Data.Add(new Cell(header.PointCell.Value, header.CellValue, header.MergeRow.Value, header.MergeCell.Value, header.IsTotal == 1, false, id: header.ID, fieldName: header.CellValue, cellType: "header"));
            }
            if (headList.Any(t => t.ParentID.HasValue && t.ParentID.Value > 0))
            {
                var rowhead2 = new Row(response.Header.Count());
                response.Header.Add(rowhead2);
                foreach (var header in headList.Where(t => t.ParentID.HasValue && t.ParentID.Value > 0))
                {
                    rowhead2.Data.Add(new Cell(header.PointCell.Value, header.CellValue, header.MergeRow.Value, header.MergeCell.Value, header.IsTotal == 1, false, id: header.ID, fieldName: header.CellValue, cellType: "header"));
                }
            }
            List<im_header> headers = new List<im_header>();
            foreach (var head in headList)
            {
                if (!headList.Any(t => t.ParentID == head.ID))
                    headers.Add(head);
            }
            #endregion

            //创建数据行
            #region 创建数据行
            if (dataList == null || dataList.Count == 0) return;
            Row rowbody = null;
            foreach (var rowNumber in dataList.Select(t => t.RowNumber).Distinct())     //.OrderBy(t => t)
            {
                foreach (var head in headers)
                {
                    if (rowbody == null || rowbody.Rownumber != rowNumber)
                    {
                        rowbody = new Row(rowNumber ?? 0);
                        response.Row.Add(rowbody);
                    }
                    if (head.CellValue.Contains("核算单元类型"))
                    {
                        var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber).UnitType;
                        var unitType = value.HasValue ? ((UnitType)value).ToString() : "";
                        rowbody.Data.Add(new Cell(head.PointCell.Value, unitType, 1, 1, false, false));
                    }
                    else if (head.CellValue.Contains("核算单元人员数量"))
                    {
                        var data = dataList.FirstOrDefault(t => t.RowNumber == rowNumber && t.SignID == head.SignID);
                        var value = data?.CellValue;
                        if (value.HasValue && value.Value > 0)
                            rowbody.Data.Add(new Cell(head.PointCell.Value, value, 1, 1, data.IsTotal == 1, true, data.Annotation, data.ID, head.CellValue));
                    }
                    else if (head.CellValue.Contains("核算单元"))
                    {
                        if (head.CellValue.Contains("医生组"))
                        {
                            var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber && t.UnitType == 1);
                            rowbody.Data.Add(new Cell(head.PointCell.Value, value?.AccountingUnit, 1, 1, false, false, "", value?.ID ?? 0, head.CellValue));
                        }
                        else if (head.CellValue.Contains("护理组"))
                        {
                            var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber && t.UnitType == 2);
                            rowbody.Data.Add(new Cell(head.PointCell.Value, value?.AccountingUnit, 1, 1, false, false, "", value?.ID ?? 0, head.CellValue));
                        }
                        else if (head.CellValue.Contains("医技组"))
                        {
                            var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber && t.UnitType == 3);
                            rowbody.Data.Add(new Cell(head.PointCell.Value, value?.AccountingUnit, 1, 1, false, false, "", value?.ID ?? 0, head.CellValue));
                        }
                        else
                        {
                            var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber);
                            rowbody.Data.Add(new Cell(head.PointCell.Value, value?.AccountingUnit, 1, 1, false, false, "", value?.ID ?? 0, head.CellValue));
                        }
                    }
                    else if (head.CellValue.Contains("科室名称"))
                    {
                        var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber);
                        rowbody.Data.Add(new Cell(head.PointCell.Value, value.Department, 1, 1, false, false, "", value.ID, head.CellValue));
                    }
                    else if (head.CellValue.Contains("备注"))
                    {
                        var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber);
                        rowbody.Data.Add(new Cell(head.PointCell.Value, value.Remark, 1, 1, false, false, "", value.ID, head.CellValue));
                    }
                    else if (head.CellValue.Contains("人员工号"))
                    {
                        var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber).JobNumber;
                        rowbody.Data.Add(new Cell(head.PointCell.Value, value, 1, 1, false, false));
                    }
                    else if (head.CellValue.Contains("医生姓名"))
                    {
                        var value = dataList.FirstOrDefault(t => t.RowNumber == rowNumber).EmployeeName;
                        rowbody.Data.Add(new Cell(head.PointCell.Value, value, 1, 1, false, false));
                    }
                    else if (!rowbody.Data.Any(t => t.PointCell == head.PointCell))
                    {
                        var data = dataList.FirstOrDefault(t => t.RowNumber == rowNumber && t.SignID == head.SignID);
                        var value = data?.CellValue;
                        if (value.HasValue)
                        {
                            if (!percentparam.Contains(head.CellValue))
                                rowbody.Data.Add(new Cell(head.PointCell.Value, value, 1, 1, data.IsTotal == 1, true, data.Annotation, data.ID, head.CellValue));
                            else
                                rowbody.Data.Add(new Cell(head.PointCell.Value, Math.Round(value.Value * 100, 2) + "%", 1, 1, data.IsTotal == 1, true, data.Annotation, data.ID, head.CellValue));
                        }
                    }
                }
            }
            #endregion
        }

        private void AccountNurseExport(int sheetID, SheetExportResponse response)
        {
            var list = _perforResaccountRepository.GetEntities(t => t.UnitType == (int)UnitType.护理组 && t.SheetID == sheetID)?.OrderByDescending(t => t.AccountingUnit);

            if (list != null && list.Count() > 0)
            {
                // Tuple Items: 列明, 字段名, mergeRow, mergeCell, isTotal
                List<(string, Func<res_account, object>, int, int, bool, bool)> pairs =
                    new List<(string, Func<res_account, object>, int, int, bool, bool)>
                {
                    ("核算单元", (t) => t.AccountingUnit, 1, 1, false, false),
                    //("护士长人数", (t) => t.ManagerNumber, 1, 1, false, false),
                    ("核算单元护士数量", (t) => t.Number, 1, 1, false, false),
                    ("医生基础系数", (t) => t.BasicFactor, 1, 1, false, false),
                    ("倾斜系数", (t) => t.SlopeFactor, 1, 1, false, true),
                    ("其他绩效1", (t) => t.OtherPerfor1, 1, 1, false, false),
                    ("其他绩效2", (t) => t.OtherPerfor2, 1, 1, false, true),
                    ("药占比奖罚", (t) => t.MedicineExtra, 1, 1, false, false),
                    ("材料占比奖罚", (t) => t.MaterialsExtra , 1, 1, false, true),
                    ("医院奖罚", (t) =>  t.Extra, 1, 1, false, true),
                    ("考核对分率", (t) => t.ScoringAverage, 1, 1, false, true),
                    ("调节系数", (t) =>t.AdjustFactor, 1, 1, false, true),
                    ("科室业绩", (t) => t.Income, 1, 1, false, true),
                    ("业绩绩效", (t) => t.PerforFee, 1, 1, false, true),
                    ("工作量绩效", (t) => t.WorkloadFee, 1, 1, false, true),
                    ("绩效合计", (t) => t.PerforTotal, 1, 1, false, true),
                    ("人均绩效", (t) => t.Avg, 1, 1, false, true),
                    ("实发绩效", (t) => t.RealGiveFee, 1, 1, false, true),
                };
                var row = new Row(0);
                int index = 1;
                foreach (var item in pairs)
                {
                    row.Data.Add(new Cell(index, item.Item1, item.Item3, item.Item4, item.Item5, item.Item6)
                    {
                        FieldName = item.Item1,
                        CellType = "header"
                    });
                    index += 1;
                }
                response.Header.Add(row);

                for (int i = 0; i < list.Count(); i++)
                {
                    var account = list.ElementAt(i);
                    var rowbody = new Row(i);
                    index = 1;
                    foreach (var item in pairs)
                    {
                        rowbody.Data.Add(new Cell(index, item.Item2.Invoke(account), item.Item3, item.Item4, item.Item5, item.Item6, id: account.ID));
                        index += 1;
                    }
                    response.Row.Add(rowbody);
                }
            }
        }

        private void AccountDoctorExport(int sheetID, SheetExportResponse response)
        {
            var list = _perforResaccountRepository.GetEntities(t => t.UnitType != (int)UnitType.护理组 && t.SheetID == sheetID)?.OrderByDescending(t => t.AccountingUnit);

            if (list != null && list.Count() > 0)
            {
                // Tuple Items: 列明, 字段名, mergeRow, mergeCell, isTotal
                List<(string, Func<res_account, object>, int, int, bool, bool)> pairs =
                    new List<(string, Func<res_account, object>, int, int, bool, bool)>
                {
                    ("核算单元", (t) => t.AccountingUnit, 1, 1, false, false),
                    //("科主任人数", (t) => t.ManagerNumber, 1, 1, false, false),
                    ("核算单元医生数量", (t) => t.Number, 1, 1, false, false),
                    ("医生基础系数", (t) => t.BasicFactor, 1, 1, false, false),
                    ("倾斜系数", (t) => t.SlopeFactor, 1, 1, false, true),
                    ("其他绩效1", (t) => t.OtherPerfor1, 1, 1, false, false),
                    ("其他绩效2", (t) => t.OtherPerfor2, 1, 1, false, true),
                    ("药占比奖罚", (t) => t.MedicineExtra, 1, 1, false, false),
                    ("材料占比奖罚", (t) => t.MaterialsExtra , 1, 1, false, true),
                    ("医院奖罚", (t) =>  t.Extra, 1, 1, false, true),
                    ("考核对分率", (t) => t.ScoringAverage, 1, 1, false, true),
                    ("调节系数", (t) =>t.AdjustFactor, 1, 1, false, true),
                    ("科室业绩", (t) => t.Income, 1, 1, false, true),
                    ("业绩绩效", (t) => t.PerforFee, 1, 1, false, true),
                    ("工作量绩效", (t) => t.WorkloadFee, 1, 1, false, true),
                    ("绩效合计", (t) => t.PerforTotal, 1, 1, false, true),
                    ("人均绩效", (t) => t.Avg, 1, 1, false, true),
                    ("实发绩效", (t) => t.RealGiveFee, 1, 1, false, true),
                };
                var row = new Row(0);
                int index = 1;
                foreach (var item in pairs)
                {
                    row.Data.Add(new Cell(index, item.Item1, item.Item3, item.Item4, item.Item5, item.Item6)
                    {
                        FieldName = item.Item1,
                        CellType = "header"
                    });
                    index += 1;
                }
                response.Header.Add(row);

                for (int i = 0; i < list.Count(); i++)
                {
                    var account = list.ElementAt(i);
                    var rowbody = new Row(i);
                    index = 1;
                    foreach (var item in pairs)
                    {
                        rowbody.Data.Add(new Cell(index, item.Item2.Invoke(account), item.Item3, item.Item4, item.Item5, item.Item6, id: account.ID));
                        index += 1;
                    }
                    response.Row.Add(rowbody);
                }
            }
        }

        //private void AccountBaiscExport(int sheetID, SheetExportResponse response)
        //{
        //    var list = _perforImaccountbasicRepository.GetEntities(t => t.SheetID == sheetID)?.OrderBy(t => t.UnitType).ThenByDescending(t => t.DoctorAccountingUnit);

        //    if (list != null && list.Count() > 0)
        //    {
        //        var row = new Row(0);
        //        row.Data.Add(new Cell(1, "核算单元类型", 1, 1, false, false));
        //        row.Data.Add(new Cell(2, "核算单元", 1, 1, false, false));
        //        row.Data.Add(new Cell(3, "科室名称", 1, 1, false, false));
        //        row.Data.Add(new Cell(4, "科主任/护士长人数", 1, 1, false, false));
        //        row.Data.Add(new Cell(5, "核算单元人员数量", 1, 1, false, false));
        //        row.Data.Add(new Cell(6, "预算比例", 1, 1, false, false));
        //        row.Data.Add(new Cell(7, "倾斜系数", 1, 1, false, false));
        //        row.Data.Add(new Cell(8, "规模绩效系数", 1, 1, false, false));
        //        row.Data.Add(new Cell(9, "效率绩效系数", 1, 1, false, false));
        //        row.Data.Add(new Cell(10, "管理绩效发放系数", 1, 1, false, false));
        //        row.Data.Add(new Cell(11, "其他绩效1", 1, 1, false, false));
        //        row.Data.Add(new Cell(12, "考核得分率", 1, 1, false, false));
        //        row.Data.Add(new Cell(13, "药占比奖罚", 1, 1, false, false));
        //        row.Data.Add(new Cell(14, "材料占比奖罚", 1, 1, false, false));
        //        row.Data.Add(new Cell(15, "医院奖罚", 1, 1, false, false));
        //        row.Data.Add(new Cell(16, "其他绩效2", 1, 1, false, false));
        //        row.Data.Add(new Cell(17, "调节系数", 1, 1, false, false));

        //        response.Header.Add(row);
        //        for (int i = 0; i < list.Count(); i++)
        //        {
        //            var item = list.ElementAt(i);
        //            var rowbody = new Row(i);
        //            rowbody.Data.Add(new Cell(1, ((UnitType)item.UnitType).ToString(), 1, 1, false, false));
        //            rowbody.Data.Add(new Cell(2, item.DoctorAccountingUnit, 1, 1, false, false));
        //            rowbody.Data.Add(new Cell(3, item.Department, 1, 1, false, false));
        //            rowbody.Data.Add(new Cell(4, item.DoctorDirectorNumber, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(5, item.DoctorNumber, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(6, item.DoctorBasicFactor, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(7, item.DoctorSlopeFactor, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(8, item.DoctorScale, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(9, item.DoctorEffic, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(10, item.DoctorGrant, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(11, item.DoctorOtherPerfor1, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(12, item.DoctorScoringAverage, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(13, item.MedicineExtra, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(14, item.MaterialsExtra, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(15, item.DoctorExtra, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(16, item.DoctorOtherPerfor2, 1, 1, false, true));
        //            rowbody.Data.Add(new Cell(17, item.DoctorAdjustFactor, 1, 1, false, true));
        //            response.Row.Add(rowbody);
        //        }
        //    }
        //}

        private void EmployeeExport(int sheetID, SheetExportResponse response)
        {
            var employeeList = _perforImEmployeeRepository.GetEntities(t => t.SheetID == sheetID)?
                .OrderByDescending(t => t.AccountType)
                .ThenBy(t => t.AccountingUnit);

            if (employeeList != null && employeeList.Count() > 0)
            {
                var pairs = PerSheetHeader.employeeHeaders;
                var row = new Row(0);
                int index = 1;
                foreach (var item in pairs)
                {
                    row.Data.Add(new Cell(index, item.Item1, item.Item3, item.Item4, item.Item5, item.Item6, fieldName: item.Item8, cellType: "header"));
                    index += 1;
                }
                response.Header.Add(row);

                for (int i = 0; i < employeeList.Count(); i++)
                {
                    var employee = employeeList.ElementAt(i);
                    var rowbody = new Row(i);
                    index = 1;
                    foreach (var item in pairs)
                    {
                        if (item.Item7)
                            rowbody.Data.Add(new Cell(index, $"{item.Item2.Invoke(employee)}%", item.Item3, item.Item4, item.Item5, item.Item6, id: employee.ID, fieldName: item.Item8));
                        else
                            rowbody.Data.Add(new Cell(index, item.Item2.Invoke(employee), item.Item3, item.Item4, item.Item5, item.Item6, id: employee.ID, fieldName: item.Item8));
                        index += 1;
                    }
                    response.Row.Add(rowbody);
                }
            }
        }

        private void ClinicEmployeeExport(int sheetID, SheetExportResponse response)
        {
            var clinicemployeeList = _perforImemployeeclinicRepository.GetEntities(t => t.SheetID == sheetID)?
                .OrderByDescending(t => t.UnitType)
                .ThenBy(t => t.AccountingUnit);

            if (clinicemployeeList != null && clinicemployeeList.Count() > 0)
            {
                var pairs = PerSheetHeader.employeeClinicHeaders;
                var row = new Row(0);
                int index = 1;
                foreach (var item in pairs)
                {
                    row.Data.Add(new Cell(index, item.Item1, item.Item3, item.Item4, item.Item5, item.Item6, fieldName: item.Item8, cellType: "header"));
                    index += 1;
                }
                response.Header.Add(row);

                for (int i = 0; i < clinicemployeeList.Count(); i++)
                {
                    var employee = clinicemployeeList.ElementAt(i);
                    var rowbody = new Row(i);
                    index = 1;
                    foreach (var item in pairs)
                    {
                        if (item.Item7)
                            rowbody.Data.Add(new Cell(index, $"{item.Item2.Invoke(employee)}%", item.Item3, item.Item4, item.Item5, item.Item6, id: employee.ID, fieldName: item.Item8));
                        else
                            rowbody.Data.Add(new Cell(index, item.Item2.Invoke(employee), item.Item3, item.Item4, item.Item5, item.Item6, id: employee.ID, fieldName: item.Item8));
                        index += 1;
                    }
                    response.Row.Add(rowbody);
                }
            }
        }

        private void LogisticsEmployeeExport(int sheetID, SheetExportResponse response)
        {
            var employeeList = _perforImemployeelogisticsRepository.GetEntities(t => t.SheetID == sheetID)?
                .OrderByDescending(t => t.AccountType)
                .ThenBy(t => t.AccountingUnit);

            if (employeeList != null && employeeList.Count() > 0)
            {
                var pairs = PerSheetHeader.employeeLogisticsHeaders;
                var row = new Row(0);
                int index = 1;
                foreach (var item in pairs)
                {
                    row.Data.Add(new Cell(index, item.Item1, item.Item3, item.Item4, item.Item5, item.Item6, fieldName: item.Item8, cellType: "header"));
                    index += 1;
                }
                response.Header.Add(row);

                for (int i = 0; i < employeeList.Count(); i++)
                {
                    var employee = employeeList.ElementAt(i);
                    var rowbody = new Row(i);
                    index = 1;
                    foreach (var item in pairs)
                    {
                        if (item.Item7)
                            rowbody.Data.Add(new Cell(index, $"{item.Item2.Invoke(employee)}%", item.Item3, item.Item4, item.Item5, item.Item6, id: employee.ID, fieldName: item.Item8));
                        else
                            rowbody.Data.Add(new Cell(index, item.Item2.Invoke(employee), item.Item3, item.Item4, item.Item5, item.Item6, id: employee.ID, fieldName: item.Item8));
                        index += 1;
                    }
                    response.Row.Add(rowbody);
                }
            }
        }

        private void SpecialUnitExport(int sheetID, SheetExportResponse response)
        {
            var list = _perforImspecialunitRepository.GetEntities(t => t.SheetID == sheetID)?.OrderByDescending(t => t.AccountingUnit);

            if (list != null && list.Count() > 0)
            {
                var pairs = PerSheetHeader.specialUnitHeaders;
                var row = new Row(0);
                int index = 1;
                foreach (var item in pairs)
                {
                    row.Data.Add(new Cell(index, item.Item1, item.Item3, item.Item4, item.Item5, item.Item6, fieldName: item.Item8, cellType: "header"));
                    index += 1;
                }
                response.Header.Add(row);

                for (int i = 0; i < list.Count(); i++)
                {
                    var specialunit = list.ElementAt(i);
                    var rowbody = new Row(i);
                    index = 1;
                    foreach (var item in pairs)
                    {
                        if (item.Item7)
                            rowbody.Data.Add(new Cell(index, $"{item.Item2.Invoke(specialunit)}%", item.Item3, item.Item4, item.Item5, item.Item6, id: specialunit.ID, fieldName: item.Item8));
                        else
                            rowbody.Data.Add(new Cell(index, item.Item2.Invoke(specialunit), item.Item3, item.Item4, item.Item5, item.Item6, id: specialunit.ID, fieldName: item.Item8));
                        index += 1;
                    }
                    response.Row.Add(rowbody);
                }
            }
        }

        /// <summary>
        /// 添加系数值
        /// </summary>
        /// <param name="response"></param>
        /// <param name="row"></param>
        /// <param name="headList"></param>
        /// <param name="dataList"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private SheetExportResponse AddFactor(SheetExportResponse response, Row row, List<im_header> headList, List<im_data> dataList, UnitType? unitType = null)
        {
            response.Header.Add(row);
            if (unitType == null)
            {
                string[] array = new string[] { "核算单元", "科室名称" };
                foreach (var header in headList.Where(t => !t.ParentID.HasValue || t.ParentID.Value == 0))
                {
                    if (!array.Contains(header.CellValue) && dataList != null && dataList.Any())
                    {
                        var value = dataList.FirstOrDefault(t => t.AllotID == header.AllotID && t.SheetID == header.SheetID && t.IsFactor == 1
                                 && t.TypeName == header.CellValue);
                        row.Data.Add(new Cell(header.PointCell.Value, value?.FactorValue, 1, 1, header.IsTotal == 1, false, id: value?.ID ?? 0, fieldName: header.CellValue, cellType: "factor"));
                    }
                }
            }
            else
            {
                string[] array = new string[] { "核算单元（医技组）", "核算单元（医生组）", "核算单元（护理组）", "科室名称" };
                foreach (var header in headList.Where(t => !t.ParentID.HasValue || t.ParentID.Value == 0))
                {
                    if (!array.Contains(header.CellValue) && dataList != null && dataList.Any())
                    {
                        var value = dataList.FirstOrDefault(t => t.AllotID == header.AllotID && t.SheetID == header.SheetID && t.IsFactor == 1
                                     && t.TypeName == header.CellValue && t.UnitType == (int)unitType);
                        row.Data.Add(new Cell(header.PointCell.Value, value?.FactorValue, 1, 1, header.IsTotal == 1, false, id: value?.ID ?? 0, fieldName: header.CellValue, cellType: "factor"));
                    }
                }
            }
            return response;
        }
    }
}
