using AutoMapper;
using Microsoft.Extensions.Options;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.EntityModels;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Performance.Services
{
    public class SecondAllotService : IAutoInjection
    {
        private readonly Application application;
        private readonly PerforUserRepository perforUserRepository;
        private readonly PerforUserhospitalRepository perforUserhospitalRepository;
        private readonly PerforPerallotRepository perforPerallotRepository;
        private readonly PerforAgsecondallotRepository perforAgsecondallotRepository;
        private readonly PerforResaccountRepository perforResaccountRepository;
        private readonly PerforUserroleRepository userroleRepository;
        private readonly PerforAgworkloadRepository perforAgworkloadRepository;
        private readonly PerforAgtempRepository perforAgtempRepository;
        private readonly PerforAgtempitemRepository perforAgtempitemRepository;
        private readonly PerforAgfixatitemRepository perforAgfixatitemRepository;
        private readonly PerforAgusetempRepository perforAgusetempRepository;

        public SecondAllotService(IOptions<Application> application,
            PerforUserRepository perforUserRepository,
            PerforUserhospitalRepository perforUserhospitalRepository,
            PerforPerallotRepository perforPerallotRepository,
            PerforAgsecondallotRepository perforAgsecondallotRepository,
            PerforResaccountRepository perforResaccountRepository,
            PerforUserroleRepository userroleRepository,
            PerforAgworkloadRepository perforAgworkloadRepository,
            PerforAgtempRepository perforAgtempRepository,
           PerforAgtempitemRepository perforAgtempitemRepository,
           PerforAgfixatitemRepository perforAgfixatitemRepository,
           PerforAgusetempRepository perforAgusetempRepository)
        {
            this.application = application.Value;
            this.perforUserRepository = perforUserRepository;
            this.perforUserhospitalRepository = perforUserhospitalRepository;
            this.perforPerallotRepository = perforPerallotRepository;
            this.perforAgsecondallotRepository = perforAgsecondallotRepository;
            this.perforResaccountRepository = perforResaccountRepository;
            this.userroleRepository = userroleRepository;
            this.perforAgworkloadRepository = perforAgworkloadRepository;
            this.perforAgtempRepository = perforAgtempRepository;
            this.perforAgtempitemRepository = perforAgtempitemRepository;
            this.perforAgfixatitemRepository = perforAgfixatitemRepository;
            this.perforAgusetempRepository = perforAgusetempRepository;
        }

        /// <summary>
        /// 获取二次绩效列表
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<ag_secondallot> GetSecondList(int userId)
        {
            var user = perforUserRepository.GetEntity(t => t.ID == userId);
            if (user == null)
                throw new NotImplementedException("人员ID无效");
            var role = userroleRepository.GetEntity(t => t.UserID == userId);
            var hospital = perforUserhospitalRepository.GetEntity(t => t.UserID == userId);
            if (hospital == null)
                throw new NotImplementedException("人员未选择医院");
            var allotList = perforPerallotRepository.GetEntities(t => t.HospitalId == hospital.HospitalID && t.States == 6);
            if (allotList == null || allotList.Count == 0)
                throw new NotImplementedException("该医院未生成绩效");

            var allotListId = allotList.Select(t => t.ID).ToList();
            var secondList = perforAgsecondallotRepository.GetEntities(t => allotListId.Contains(t.AllotId.Value) && t.Department == user.Department);
            //各科室绩效分配结果
            var accountList = perforResaccountRepository.GetEntities(t => allotListId.Contains(t.AllotID.Value) && t.Department == user.Department);
            //取得未生成二次绩效的绩效id  
            var exceptListId = secondList == null ? allotListId : allotListId.Except(secondList.Select(t => t.AllotId.Value));

            #region 初始化二次绩效
            List<ag_secondallot> newSecond = new List<ag_secondallot>();
            foreach (var item in exceptListId)
            {
                var allot = allotList.FirstOrDefault(t => t.ID == item);
                if (allot == null) continue;

                res_account account = null;
                if (role.RoleID == application.DirectorRole)
                    account = accountList.FirstOrDefault(t => t.AllotID == item && (t.UnitType == (int)UnitType.医生组 || t.UnitType == (int)UnitType.医技组));
                else if (role.RoleID == application.NurseRole)
                    account = accountList.FirstOrDefault(t => t.AllotID == item && t.UnitType == (int)UnitType.护理组);

                if (account == null) continue;

                var second = new ag_secondallot
                {
                    AllotId = item,
                    Year = allot.Year,
                    Month = allot.Month,
                    Department = user.Department,
                    UnitType = ((UnitType)account.UnitType).ToString(),
                    RealGiveFee = account.RealGiveFee
                };
                newSecond.Add(second);
            }
            #endregion

            if (newSecond.Count > 0)
            {
                perforAgsecondallotRepository.AddRange(newSecond.ToArray());
                if (secondList == null)
                    secondList = newSecond;
                else
                    secondList.AddRange(newSecond);
            }

            return secondList;
        }

        /// <summary>
        /// 获取模板列表
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<ag_temp> GetTemp(int userId)
        {
            return perforAgtempRepository.GetEntities();
        }

        /// <summary>
        /// 使用模板
        /// </summary>
        /// <param name="tempId"></param>
        /// <returns></returns>
        public bool UseTemp(UseTempRequest request)
        {
            var temp = perforAgtempRepository.GetEntity(t => t.Id == request.TempId);
            if (temp == null)
                throw new PerformanceException("参数tempId 无效");

            var entity = Mapper.Map<ag_usetemp>(request);
            return perforAgusetempRepository.Add(entity);
        }

        /// <summary>
        /// 应用模板
        /// </summary>
        /// <returns></returns>
        public void RefreshTemp(int secondId)
        {
            var fixatList = perforAgfixatitemRepository.GetEntities(t => t.SecondId == secondId);
            if (fixatList == null || fixatList.Count == 0)
                throw new PerformanceException("参数secondId 无效");


        }

        /// <summary>
        /// 获取工作量列表
        /// </summary>
        /// <param name="secondId"></param>
        /// <returns></returns>
        public List<ag_workload> GetWorkloadList(WorkloadRequest request)
        {
            return perforAgworkloadRepository.GetEntities(t => t.HospitalId == request.HospitalId && t.Department == request.Department && t.UnitType == request.Department);
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool WorkloadAdd(WorkloadRequest request)
        {
            var workloadList = perforAgworkloadRepository.GetEntities(t => t.HospitalId == request.HospitalId && t.Department == request.Department && t.UnitType == request.Department);
            if (workloadList.Any(t => t.ItemName == request.ItemName))
                throw new PerformanceException("项目名称重复");
            ag_workload workload = new ag_workload
            {
                HospitalId = request.HospitalId,
                Department = request.Department,
                UnitType = request.UnitType,
                FactorValue = request.FactorValue ?? 1,
                ItemName = request.ItemName,
                Sort = request.Sort ?? 1,
            };
            var result = perforAgworkloadRepository.Add(workload);
            if (result)
            {
                workload.ItemId = $"Feild{workload.Id}";
                perforAgworkloadRepository.Update(workload);
            }

            return result;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool WorkloadUpdate(WorkloadRequest request)
        {
            var workloadList = perforAgworkloadRepository.GetEntities(t => t.HospitalId == request.HospitalId && t.Department == request.Department && t.UnitType == request.Department);
            if (workloadList.Any(t => t.Id != request.Id && t.ItemName == request.ItemName))
                throw new PerformanceException("项目名称重复");

            var workload = workloadList.FirstOrDefault(t => t.Id == request.Id);
            workload.HospitalId = request.HospitalId;
            workload.Department = request.Department;
            workload.UnitType = request.UnitType;
            workload.FactorValue = request.FactorValue;
            workload.ItemName = request.ItemName;
            workload.Sort = request.Sort;
            workload.ItemId = $"Feild{workload.Id}";

            return perforAgworkloadRepository.Update(workload);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool WorkloadDelete(int id)
        {
            var workload = perforAgworkloadRepository.GetEntity(t => t.Id == id);
            return perforAgworkloadRepository.Remove(workload);
        }

        public void GetHeader()
        {

        }

        public void SaveValue(FixatItemRequest request)
        {
            if (request.FixatItems == null || request.FixatItems.Count == 0)
                throw new PerformanceException("保存的内容为空");

            #region 添加新的值
            var addItem = request.FixatItems.Where(t => t.FixatId == 0).ToList();
            if (addItem != null && addItem.Count() > 0)
            {
                var newFixat = addItem.Select(t => new ag_fixatitem
                {
                    AllotId = request.AllotId,
                    SecondId = request.SecondId,
                    UnitType = request.UnitType,
                    RowNumber = request.RowNumber,
                    ItemName = t.ItemName,
                    ItemValue = t.ItemValue,
                    FactorValue = t.FactorValue,
                    Sort = t.Sort,
                    Type = t.Type,
                    SourceType = t.SourceType
                });

                if (newFixat != null && newFixat.Count() > 0)
                    perforAgfixatitemRepository.AddRange(newFixat.ToArray());
            }
            #endregion

            #region 更新原始值
            var updateItme = request.FixatItems.Where(t => t.FixatId >= 0).ToList();
            if (updateItme != null && updateItme.Count() > 0)
            {
                var fixatIds = updateItme.Select(t => t.FixatId);
                var oldFixat = perforAgfixatitemRepository.GetEntities(t => fixatIds.Contains(t.Id));
                if (oldFixat != null && oldFixat.Count > 0)
                {
                    oldFixat.ForEach(t =>
                    {
                        var fixat = updateItme.Where(s => s.FixatId == t.Id).FirstOrDefault();
                        t.ItemName = fixat.ItemName;
                        t.ItemValue = fixat.ItemValue;
                        t.FactorValue = fixat.FactorValue;
                        t.Sort = fixat.Sort;
                        t.Type = fixat.Type;
                        t.SourceType = fixat.SourceType;
                    });
                    perforAgfixatitemRepository.AddRange(oldFixat.ToArray());
                }
            }
            #endregion

        }
    }
}
