using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Services;
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;

        public SecondAllotController(ClaimService claimService,
            SecondAllotService secondAllotService)
        {
            this.claimService = claimService;
            this.secondAllotService = secondAllotService;
        }

        #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 }).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);
            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());
            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

        #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 userid = claimService.GetUserId();
            var list = secondAllotService.AuditList(userid, 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);
            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 = secondAllotService.OtherList(request.SecondId, claimService.GetUserId());
            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);
        }
        #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<List<SecondPerforResponse>> DeptComputeDetail(int allotId)
        {
            var userId = claimService.GetUserId();
            var data = secondAllotService.DeptComputeDetail(userId, allotId);
            return new ApiResponse<List<SecondPerforResponse>>(ResponseType.OK, data);
        }
    }
}