using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Services;
using Performance.Services.AllotCompute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Performance.Api.Controllers
{
    /// <summary>
    /// 二次绩效
    /// </summary>
    [ApiController]
    public class SecondAllotController : ControllerBase
    {
        private readonly ClaimService claimService;
        private readonly SecondAllotService secondAllotService;
        private readonly ResultComputeService resultComputeService;
        private readonly SecondAllotDetails secondAllotDetails;

        public SecondAllotController(
            ClaimService claimService,
            SecondAllotService secondAllotService,
            ResultComputeService resultComputeService,
            SecondAllotDetails secondAllotDetails
            )
        {
            this.claimService = claimService;
            this.secondAllotService = secondAllotService;
            this.resultComputeService = resultComputeService;
            this.secondAllotDetails = secondAllotDetails;
        }

        #region 二次绩效列表、录入数据展示，保存数据

        /// <summary>
        /// 二次绩效列表（没有需要初始化）
        /// </summary>
        /// <returns></returns>
        [Route("api/second/list")]
        [HttpPost]
        public ApiResponse List()
        {
            var userId = claimService.GetUserId();
            var result = secondAllotService.GetSecondList(userId);
            if (result != null && result.Any())
                result = result.OrderByDescending(t => t.Year).ThenByDescending(t => t.Month).ToList();
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 二次绩效项目内容保存
        /// </summary>
        /// <returns></returns>
        [Route("api/second/savevalue/{secondid}")]
        [HttpPost]
        public ApiResponse SaveValue(int secondid, [FromBody] List<ag_fixatitem> request)
        {
            //if (secondid != 0 && (request == null || request.Count == 0))
            //    secondAllotService.DelValue(secondid, request);

            var allotCount = request.Where(t => t.AllotId > 0).Select(t => t.AllotId).Distinct().Count();
            if (allotCount != 1 || request.Any(t => t.AllotId == 0))
                throw new PerformanceException("一次绩效ID错误");

            var secondCount = request.Where(t => t.SecondId > 0).Select(t => t.SecondId).Distinct().Count();
            if (secondCount != 1 || request.Any(t => t.SecondId == 0))
                throw new PerformanceException("二次绩效ID错误");

            var typeCount = request.Where(t => t.Type > 0).Select(t => t.Type).Distinct().Count();
            if (request.Any(t => t.Type == 0)) //typeCount != 1 ||
                throw new PerformanceException("二次绩效项位置错误");

            var unitTypeCount = request.Where(t => !string.IsNullOrEmpty(t.UnitType)).Select(t => t.UnitType).Distinct().Count();
            if (unitTypeCount != 1 || request.Any(t => string.IsNullOrEmpty(t.UnitType)))
                throw new PerformanceException("科室类型错误");

            var repetition = request.GroupBy(t => new { t.RowNumber, t.ItemName /*, WorkType = t.WorkType ?? 0*/ }).Where(t => t.Count() > 1);
            if (repetition.Any())
                throw new PerformanceException(string.Join(";", repetition.Select(t => $"行{t.Key.RowNumber}项‘{t.Key.ItemName}’重复录入")));

            var result = secondAllotService.SaveValue(request, secondid);
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 提交二次绩效分配结果
        /// </summary>
        /// <returns></returns>
        [Route("api/second/savecompute")]
        [HttpPost]
        public ApiResponse SaveCompute([FromBody] List<ag_compute> request)
        {
            var allotCount = request.Where(t => t.AllotId > 0).Select(t => t.AllotId).Distinct().Count();
            if (allotCount != 1 || request.Any(t => t.AllotId == 0))
                throw new PerformanceException("一次绩效ID错误");

            var secondCount = request.Where(t => t.SecondId > 0).Select(t => t.SecondId).Distinct().Count();
            if (secondCount != 1 || request.Any(t => t.SecondId == 0))
                throw new PerformanceException("二次绩效ID错误");

            var departmentCount = request.Where(t => !string.IsNullOrEmpty(t.Department)).Select(t => t.Department).Distinct().Count();
            if (departmentCount != 1 || request.Any(t => string.IsNullOrEmpty(t.Department)))
                throw new PerformanceException("科室名称错误");

            var personNameCount = request.Where(t => !string.IsNullOrEmpty(t.PersonName)).Select(t => t.PersonName).Distinct().Count();
            if (personNameCount != 1 || request.Any(t => string.IsNullOrEmpty(t.PersonName)))
                throw new PerformanceException("人员名称错误");

            var result = secondAllotService.SaveCompute(request);
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 二次绩效录入页面配置信息
        /// </summary>
        /// <returns></returns>
        [Route("api/second/detail")]
        [HttpPost]
        public ApiResponse SecondDetail([CustomizeValidator(RuleSet = "Refresh"), FromBody] UseTempRequest request)
        {
            //var result = secondAllotService.GetSecondDetail(request, claimService.GetUserId());
            var result = secondAllotDetails.GetSecondDetails(claimService.GetUserId(), request.SecondId, request.HospitalId, request.IsArchive, request.EmployeeSource);
            return new ApiResponse(ResponseType.OK, result);
        }

        ///// <summary>
        ///// 二次绩效录入页面配置信息
        ///// </summary>
        ///// <returns></returns>
        //[Route("api/second/otherdetail/{secondid}")]
        //[HttpPost]
        //public ApiResponse SecondOtherDetail(int secondid)
        //{
        //    var result = secondAllotService.GetSecondDetail(secondid);
        //    return new ApiResponse(ResponseType.OK, result);
        //}

        #endregion 二次绩效列表、录入数据展示，保存数据

        /// <summary>
        /// 二次绩效录入页面自动补全
        /// </summary>
        /// <returns></returns>
        [Route("api/second/autocomplete")]
        [HttpPost]
        public ApiResponse AutoComplete([FromBody] SecondEmpRequest request)
        {
            var result = secondAllotService.AutoComplete(request, claimService.GetUserId());
            //var result = secondAllotService.AutoComplete(request.SecondId, request.JobNumber);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 二次绩效录入页面其他模板自动补全
        /// </summary>
        /// <returns></returns>
        [Route("api/second/other/autocomplete")]
        [HttpPost]
        public ApiResponse OtherAutoComplete([FromBody] SecondEmpRequest request)
        {
            var result = secondAllotService.OtherAutoComplete(request, claimService.GetUserId());
            return new ApiResponse(ResponseType.OK, result);
        }

        #region 模板使用

        /// <summary>
        /// 选择二次绩效模板
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("api/temp/list")]
        public ApiResponse<List<SecondTempResponse>> Temp([FromBody] AllotDeptRequest request)
        {
            var userId = claimService.GetUserId();
            var result = secondAllotService.GetTemp(request.HospitalId, request.Department, userId);
            return new ApiResponse<List<SecondTempResponse>>(ResponseType.OK, result);
        }

        /// <summary>
        /// 保存已选择二次绩效模板
        /// </summary>
        /// <returns></returns>
        [Route("api/temp/usetemp")]
        [HttpPost]
        public ApiResponse UseTemp([CustomizeValidator(RuleSet = "Use"), FromBody] UseTempRequest request)
        {
            var result = secondAllotService.UseTemp(request);
            return result ? new ApiResponse(ResponseType.OK, "选择成功") : new ApiResponse(ResponseType.Fail, "选择失败");
        }

        /// <summary>
        /// 刷新已选择模板
        /// </summary>
        /// <returns></returns>
        [Route("api/second/refreshtemp")]
        [HttpPost]
        public ApiResponse RefreshTemp([CustomizeValidator(RuleSet = "Refresh"), FromBody] UseTempRequest request)
        {
            secondAllotService.RefreshTemp(request);
            return new ApiResponse(ResponseType.OK);
        }

        #endregion 模板使用

        #region 二次绩效工作量配置

        /// <summary>
        /// 二次绩效工作量列表
        /// </summary>
        /// <returns></returns>
        [Route("api/second/workload/list")]
        [HttpPost]
        public ApiResponse WorkloadList([CustomizeValidator(RuleSet = "Query"), FromBody] WorkloadRequest request)
        {
            var result = secondAllotService.GetWorkloadList(request);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 二次绩效工作量新增
        /// </summary>
        /// <returns></returns>
        [Route("api/second/workload/add")]
        [HttpPost]
        public ApiResponse WorkloadAdd([CustomizeValidator(RuleSet = "Add"), FromBody] WorkloadRequest request)
        {
            var result = secondAllotService.WorkloadAdd(request);
            return new ApiResponse(result ? ResponseType.OK : ResponseType.Fail);
        }

        /// <summary>
        /// 二次绩效工作量修改
        /// </summary>
        /// <returns></returns>
        [Route("api/second/workload/update")]
        [HttpPost]
        public ApiResponse WorkloadUpdate([CustomizeValidator(RuleSet = "Update"), FromBody] WorkloadRequest request)
        {
            var result = secondAllotService.WorkloadUpdate(request);
            return new ApiResponse(result ? ResponseType.OK : ResponseType.Fail);
        }

        /// <summary>
        /// 二次绩效工作量删除
        /// </summary>
        /// <returns></returns>
        [Route("api/second/workload/delete")]
        [HttpPost]
        public ApiResponse WorkloadDelete([CustomizeValidator(RuleSet = "Delete"), FromBody] WorkloadRequest request)
        {
            var result = secondAllotService.WorkloadDelete(request.Id);
            return new ApiResponse(result ? ResponseType.OK : ResponseType.Fail);
        }

        /// <summary>
        /// 二次绩效单例奖励列表
        /// </summary>
        /// <returns></returns>
        [Route("api/second/single/list")]
        [HttpPost]
        public ApiResponse SingleAwards([FromBody] WorkloadRequest request)
        {
            var result = secondAllotService.GetSingleList(request);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 二次绩效工作量类型列表
        /// </summary>
        /// <returns></returns>
        [Route("api/second/worktype/list")]
        [HttpPost]
        public ApiResponse WorkTypeList([FromBody] WorkloadRequest request)
        {
            var result = secondAllotService.WorkTypeList(request, claimService.GetUserId());
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 保存二次绩效工作量类型
        /// </summary>
        /// <returns></returns>
        [Route("api/second/worktype/save")]
        [HttpPost]
        public ApiResponse SingleSave([FromBody] ag_workload_type request)
        {
            if (request.HospitalId == 0)
                return new ApiResponse(ResponseType.ParameterError, "医院信息无效");
            if (string.IsNullOrEmpty(request.TypeName))
                return new ApiResponse(ResponseType.ParameterError, "填写参数无效");

            var result = secondAllotService.SaveWorkType(request, claimService.GetUserId());
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 删除二次绩效工作量类型
        /// </summary>
        /// <returns></returns>
        [Route("api/second/worktype/delete")]
        [HttpPost]
        public ApiResponse SingleDelete([CustomizeValidator(RuleSet = "Delete"), FromBody] WorkloadRequest request)
        {
            var result = secondAllotService.DeleteWorkType(request);
            return result ? new ApiResponse(ResponseType.OK, "删除成功") : new ApiResponse(ResponseType.Fail, "删除失败");
        }

        #endregion 二次绩效工作量配置

        #region 二次绩效审核

        /// <summary>
        /// 提交审核
        /// </summary>
        /// <param name="request">二次绩效Id</param>
        /// <returns></returns>
        [HttpPost]
        [Route("/api/second/audit/submit")]
        public ApiResponse SubmitAudit(SubmitAuditRequest request)
        {
            var second = secondAllotService.GetSecondallot(request.SecondId);
            if (second == null)
                return new ApiResponse(ResponseType.ParameterError, "二次绩效Id无效");
            if (second.Status == 3)
                return new ApiResponse(ResponseType.Fail, "该绩效已\"审核通过\",无需再次提交");

            var userid = claimService.GetUserId();
            var result = secondAllotService.AuditSubmit(second, userid);
            return result ? new ApiResponse(ResponseType.OK, "提交成功") : new ApiResponse(ResponseType.Fail, "提交失败");
        }

        /// <summary>
        /// 二次绩效审核列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("/api/second/audit/list")]
        public ApiResponse<List<ag_secondallot>> AuditList([FromBody] AllotDeptRequest request)
        {
            var list = secondAllotService.AuditList(request.AllotId);
            return new ApiResponse<List<ag_secondallot>>(ResponseType.OK, "审核列表", list);
        }

        /// <summary>
        /// 二次绩效审核结果;驳回、成功
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("/api/second/audit/result")]
        public ApiResponse AuditResult([FromBody] SecondAuditRequest request)
        {
            var userid = claimService.GetUserId();
            var result = secondAllotService.ConfirmAudit(userid, request);
            if (request.IsPass == 1)
            {
                resultComputeService.SaveSecondReserved(request.SecondId);
            }
            return result ? new ApiResponse(ResponseType.OK, "操作成功") : new ApiResponse(ResponseType.Fail, "操作失败");
        }

        /// <summary>
        /// 护理部二次绩效审核列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("/api/second/audit/nursingdept/list")]
        public ApiResponse<List<ag_secondallot>> NursingDeptlist([FromBody] AllotDeptRequest request)
        {
            var list = secondAllotService.NursingDeptlist(request.AllotId);
            return new ApiResponse<List<ag_secondallot>>(ResponseType.OK, "审核列表", list);
        }

        /// <summary>
        /// 护理部二次绩效审核结果;驳回、成功
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("/api/second/audit/nursingdept/result")]
        public ApiResponse NursingDeptAuditResult([FromBody] SecondAuditRequest request)
        {
            var userid = claimService.GetUserId();
            var result = secondAllotService.NursingDeptAudit(userid, request);
            return result ? new ApiResponse(ResponseType.OK, "操作成功") : new ApiResponse(ResponseType.Fail, "操作失败");
        }

        #endregion 二次绩效审核

        #region 二次绩效其他绩效

        /// <summary>
        /// 二次绩效其他绩效详情
        /// </summary>
        /// <returns></returns>
        [Route("api/second/other/list")]
        [HttpPost]
        public ApiResponse OtherList([FromBody] AgOtherRequest request)
        {
            var result = secondAllotDetails.GetOtherTempDetails(claimService.GetUserId(), request.SecondId, request.IsArchive, request.EmployeeSource);
            //var result = secondAllotDetails.GetOtherTempData(claimService.GetUserId(), request.SecondId, request.IsArchive, request.EmployeeSource, out decimal? realAmount);
            var obj = new
            {
                header = secondAllotService.OtherListHeader(request.SecondId, result?.Sum(t => t.RealAmount)),
                body = result,
            };
            return new ApiResponse(ResponseType.OK, obj);
        }

        /// <summary>
        /// 二次绩效其他绩效保存
        /// </summary>
        /// <returns></returns>
        [Route("api/second/other/save")]
        [HttpPost]
        public ApiResponse OtherSave([FromBody] AgOtherRequest request)
        {
            var result = secondAllotService.OtherSave(request.SecondId, request.Othersources);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 二次绩效其他绩效保存(new)
        /// </summary>
        /// <param name="secondId"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("api/second/other/save/{secondId}")]
        [HttpPost]
        public ApiResponse OtherSave(int secondId, [FromBody] SaveCollectData request)
        {
            secondAllotService.OtherSave(secondId, request);
            return new ApiResponse(ResponseType.OK);
        }

        #endregion 二次绩效其他绩效

        /// <summary>
        /// 二次绩效结果打印
        /// </summary>
        /// <returns></returns>
        [Route("api/second/print/{secondid}")]
        [HttpPost]
        public ApiResponse SecondPrint(int secondid)
        {
            var result = secondAllotService.Print(secondid);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 科主任/护士长绩效发布
        /// </summary>
        /// <returns></returns>
        [Route("api/second/deptcompute/{allotId}")]
        [HttpPost]
        public ApiResponse DeptComputeDetail(int allotId)
        {
            var userId = claimService.GetUserId();
            //var data = secondAllotService.DeptComputeDetail(userId, allotId, out int isShowManage);
            var data = secondAllotService.DeptComputeDetailList(userId, allotId, out int isShowManage);
            return new ApiResponse(ResponseType.OK, new { isShowManage, data });
        }

        /// <summary>
        /// 获取二次绩效详情数据
        /// </summary>
        /// <param name="secondId"></param>
        /// <param name="employeeSource"></param>
        /// <returns></returns>
        [HttpPost("api/second/detail/{secondId}/{employeeSource}")]
        public ApiResponse GetSecondAllotDetail([FromRoute] int secondId, int employeeSource)
        {
            var detail = secondAllotService.GetSecondSavedData(claimService.GetUserId(), secondId, employeeSource);
            return new ApiResponse(ResponseType.OK, detail);
        }

        /// <summary>
        /// 获取工作量类型
        /// </summary>
        /// <param name="secondId"></param>
        /// <returns></returns>
        [HttpPost("api/second/worktype/{secondId}")]
        public ApiResponse GetWorktypeDict([FromRoute] int secondId)
        {
            var detail = secondAllotService.GetWorkTypeDict(secondId);
            return new ApiResponse(ResponseType.OK, detail);
        }

        /// <summary>
        /// 获取工作量明细项
        /// </summary>
        /// <param name="secondId"></param>
        /// <returns></returns>
        [HttpPost("api/second/workload/{secondId}")]
        public ApiResponse GetWorkloadDict([FromRoute] int secondId)
        {
            var detail = secondAllotService.GetWorkloadDict(secondId);
            return new ApiResponse(ResponseType.OK, detail);
        }

        /// <summary>
        /// 二次绩效项目内容保存
        /// </summary>
        /// <param name="secondId"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("api/second/savedata/{secondId}")]
        [AllowAnonymous]
        public ApiResponse SaveValue([FromRoute] int secondId, [FromBody] dynamic request)
        {
            secondAllotService.SaveSecondAllotData(secondId, request);
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 二次绩效录入页面自动补全
        /// </summary>
        /// <returns></returns>
        [Route("api/second/autocomplete/{secondId}/{jobNumber}")]
        [HttpPost]
        public ApiResponse AutoCompleteBodyData([FromRoute] int secondId, string jobNumber)
        {
            var result = secondAllotService.AutoComplete(secondId, jobNumber);
            return new ApiResponse(ResponseType.OK, result);
        }
    }
}
