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
{
    public class AssessService : IAutoInjection
    {
        private PerforAsassessRepository perforAsassessRepository;
        private PerforAsdataRepository perforAsdataRepository;
        private PerforAscolumnsRepository perforAscolumnsRepository;
        private PerforAstempassessRepository perforAstempassessRepository;
        private PerforAstempcolumnsRepository perforAstempcolumnsRepository;
        private PerforPerallotRepository perforPerallotRepository;
        private PerforImemployeeRepository perforImemployeeRepository;
        private PerforImaccountbasicRepository perforImaccountbasicRepository;
        public AssessService(PerforAsassessRepository perforAsassessRepository,
            PerforAsdataRepository perforAsdataRepository,
            PerforAscolumnsRepository perforAscolumnsRepository,
            PerforAstempassessRepository perforAstempassessRepository,
            PerforAstempcolumnsRepository perforAstempcolumnsRepository,
            PerforPerallotRepository perforPerallotRepository,
            PerforImemployeeRepository perforImemployeeRepository,
            PerforImaccountbasicRepository perforImaccountbasicRepository)
        {
            this.perforAsassessRepository = perforAsassessRepository;
            this.perforAsdataRepository = perforAsdataRepository;
            this.perforAscolumnsRepository = perforAscolumnsRepository;
            this.perforAstempassessRepository = perforAstempassessRepository;
            this.perforAstempcolumnsRepository = perforAstempcolumnsRepository;
            this.perforPerallotRepository = perforPerallotRepository;
            this.perforImemployeeRepository = perforImemployeeRepository;
            this.perforImaccountbasicRepository = perforImaccountbasicRepository;
        }

        #region 考核类别
        /// <summary>
        /// 考核类别列表
        /// </summary>
        /// <param name="allotID"></param>
        /// <returns></returns>
        public ApiResponse AssessList(int allotID)
        {
            var list = perforAsassessRepository.GetEntities(t => t.AllotID == allotID);
            return new ApiResponse(ResponseType.OK, list);
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="allotID"></param>
        /// <param name="assessName"></param>
        /// <returns></returns>
        public ApiResponse AddAssess(int allotID, string assessName)
        {
            var entity = perforAsassessRepository.GetEntities(t => t.AllotID == allotID && t.AssessName == assessName);
            if (entity != null && entity.Count > 0)
                return new ApiResponse(ResponseType.Fail, "考核类别重复");
            var assess = new as_assess { AllotID = allotID, AssessName = assessName };
            var result = perforAsassessRepository.Add(assess);
            return result ? new ApiResponse(ResponseType.OK, assess) : new ApiResponse(ResponseType.Fail);
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="assessID"></param>
        /// <param name="assessName"></param>
        /// <returns></returns>
        public ApiResponse EditAssess(int assessID, string assessName)
        {
            var entity = perforAsassessRepository.GetEntity(t => t.ID == assessID);
            if (entity == null)
                return new ApiResponse(ResponseType.Fail, "考核类别ID无效");
            entity.AssessName = assessName;

            var result = perforAsassessRepository.Update(entity);
            return result ? new ApiResponse(ResponseType.OK, entity) : new ApiResponse(ResponseType.Fail);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="assessID"></param>
        /// <returns></returns>
        public ApiResponse DelAssess(int assessID)
        {
            var entity = perforAsassessRepository.GetEntity(t => t.ID == assessID);
            if (entity == null)
                return new ApiResponse(ResponseType.Fail, "考核类别ID无效");

            var result = perforAsassessRepository.Remove(entity);
            var columns = perforAscolumnsRepository.GetEntities(t => t.AssessID == assessID);
            if (result && columns != null && columns.Count > 0)
                result = perforAscolumnsRepository.RemoveRange(columns.ToArray());
            return result ? new ApiResponse(ResponseType.OK) : new ApiResponse(ResponseType.Fail);
        }

        /// <summary>
        /// 科室考核类别归纳
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public ApiResponse SetAssessType(SetAssessRequest request)
        {
            var entity = perforAsassessRepository.GetEntity(t => t.ID == request.AssessID);
            if (entity == null)
                return new ApiResponse(ResponseType.Fail, "考核类别ID无效");

            var entities = perforAsdataRepository.GetEntities(t => t.AllotID == request.AllotID);
            if (entities != null)
            {
                //保留共有
                var intersectList = entities.Where(t => t.AssessID == request.AssessID).Select(t => t.Department).Intersect(request.Department).ToList();
                if (intersectList != null && intersectList.Count() > 0)
                    intersectList.ForEach(t => request.Department.Remove(t));
                //删除更改
                var removeList = perforAsdataRepository.GetEntities(t => !intersectList.Contains(t.Department) && t.AssessID == request.AssessID);
                if (removeList != null && removeList.Count() > 0)
                    perforAsdataRepository.RemoveRange(removeList.ToArray());
            }
            //添加新增
            var addList = request.Department.Select(t => new as_data { AllotID = request.AllotID, AssessID = request.AssessID, Department = t }).ToArray();
            var result = (addList != null && addList.Count() > 0) ? perforAsdataRepository.AddRange(addList) : true;

            return result ? new ApiResponse(ResponseType.OK) : new ApiResponse(ResponseType.Fail);
        }
        #endregion

        #region 考核项
        /// <summary>
        /// 列头列表
        /// </summary>
        /// <param name="assessID"></param>
        /// <returns></returns>
        public ApiResponse ColumnList(int assessID)
        {
            var list = perforAscolumnsRepository.GetEntities(t => t.AssessID == assessID).OrderBy(t => t.ParentID).ThenBy(t => t.Sort);
            return new ApiResponse(ResponseType.OK, list);
        }

        /// <summary>
        /// 新增考核项
        /// </summary>
        /// <param name="assessID"></param>
        /// <param name="parentID"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public ApiResponse AddColumn(int assessID, int parentID, string columnName, int sort)
        {
            var entity = perforAsassessRepository.GetEntity(t => t.ID == assessID);
            if (entity == null)
                return new ApiResponse(ResponseType.Fail, "考核类别ID无效");
            if (parentID > 0)
            {
                var centity = perforAscolumnsRepository.GetEntity(t => t.ID == parentID);
                if (centity == null)
                    return new ApiResponse(ResponseType.Fail, "考核项目父级ID无效");
            }
            var clist = perforAscolumnsRepository.GetEntities(t => t.ParentID == parentID && t.AssessID == assessID && t.Sort >= sort).OrderBy(t => t.Sort).ToList();
            if (clist != null && clist.Count > 0)
            {
                int atsort = sort;
                clist.ForEach(t => { t.Sort = atsort + 1; atsort++; });
                perforAscolumnsRepository.UpdateRange(clist.ToArray());
            }
            var column = new as_columns { AssessID = assessID, ParentID = parentID, ColumnName = columnName, Sort = sort };
            var result = perforAscolumnsRepository.Add(column);
            return result ? new ApiResponse(ResponseType.OK, column) : new ApiResponse(ResponseType.Fail);
        }

        /// <summary>
        /// 修改考核项
        /// </summary>
        /// <param name="columnID"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public ApiResponse EditColumn(int columnID, string columnName, int sort)
        {
            var entity = perforAscolumnsRepository.GetEntity(t => t.ID == columnID);
            if (entity == null)
                return new ApiResponse(ResponseType.Fail, "考核项目父级ID无效");
            entity.ColumnName = columnName;
            //entity.Sort = sort;
            var result = perforAscolumnsRepository.Update(entity);
            return result ? new ApiResponse(ResponseType.OK, entity) : new ApiResponse(ResponseType.Fail);
        }

        /// <summary>
        /// 删除考核项
        /// </summary>
        /// <param name="columnID"></param>
        /// <returns></returns>
        public ApiResponse DelColumn(int columnID)
        {
            var entity = perforAscolumnsRepository.GetEntity(t => t.ID == columnID);
            if (entity == null)
                return new ApiResponse(ResponseType.Fail, "考核项目父级ID无效");

            var result = perforAscolumnsRepository.Remove(entity);
            return result ? new ApiResponse(ResponseType.OK) : new ApiResponse(ResponseType.Fail);
        }
        #endregion

        #region 考核数据

        /// <summary>
        /// 考核数据列表
        /// </summary>
        /// <param name="assessID"></param>
        /// <returns></returns>
        public ApiResponse DataList(int assessID)
        {
            var entity = perforAsassessRepository.GetEntity(t => t.ID == assessID);
            if (entity == null)
                return new ApiResponse(ResponseType.Fail, "考核类别ID无效");

            var list = perforAsdataRepository.GetEntities(t => t.AssessID == assessID);
            if (list != null)
            {
                var response = list.Select(t => new AssessDataResponse
                {
                    ID = t.ID,
                    AssessID = t.AssessID,
                    Department = t.Department,
                    RowData = t.RowData
                });
                return new ApiResponse(ResponseType.OK, response);
            }
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 编辑考核数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public ApiResponse EditAssessData(List<AssessRow> request)
        {
            var dataIDList = request.Select(t => t.DataID).ToList();
            var dataList = perforAsdataRepository.GetEntities(t => dataIDList.Contains(t.ID));
            foreach (var item in request)
            {
                var entity = dataList.FirstOrDefault(t => t.ID == item.DataID);
                if (entity != null)
                {
                    entity.RowData = item.DataValue;
                    perforAsdataRepository.Update(entity);
                }
            }
            return new ApiResponse(ResponseType.OK);
        }
        #endregion

        #region 模版
        /// <summary>
        /// 考核模版列表
        /// </summary>
        /// <param name="allotID"></param>
        /// <returns></returns>
        public ApiResponse TempAssessList()
        {
            var list = perforAstempassessRepository.GetEntities();
            return new ApiResponse(ResponseType.OK, list);
        }

        /// <summary>
        /// 模版列头列表
        /// </summary>
        /// <param name="assessID"></param>
        /// <returns></returns>
        public ApiResponse TempColumnList(int assessID)
        {
            var list = perforAstempcolumnsRepository.GetEntities(t => t.AssessID == assessID)?.OrderBy(t => t.ParentID).ThenBy(t => t.Sort);
            return new ApiResponse(ResponseType.OK, list);
        }

        /// <summary>
        /// 使用模版
        /// </summary>
        /// <returns></returns>
        public ApiResponse UseTemplate(int allotID, int assessID)
        {
            var allot = perforPerallotRepository.GetEntity(t => t.ID == allotID);
            var temp = perforAstempassessRepository.GetEntity(t => t.ID == assessID);
            if (temp != null && allot != null)
            {
                string assessName = temp.AssessName;
                var assess = perforAsassessRepository.GetEntity(t => t.AssessName == assessName && t.AllotID == allotID);
                if (assess != null)
                    return new ApiResponse(ResponseType.Fail, "该模版已经被使用");
                assess = new as_assess
                {
                    AllotID = allotID,
                    AssessName = assessName
                };
                //copy模版信息
                var result = perforAsassessRepository.Add(assess);

                var tempColumns = perforAstempcolumnsRepository.GetEntities(t => t.AssessID == assessID);
                var columns = tempColumns?.Select(t => new as_columns
                {
                    AssessID = assess.ID,
                    ParentID = t.ParentID,
                    ColumnName = t.ColumnName,
                    TempColumnID = t.ID,
                    Sort = t.Sort
                }).ToList();
                //copy模版列头
                if (result && columns != null && columns.Count > 0)
                {
                    result = perforAscolumnsRepository.AddRange(columns.ToArray());
                    if (result)
                    {
                        var parentList = columns.Select(t => t.ParentID).Distinct();
                        var keyvalue = new Dictionary<int?, int>();
                        foreach (var item in columns.Where(t => parentList.Contains(t.TempColumnID)))
                        {
                            keyvalue.Add(item.TempColumnID, item.ID);
                        }
                        columns = columns.Where(t => t.ParentID.HasValue && t.ParentID != 0).ToList();
                        columns?.ForEach(t => t.ParentID = keyvalue[t.ParentID]);

                        result = perforAscolumnsRepository.UpdateRange(columns.ToArray());
                    }
                }
                return result ? new ApiResponse(ResponseType.OK) : new ApiResponse(ResponseType.Fail);
            }
            return allot == null ? new ApiResponse(ResponseType.Fail, "绩效ID无效") : new ApiResponse(ResponseType.Fail, "模版信息不存在");
        }
        #endregion

        /// <summary>
        /// 科室列表
        /// </summary>
        /// <returns></returns>
        public List<TitleValue> Department(AssessRequest request)
        {
            var allot = perforPerallotRepository.GetEntity(t => t.ID == request.AllotID);
            if (allot != null)
            {
                var result = new List<TitleValue>();
                //取到该家医院下所有科室
                var idList = perforPerallotRepository.GetEntities(t => t.HospitalId == allot.HospitalId).Select(s => s.ID).ToList();
                //var department = perforImaccountbasicRepository.GetEntities(t => t.Department != "" && idList.Contains(t.AllotID.Value))?.Select(t => t.Department).Distinct().ToList();
                //if (department != null && department.Count > 0)
                //{
                var department = perforImaccountbasicRepository.GetEntities(t => t.DoctorAccountingUnit != "" && idList.Contains(t.AllotID.Value))?.Select(t => t.DoctorAccountingUnit).Distinct().ToList();
                if (department != null && department.Count > 0)
                {
                    //自己选的
                    var _checked = perforAsdataRepository.GetEntities(t => t.AssessID == request.AssessID)?.Select(t => t.Department).ToList();
                    if (_checked != null && _checked.Count > 0)
                        result = _checked.Select(t => new TitleValue { Title = t, Value = t, State = 1 }).ToList();
                    //已经被选择
                    var assessId = perforAsassessRepository.GetEntities(t => t.AllotID == request.AllotID)?.Select(t => t.ID).ToList();
                    if (assessId.Count > 0 && assessId != null)
                    {
                        assessId.Remove(request.AssessID);
                        _checked = perforAsdataRepository.GetEntities(t => assessId.Contains(t.AssessID.Value))?.Select(t => t.Department).ToList();
                        if (_checked != null && _checked.Count > 0)
                        {
                            result = result.Union(_checked.Select(t => new TitleValue { Title = t, Value = t, State = 3 })).ToList();
                        }
                    }
                    //未被选择
                    if (result != null || result.Count > 0)
                        department = department.Except(result.Select(t => t.Title)).ToList();
                    result = result.Union(department.Select(t => new TitleValue { Title = t, Value = t, State = 2 })).OrderBy(t => t.State).ThenBy(t => t.Title).ToList();
                }
                return result;
            }
            return new List<TitleValue>();
        }
    }
}
