using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using Performance.Services.ExtractExcelService;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Performance.Services
{
    public class ReportGlobalService : IAutoInjection
    {
        private readonly ILogger logger;
        private readonly PerforPerallotRepository perallotRepository;
        private readonly PerforReportglobalRepository reportglobalRepository;
        private readonly PerforHisimportdataRepository hisimportdataRepository;
        private readonly PerforHisimportaccountRepository hisimportaccountRepository;
        private readonly PerforHisimportclinicRepository hisimportclinicRepository;
        private readonly PerforHisimportbaiscnormRepository hisimportbaiscnormRepository;
        private readonly PerforReportperformancetagsRepository reportperformancetagsRepository;
        private readonly PerforReportperformancepersontagsRepository reportperformancepersontagsRepository;

        public ReportGlobalService(
            ILogger<ReportGlobalService> logger,
            PerforPerallotRepository perallotRepository,
            PerforReportglobalRepository reportglobalRepository,
            PerforHisimportdataRepository hisimportdataRepository,
            PerforHisimportaccountRepository hisimportaccountRepository,
            PerforHisimportclinicRepository hisimportclinicRepository,
            PerforHisimportbaiscnormRepository hisimportbaiscnormRepository,
            PerforReportperformancetagsRepository reportperformancetagsRepository,
            PerforReportperformancepersontagsRepository reportperformancepersontagsRepository
            )
        {
            this.logger = logger;
            this.perallotRepository = perallotRepository;
            this.reportglobalRepository = reportglobalRepository;
            this.hisimportdataRepository = hisimportdataRepository;
            this.hisimportaccountRepository = hisimportaccountRepository;
            this.hisimportclinicRepository = hisimportclinicRepository;
            this.hisimportbaiscnormRepository = hisimportbaiscnormRepository;
            this.reportperformancetagsRepository = reportperformancetagsRepository;
            this.reportperformancepersontagsRepository = reportperformancepersontagsRepository;
        }

        #region Report_Global

        public List<report_global> GetReportGlobals(int hospitalId)
        {
            var globals = reportglobalRepository.GetEntities(t => t.HospitalID == hospitalId)
                ?.OrderBy(t => t.Category).ThenBy(t => t.Year).ThenBy(t => t.Month).ToList();
            return globals;
        }

        public bool CreateReportGlobal(report_global global)
        {
            return reportglobalRepository.Add(global);
        }

        public bool UpdateReportGlobal(report_global global)
        {
            var entity = reportglobalRepository.GetEntity(t => t.Id == global.Id);
            entity.Year = global.Year;
            entity.Month = global.Month;
            entity.Category = global.Category;
            entity.Value = global.Value;
            return reportglobalRepository.Update(entity);
        }

        public bool DeleteReportGlobal(int globalId)
        {
            var entity = reportglobalRepository.GetEntity(t => t.Id == globalId);
            return reportglobalRepository.Remove(entity);
        }

        #endregion Report_Global

        #region Copy Previous Report Data

        public void CopyPreviousGlobalData(per_allot allot)
        {
            var globals = reportglobalRepository.GetEntities(t => t.HospitalID == allot.HospitalId);
            if (globals == null || !globals.Any()) return;

            var onlyYears = globals.Where(t => t.Year.HasValue && !t.Month.HasValue);
            if (onlyYears != null && onlyYears.Any())
            {
                var year = onlyYears.Where(t => t.Year < allot.Year)?.Max(t => t.Year);
                if (year.HasValue)
                {
                    var current = onlyYears.Where(t => t.Year == allot.Year)?.ToList() ?? new List<report_global>();
                    var previous = onlyYears.Where(t => t.Year == year)?.ToList() ?? new List<report_global>();

                    var newdata = previous.Where(t => !current.Select(s => s.Category).Contains(t.Category))?.ToList();
                    if (newdata != null && newdata.Any())
                    {
                        newdata = newdata.Select(t => new report_global
                        {
                            HospitalID = allot.HospitalId,
                            Year = allot.Year,
                            Category = t.Category,
                            Value = t.Value
                        }).ToList();
                        reportglobalRepository.AddRange(newdata.ToArray());
                    }
                }
            }

            var yearAndMonth = globals.Where(t => t.Year.HasValue && t.Month.HasValue);
            if (yearAndMonth != null && yearAndMonth.Any())
            {
                var month = yearAndMonth.Where(t => t.Year == allot.Year && t.Month < allot.Month)?.Max(t => t.Month);
                if (allot.Month == 1 || !month.HasValue)
                {
                    var year = yearAndMonth.Where(t => t.Year < allot.Year)?.Max(t => t.Year);
                    month = yearAndMonth.Where(t => t.Year == year)?.Max(t => t.Month);
                    if (year.HasValue && month.HasValue)
                    {
                        var current = yearAndMonth.Where(t => t.Year == allot.Year && t.Month == allot.Month)?.ToList() ?? new List<report_global>();
                        var previous = yearAndMonth.Where(t => t.Year == year && t.Month == month)?.ToList() ?? new List<report_global>();

                        var newdata = previous.Where(t => !current.Select(s => s.Category).Contains(t.Category))?.ToList();
                        if (newdata != null && newdata.Any())
                        {
                            newdata = newdata.Select(t => new report_global
                            {
                                HospitalID = allot.HospitalId,
                                Year = allot.Year,
                                Month = allot.Month,
                                Category = t.Category,
                                Value = t.Value
                            }).ToList();
                            reportglobalRepository.AddRange(newdata.ToArray());
                        }
                    }
                }
                else
                {
                    if (month.HasValue)
                    {
                        var current = yearAndMonth.Where(t => t.Year == allot.Year && t.Month == allot.Month)?.ToList() ?? new List<report_global>();
                        var previous = yearAndMonth.Where(t => t.Year == allot.Year && t.Month == month)?.ToList() ?? new List<report_global>();

                        var newdata = previous.Where(t => !current.Select(s => s.Category).Contains(t.Category))?.ToList();
                        if (newdata != null && newdata.Any())
                        {
                            newdata = newdata.Select(t => new report_global
                            {
                                HospitalID = allot.HospitalId,
                                Year = allot.Year,
                                Month = allot.Month,
                                Category = t.Category,
                                Value = t.Value
                            }).ToList();
                            reportglobalRepository.AddRange(newdata.ToArray());
                        }
                    }
                }
            }
        }

        #endregion Copy Previous Report Data

        #region ImportFile && SaveData

        public void ImportAllotData(int hospitalId, string filePath)
        {
            IWorkbook workbook = null;
            try
            {
                workbook = ExcelHelper.GetWorkbook(filePath);
                if (workbook == null) throw new PerformanceException("文件读取失败");

                var allots = perallotRepository.GetEntities(t => t.HospitalId == hospitalId);

                var basicnormData = new List<his_import_baiscnorm>();

                for (int sheetIndex = 0; sheetIndex < workbook.NumberOfSheets; sheetIndex++)
                {
                    var sheet = workbook.GetSheetAt(sheetIndex);

                    if (sheet == null) continue;

                    string sheetName = sheet.SheetName.NoBlank();
                    logger.LogInformation($"正在读取{sheetName}的数据");

                    var columns = GetColumns(sheet, sheetName, out string sourceType);
                    if (columns == null || !columns.Any(t => !string.IsNullOrEmpty(t.NoBlank()))) continue;

                    switch (sheetName)
                    {
                        case "科室绩效":
                            ImporAccountData(sheet, columns, hospitalId, allots, basicnormData);
                            break;

                        case "科室标签":
                            ImporAccountTag(sheet, columns, hospitalId);
                            break;

                        case "科主任护士长绩效":
                            ImporClinicData(sheet, columns, hospitalId, allots, basicnormData);
                            break;

                        case "科主任护士长标签":
                            ImporClinicTag(sheet, columns, hospitalId);
                            break;

                        default:
                            ImportBasicData(sheet, columns, hospitalId, allots, sheetName, sourceType);
                            break;
                    }
                    logger.LogInformation($"{sheetName}读取已结束");
                }

                #region 人均绩效

                if (basicnormData != null && basicnormData.Any())
                {
                    foreach (var item in basicnormData.Select(t => new { t.Year, t.Month }).Distinct())
                    {
                        hisimportbaiscnormRepository.DeleteFromQuery(t => t.HospitalId == hospitalId && t.Year == item.Year && t.Month == item.Month);
                    }
                    hisimportbaiscnormRepository.BulkInsert(basicnormData);
                }

                #endregion 科室总绩效 人均绩效
            }
            catch (Exception ex)
            {
                logger.LogError(ex.ToString());
            }
        }

        private void ImportBasicData(ISheet sheet, List<string> columns, int hospitalId, List<per_allot> allots, string sheetName, string sourceType)
        {
            if (string.IsNullOrEmpty(sourceType)) return;

            var data = new List<his_importdata>();
            for (int rowIndex = 1; rowIndex < sheet.LastRowNum + 1; rowIndex++)
            {
                var row = sheet.GetRow(rowIndex);
                if (row == null) continue;

                his_importdata importdata = new his_importdata
                {
                    Year = GetCellValue<int>(row, columns, "年份"),
                    Month = GetCellValue<int>(row, columns, "月份"),
                    AccountingUnit = GetCellValue<string>(row, columns, "核算单元"),
                    Department = GetCellValue<string>(row, columns, "科室"),
                    PersonnelNumber = GetCellValue<string>(row, columns, "工号"),
                    PersonnelName = GetCellValue<string>(row, columns, "医生姓名"),
                    Original = GetCellValue<string>(row, columns, "类别"),
                    Value = GetCellValue<decimal>(row, columns, "值"),
                };
                data.Add(importdata);
            }
            logger.LogInformation($"{sheet.SheetName}共有{sheet.LastRowNum}行数据，读取到{data.Count}条记录");
            if (data == null || !data.Any(t => t.Year != 0 && t.Month != 0)) return;

            var dateTime = DateTime.Now;
            data.ForEach(t =>
            {
                t.HospitalId = hospitalId;
                t.AllotId = allots?.FirstOrDefault(w => w.Year == t.Year && t.Month == w.Month)?.ID;
                t.SourceType = sourceType;
                t.Category = sheetName;
                t.CreateTime = dateTime;
            });

            foreach (var item in data.Select(t => new { t.Year, t.Month }).Distinct())
            {
                hisimportdataRepository.DeleteFromQuery(t => t.HospitalId == hospitalId && t.Category == sheetName && t.Year == item.Year && t.Month == item.Month);
            }
            hisimportdataRepository.BulkInsert(data.Where(t => t.Year != 0 && t.Month != 0));
        }

        private void ImporAccountData(ISheet sheet, List<string> columns, int hospitalId, List<per_allot> allots, List<his_import_baiscnorm> basicnormData)
        {
            var data = new List<his_import_account>();
            for (int rowIndex = 1; rowIndex < sheet.LastRowNum + 1; rowIndex++)
            {
                var row = sheet.GetRow(rowIndex);
                if (row == null) continue;

                his_import_account importdata = new his_import_account
                {
                    Year = GetCellValue<int>(row, columns, "年份"),
                    Month = GetCellValue<int>(row, columns, "月份"),
                    UnitType = GetCellValue<string>(row, columns, "核算单元类型"),
                    AccountingUnit = GetCellValue<string>(row, columns, "核算单元"),
                    Number = GetCellValue<decimal>(row, columns, "核算单元人员数量"),
                    RealGiveFee = GetCellValue<decimal>(row, columns, "实发绩效"),
                };
                data.Add(importdata);
            }
            logger.LogInformation($"{sheet.SheetName}共有{sheet.LastRowNum}行数据，读取到{data.Count}条记录");
            if (data == null || !data.Any(t => t.Year != 0 && t.Month != 0)) return;

            var dateTime = DateTime.Now;
            data.ForEach(t =>
            {
                t.HospitalId = hospitalId;
                t.AllotId = allots?.FirstOrDefault(w => w.Year == t.Year && t.Month == w.Month)?.ID ?? 0;
                t.CreateTime = dateTime;
            });

            #region his_import_baiscnorm 人均绩效计算
            logger.LogInformation($"人均绩效计算");
            Dictionary<string, string> basicDict = new Dictionary<string, string>
            {
                { "行政工勤人均绩效", UnitType.行政后勤.ToString() },
                { "临床医生人均绩效", UnitType.医生组.ToString() },
                { "医技医生人均绩效", UnitType.医技组.ToString() },
                { "护士人均绩效", UnitType.护理组.ToString() },
            };
            List<his_import_baiscnorm> baiscnorms = new List<his_import_baiscnorm>();
            foreach (var item in basicDict)
            {
                basicnormData.AddRange(data.Where(t => t.UnitType == item.Value).GroupBy(t => new { t.AllotId, t.Year, t.Month }).Select(t => new his_import_baiscnorm
                {
                    HospitalId = hospitalId,
                    AllotId = t.Key.AllotId ?? 0,
                    Year = t.Key.Year,
                    Month = t.Key.Month,
                    PositionName = item.Key,
                    TotelValue = t.Sum(s => s.RealGiveFee),
                    TotelNumber = t.Sum(s => s.Number),
                    AvgValue = t.Sum(s => s.Number) == 0 ? 0 : t.Sum(s => s.RealGiveFee) / t.Sum(s => s.Number),
                    CreateTime = dateTime
                }));
            }
            #endregion his_import_baiscnorm

            #region his_import_account 临床科室绩效
            logger.LogInformation($"临床科室绩效");
            foreach (var item in data.Select(t => new { t.Year, t.Month }).Distinct())
            {
                hisimportaccountRepository.DeleteFromQuery(t => t.HospitalId == hospitalId && t.Year == item.Year && t.Month == item.Month);
            }
            hisimportaccountRepository.BulkInsert(data.Where(t => t.Year != 0 && t.Month != 0));
            #endregion his_import_account
        }

        private void ImporAccountTag(ISheet sheet, List<string> columns, int hospitalId)
        {
            var data = new List<report_performance_tags>();
            for (int rowIndex = 1; rowIndex < sheet.LastRowNum + 1; rowIndex++)
            {
                var row = sheet.GetRow(rowIndex);
                if (row == null) continue;

                report_performance_tags importdata = new report_performance_tags
                {
                    UnitType = GetCellValue<string>(row, columns, "核算单元类型"),
                    AccountingUnit = GetCellValue<string>(row, columns, "核算单元"),
                    Tag1 = GetCellValue<string>(row, columns, "Tag1"),
                    Tag2 = GetCellValue<string>(row, columns, "Tag2"),
                    Tag3 = GetCellValue<string>(row, columns, "Tag3"),
                    Tag4 = GetCellValue<string>(row, columns, "Tag4"),
                    Tag5 = GetCellValue<string>(row, columns, "Tag5"),
                };
                data.Add(importdata);
            }
            logger.LogInformation($"{sheet.SheetName}共有{sheet.LastRowNum}行数据，读取到{data.Count}条记录");
            if (data == null || !data.Any(t => !string.IsNullOrEmpty(t.UnitType) && !string.IsNullOrEmpty(t.AccountingUnit))) return;

            var dateTime = DateTime.Now;
            data.ForEach(t =>
            {
                t.HospitalId = hospitalId;
                t.CreateTime = dateTime;
            });

            reportperformancetagsRepository.DeleteFromQuery(t => t.HospitalId == hospitalId);
            reportperformancetagsRepository.BulkInsert(data.Where(t => !string.IsNullOrEmpty(t.UnitType) && !string.IsNullOrEmpty(t.AccountingUnit)));
        }

        private void ImporClinicData(ISheet sheet, List<string> columns, int hospitalId, List<per_allot> allots, List<his_import_baiscnorm> basicnormData)
        {
            var data = new List<his_import_clinic>();
            for (int rowIndex = 1; rowIndex < sheet.LastRowNum + 1; rowIndex++)
            {
                var row = sheet.GetRow(rowIndex);
                if (row == null) continue;

                his_import_clinic importdata = new his_import_clinic
                {
                    Year = GetCellValue<int>(row, columns, "年份"),
                    Month = GetCellValue<int>(row, columns, "月份"),
                    UnitType = GetCellValue<string>(row, columns, "核算单元类型"),
                    AccountingUnit = GetCellValue<string>(row, columns, "核算单元"),
                    AccountType = GetCellValue<string>(row, columns, "职称"),
                    JobNumber = GetCellValue<string>(row, columns, "工号"),
                    EmployeeName = GetCellValue<string>(row, columns, "姓名"),
                    Basics = GetCellValue<decimal>(row, columns, "基础绩效系数"),
                    RealGiveFee = GetCellValue<decimal>(row, columns, "实发绩效"),
                };
                data.Add(importdata);
            }
            logger.LogInformation($"{sheet.SheetName}共有{sheet.LastRowNum}行数据，读取到{data.Count}条记录");
            if (data == null || !data.Any(t => t.Year != 0 && t.Month != 0)) return;

            var dateTime = DateTime.Now;
            data.ForEach(t =>
            {
                t.HospitalId = hospitalId;
                t.AllotId = allots?.FirstOrDefault(w => w.Year == t.Year && t.Month == w.Month)?.ID ?? 0;
                t.CreateTime = dateTime;
            });

            #region his_import_baiscnorm 人均绩效计算
            logger.LogInformation($"人均绩效计算");
            Dictionary<string, string> basicDict = new Dictionary<string, string>
            {
                { "临床科室主任人均绩效", UnitType.医生组.ToString() },
                { "医技科室主任人均绩效", UnitType.医技组.ToString() },
                { "护士长人均绩效", UnitType.护理组.ToString() },
            };
            List<his_import_baiscnorm> baiscnorms = new List<his_import_baiscnorm>();
            foreach (var item in basicDict)
            {
                basicnormData.AddRange(data.Where(t => t.UnitType == item.Value).GroupBy(t => new { t.AllotId, t.Year, t.Month }).Select(t => new his_import_baiscnorm
                {
                    HospitalId = hospitalId,
                    AllotId = t.Key.AllotId ?? 0,
                    Year = t.Key.Year,
                    Month = t.Key.Month,
                    PositionName = item.Key,
                    TotelValue = t.Sum(s => s.RealGiveFee),
                    TotelNumber = t.Sum(s => s.Basics),
                    AvgValue = t.Sum(s => s.Basics) == 0 ? 0 : t.Sum(s => s.RealGiveFee) / t.Sum(s => s.Basics),
                    CreateTime = dateTime
                }));
            }
            #endregion his_import_baiscnorm

            #region his_import_clinic 科主任护士长绩效
            logger.LogInformation($"科主任护士长绩效");
            foreach (var item in data.Select(t => new { t.Year, t.Month }).Distinct())
            {
                hisimportclinicRepository.DeleteFromQuery(t => t.HospitalId == hospitalId && t.Year == item.Year && t.Month == item.Month);
            }
            hisimportclinicRepository.BulkInsert(data.Where(t => t.Year != 0 && t.Month != 0));
            #endregion his_import_clinic
        }

        private void ImporClinicTag(ISheet sheet, List<string> columns, int hospitalId)
        {
            var data = new List<report_performance_person_tags>();
            for (int rowIndex = 1; rowIndex < sheet.LastRowNum + 1; rowIndex++)
            {
                var row = sheet.GetRow(rowIndex);
                if (row == null) continue;

                report_performance_person_tags importdata = new report_performance_person_tags
                {
                    UnitType = GetCellValue<string>(row, columns, "核算单元类型"),
                    AccountingUnit = GetCellValue<string>(row, columns, "核算单元"),
                    PersonnelName = GetCellValue<string>(row, columns, "姓名"),
                    PersonnelNumber = GetCellValue<string>(row, columns, "工号"),
                    Tag1 = GetCellValue<string>(row, columns, "Tag1"),
                    Tag2 = GetCellValue<string>(row, columns, "Tag2"),
                    Tag3 = GetCellValue<string>(row, columns, "Tag3"),
                    Tag4 = GetCellValue<string>(row, columns, "Tag4"),
                    Tag5 = GetCellValue<string>(row, columns, "Tag5"),
                };
                data.Add(importdata);
            }
            logger.LogInformation($"{sheet.SheetName}共有{sheet.LastRowNum}行数据，读取到{data.Count}条记录");
            if (data == null || !data.Any(t => !string.IsNullOrEmpty(t.UnitType) && !string.IsNullOrEmpty(t.AccountingUnit))) return;

            var dateTime = DateTime.Now;
            data.ForEach(t =>
            {
                t.HospitalId = hospitalId;
                t.CreateTime = dateTime;
            });

            reportperformancepersontagsRepository.DeleteFromQuery(t => t.HospitalId == hospitalId);
            reportperformancepersontagsRepository.BulkInsert(data.Where(t => !string.IsNullOrEmpty(t.PersonnelName) && !string.IsNullOrEmpty(t.PersonnelNumber)));
        }

        private List<string> GetColumns(ISheet sheet, string sheetName, out string sourceType)
        {
            sourceType = "";
            foreach (var item in sourceTypes)
            {
                if (item.Value.Contains(sheetName))
                {
                    sourceType = item.Key;
                    break;
                }
            }

            //if (string.IsNullOrEmpty(sourceType)) return new List<string>(); ;

            var columnRow = sheet.GetOrCreate(0);
            return columnRow.GetCellValues();
        }

        private T GetCellValue<T>(IRow row, List<string> columns, string key)
        {
            if (columns.Contains(key) && row.GetCell(columns.IndexOf(key)) != null)
                return row.GetCell(columns.IndexOf(key)).GetCellValue<T>();

            return default;
        }

        private readonly Dictionary<string, string[]> sourceTypes = new Dictionary<string, string[]>
        {
            { "收入", new string[] { "门诊收入", "住院收入" } },
            { "医生工作量", new string[] { "门诊人次", "出院人次", "手术概况", "住院天数", "实际开放总床日数" } },
            { "医技工作量", new string[] { "医技工作量" } },
            { "支出", new string[] { "支出" } },
        };

        #endregion ImportFile && SaveData

        #region 人员、科室标签配置

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

            var data = reportperformancepersontagsRepository.GetEntities(t => t.HospitalId == hospitalId)?.OrderBy(t=>Convert.ToInt32(t.PersonnelNumber));
            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);

                var cells = (from conf in PersonTag 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 SaveReportPersonTag(int hospitalId, SaveCollectData request)
        {
            var dicData = CreateDataRow(hospitalId, request, PersonTag);

            List<report_performance_person_tags> personTags = new List<report_performance_person_tags>();
            foreach (var item in dicData)
            {
                var json = JsonHelper.Serialize(item);
                var data = JsonHelper.Deserialize<report_performance_person_tags>(json);
                if (!string.IsNullOrEmpty(data.UnitType) && !string.IsNullOrEmpty(data.AccountingUnit) && !string.IsNullOrEmpty(data.PersonnelName) && !string.IsNullOrEmpty(data.PersonnelNumber) && !string.IsNullOrEmpty(data.Tag1) && !string.IsNullOrEmpty(data.Tag2))
                {
                    data.CreateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    personTags.Add(data);
                }
            }

            reportperformancepersontagsRepository.Execute("delete from report_performance_person_tags where HospitalId=@hospitalId", new { hospitalId });
            reportperformancepersontagsRepository.AddRange(personTags.ToArray());
        }

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

            var data = reportperformancetagsRepository.GetEntities(t => t.HospitalId == hospitalId)?.OrderBy(t=>t.UnitType);
            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);

                var cells = (from conf in ReportTag 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 SaveReportTag(int hospitalId, SaveCollectData request)
        {
            var dicData = CreateDataRow(hospitalId, request, PersonTag);

            List<report_performance_tags> report = new List<report_performance_tags>();
            foreach (var item in dicData)
            {
                var json = JsonHelper.Serialize(item);
                var data = JsonHelper.Deserialize<report_performance_tags>(json);
                if (!string.IsNullOrEmpty(data.UnitType) && !string.IsNullOrEmpty(data.AccountingUnit) && !string.IsNullOrEmpty(data.Tag1) && !string.IsNullOrEmpty(data.Tag2))
                {
                    data.CreateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    report.Add(data);
                }
            }

            reportperformancetagsRepository.Execute("delete from report_performance_tags where HospitalId=@hospitalId", new { hospitalId });
            reportperformancetagsRepository.AddRange(report.ToArray());
        }

        private static Dictionary<string, string> PersonTag { get; } = new Dictionary<string, string>
        {
            {nameof(report_performance_person_tags.UnitType), "核算单元类型"},
            {nameof(report_performance_person_tags.AccountingUnit), "科室"},
            {nameof(report_performance_person_tags.PersonnelNumber), "工号"},
            {nameof(report_performance_person_tags.PersonnelName), "姓名"},
            {nameof(report_performance_person_tags.Tag1), "绩效发放情况"},
            {nameof(report_performance_person_tags.Tag2), "当月绩效权重"},
            {nameof(report_performance_person_tags.Tag3), "重点群体对比1"},
            {nameof(report_performance_person_tags.Tag4), "重点群体对比2"},
            {nameof(report_performance_person_tags.Tag5), "重点群体对比5"},
        };

        public static Dictionary<string, string> ReportTag { get; } = new Dictionary<string, string>
        {
            {nameof(report_performance_tags.UnitType), "核算单元类型"},
            {nameof(report_performance_tags.AccountingUnit), "科室"},
            {nameof(report_performance_tags.Tag1), "绩效发放情况"},
            {nameof(report_performance_tags.Tag2), "当月绩效权重"},
            {nameof(report_performance_tags.Tag3), "重点群体对比1"},
            {nameof(report_performance_tags.Tag4), "重点群体对比2"},
            {nameof(report_performance_tags.Tag5), "重点群体对比5"},
        };

        private List<Dictionary<string, string>> CreateDataRow(int hospitalId, 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.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;
        }
        #endregion
    }
}
