using Dapper;
using Microsoft.Extensions.Logging;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Performance.Services.ExtractExcelService
{
    public class DictionaryService : IAutoInjection
    {
        private readonly ILogger<DictionaryService> logger;
        private readonly QueryService queryService;
        private readonly LogManageService logService;
        private readonly PerforPeremployeeRepository peremployeeRepository;
        private readonly PerforHospitalconfigRepository hospitalconfigRepository;
        private readonly PerforExtypeRepository extypeRepository;
        private readonly PerforExscriptRepository exscriptRepository;
        private readonly PerforHisdataRepository hisdataRepository;
        private readonly PerforHisscriptRepository hisscriptRepository;

        public DictionaryService(
            ILogger<DictionaryService> logger,
            QueryService queryService,
            LogManageService logService,
            PerforPeremployeeRepository peremployeeRepository,
            PerforHospitalconfigRepository hospitalconfigRepository,
            PerforExtypeRepository extypeRepository,
            PerforExscriptRepository exscriptRepository,
            PerforHisdataRepository hisdataRepository,
            PerforHisscriptRepository hisscriptRepository
            )
        {
            this.logger = logger;
            this.queryService = queryService;
            this.logService = logService;
            this.peremployeeRepository = peremployeeRepository;
            this.hospitalconfigRepository = hospitalconfigRepository;
            this.extypeRepository = extypeRepository;
            this.exscriptRepository = exscriptRepository;
            this.hisdataRepository = hisdataRepository;
            this.hisscriptRepository = hisscriptRepository;
        }

        public void Handler(int hospitalId, per_allot allot, string groupName, bool isSingle)
        {
            try
            {
                var configs = hospitalconfigRepository.GetEntities(t => t.HospitalId == hospitalId);
                if (configs == null || !configs.Any()) throw new Exception("医院未配置绩效抽取信息");

                var types = extypeRepository.GetEntities(t => t.HospitalId == hospitalId && new int[] { 2 }.Contains(t.Source));
                if (types != null && types.Any())
                {
                    logService.ReturnTheLog(allot.ID, groupName, 2, "提取数据", $"提取人员信息数据", isSingle: isSingle);
                    var scripts = exscriptRepository.GetEntities(t => types.Select(s => s.Id).Contains(t.TypeId) && t.IsEnable == 1);
                    if (scripts != null && scripts.Any())
                    {
                        if (types.Any(t => t.Source == (int)SheetType.Employee))    //人员字典抽取配置
                        {
                            var typeIds = types.Where(t => t.Source == (int)SheetType.Employee).Select(t => t.Id);
                            var script = scripts.FirstOrDefault(t => typeIds.Contains(t.TypeId));
                            if (script != null)
                                Employee(allot, configs.FirstOrDefault(t => t.Id == script.ConfigId), script.ExecScript);
                        }
                    }
                }

                var hisScrips = hisscriptRepository.GetEntities(t => t.HospitalId == hospitalId);
                if (hisScrips == null || !hisScrips.Any()) return;
                foreach (var item in hisScrips)
                {
                    logService.ReturnTheLog(allot.ID, groupName, 2, "提取数据", $"提取{item.SourceType} - {item.Category}数据", isSingle: isSingle);
                    HisData(allot, configs.FirstOrDefault(t => t.Id == item.ConfigId), item);
                }
            }
            catch (Exception ex)
            {
                logger.LogError("获取数据时发生异常");
                throw ex;
            }
        }

        private void Employee(per_allot allot, sys_hospitalconfig config, string sql)
        {
            try
            {
                if (config == null || string.IsNullOrEmpty(sql)) return;

                var data = queryService.QueryData<per_employee>(config, allot, sql);
                if (data == null || !data.Any()) return;

                var employees = peremployeeRepository.GetEntities(t => t.AllotId == allot.ID);
                if (employees != null && employees.Any())
                {
                    peremployeeRepository.RemoveRange(employees.ToArray());
                }

                data.ToList().ForEach(t =>
                {
                    t.AllotId = allot.ID;
                    t.HospitalId = allot.HospitalId;
                });
                peremployeeRepository.AddRange(data.ToArray());
            }
            catch (Exception ex)
            {
                logger.LogError("获取人员名单时发生异常：" + ex.ToString());
            }
        }

        private void HisData(per_allot allot, sys_hospitalconfig config, his_script script)
        {
            try
            {
                if (config == null || string.IsNullOrEmpty(script.ExecScript)) return;

                var data = queryService.QueryData<HisData>(config, allot, script.ExecScript);
                if (data == null || !data.Any()) return;

                var hisdata = hisdataRepository.GetEntities(t => t.AllotId == allot.ID && t.SourceType == script.SourceType && t.Category == script.Category);
                if (hisdata != null && hisdata.Any())
                {
                    hisdataRepository.RemoveRange(hisdata.ToArray());
                }

                var insertData = data.Select(t => new his_data
                {
                    HospitalId = allot.HospitalId,
                    AllotId = allot.ID,
                    Year = allot.Year,
                    Month = allot.Month,
                    HisDepartment = GetSaveValue(t.HisDepartment, t.Department, t.AccountingUnit),
                    PersonnelName = t.DoctorName,
                    PersonnelNumber = GetSaveValue(t.PersonnelNumber, t.DoctorName),
                    SourceType = script.SourceType,
                    Category = script.Category,
                    Original = GetSaveValue(t.Category, t.ItemName, t.Original),
                    Value = t.Value,
                    CreateTime = DateTime.Now,
                });
                hisdataRepository.AddRange(insertData.ToArray());
            }
            catch (Exception ex)
            {
                logger.LogError("获取his_data时发生异常：" + ex.ToString());
            }
        }

        private void Department()
        {
        }

        private string GetSaveValue(params string[] arr)
        {
            string value = string.Empty;
            if (arr == null || !arr.Any())
                return value;
            return arr.FirstOrDefault(w => !string.IsNullOrEmpty(w));
        }
    }
}
