using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Services;
using Performance.Services.ExtractExcelService;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Performance.Api.Controllers
{
    [Route("api/[controller]")]
    public class EmployeeController : Controller
    {
        private EmployeeService employeeService;
        private AllotService allotService;
        private ClaimService claim;
        private IHostingEnvironment evn;

        public EmployeeController(EmployeeService employeeService, AllotService allotService,
            ClaimService claim, IHostingEnvironment evn)
        {
            this.employeeService = employeeService;
            this.allotService = allotService;
            this.claim = claim;
            this.evn = evn;
        }

        /// <summary>
        /// 获取人员列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("getlist")]
        [HttpPost]
        public ApiResponse GetEmployeeList([CustomizeValidator(RuleSet = "Select"), FromBody] EmployeeRequest request)
        {
            var employee = employeeService.GetEmployeeList(request.AllotID, claim.GetUserId());
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 新增人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("insert")]
        [HttpPost]
        public ApiResponse Insert([CustomizeValidator(RuleSet = "Insert"), FromBody] EmployeeRequest request)
        {
            var employee = employeeService.Insert(request);
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 修改人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("update")]
        [HttpPost]
        public ApiResponse Update([CustomizeValidator(RuleSet = "Update"), FromBody] EmployeeRequest request)
        {
            var employee = employeeService.Update(request);
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 删除人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("delete")]
        [HttpPost]
        public ApiResponse Delete([CustomizeValidator(RuleSet = "Delete"), FromBody] EmployeeRequest request)
        {
            if (!employeeService.Delete(request))
                return new ApiResponse(ResponseType.Fail);
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 获取临床人员列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("clinic/getlist")]
        [HttpPost]
        public ApiResponse GetEmployeeClinicList([FromBody] im_employee_clinic request)
        {
            //if ((request.AllotID ?? 0) == 0)
            //    return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            var employee = employeeService.GetEmployeeClinicList(request.AllotID, claim.GetUserId());
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 新增临床人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("clinic/insert")]
        [HttpPost]
        public ApiResponse InsertClinic([FromBody] im_employee_clinic request)
        {
            if ((request.AllotID ?? 0) == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            if (string.IsNullOrEmpty(request.AccountingUnit))
                return new ApiResponse(ResponseType.ParameterError, "参数AccountingUnit无效！");

            if (string.IsNullOrEmpty(request.DoctorName))
                return new ApiResponse(ResponseType.ParameterError, "参数DoctorName无效！");

            var employee = employeeService.InsertClinic(request);
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 修改临床人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("clinic/update")]
        [HttpPost]
        public ApiResponse UpdateClinic([FromBody] im_employee_clinic request)
        {
            if ((request.AllotID ?? 0) == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            if (string.IsNullOrEmpty(request.AccountingUnit))
                return new ApiResponse(ResponseType.ParameterError, "参数AccountingUnit无效！");

            if (string.IsNullOrEmpty(request.DoctorName))
                return new ApiResponse(ResponseType.ParameterError, "参数DoctorName无效！");
            var employee = employeeService.UpdateClinic(request);
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 删除临床人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("clinic/delete")]
        [HttpPost]
        public ApiResponse DeleteClinic([FromBody] im_employee_clinic request)
        {
            if (request.ID == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数ID无效！");

            if (!employeeService.DeleteClinic(request))
                return new ApiResponse(ResponseType.Fail);
            return new ApiResponse(ResponseType.OK);
        }

        #region 行政后勤

        /// <summary>
        /// 获取临床人员列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("logistics/getlist")]
        [HttpPost]
        public ApiResponse GetEmployeeLogisticsList([FromBody] im_employee_clinic request)
        {
            //if ((request.AllotID ?? 0) == 0)
            //    return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            var employee = employeeService.GetEmployeeLogisticsList(request.AllotID, claim.GetUserId());
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 新增临床人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("logistics/insert")]
        [HttpPost]
        public ApiResponse InsertLogistics([FromBody] im_employee_logistics request)
        {
            if ((request.AllotID ?? 0) == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            if (string.IsNullOrEmpty(request.AccountingUnit))
                return new ApiResponse(ResponseType.ParameterError, "参数AccountingUnit无效！");

            if (string.IsNullOrEmpty(request.DoctorName))
                return new ApiResponse(ResponseType.ParameterError, "参数DoctorName无效！");

            var employee = employeeService.InsertLogistics(request);
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 修改临床人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("logistics/update")]
        [HttpPost]
        public ApiResponse UpdateLogistics([FromBody] im_employee_logistics request)
        {
            if ((request.AllotID ?? 0) == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            if (string.IsNullOrEmpty(request.AccountingUnit))
                return new ApiResponse(ResponseType.ParameterError, "参数AccountingUnit无效！");

            if (string.IsNullOrEmpty(request.DoctorName))
                return new ApiResponse(ResponseType.ParameterError, "参数DoctorName无效！");
            var employee = employeeService.UpdateLogistics(request);
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 删除临床人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("logistics/delete")]
        [HttpPost]
        public ApiResponse DeleteLogistics([FromBody] im_employee_clinic request)
        {
            if (request.ID == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数ID无效！");

            if (!employeeService.DeleteLogistics(request))
                return new ApiResponse(ResponseType.Fail);
            return new ApiResponse(ResponseType.OK);
        }

        #endregion 行政后勤

        /// <summary>
        /// 人事科修改参数后提交
        /// </summary>
        /// <param name="allotid"></param>
        /// <returns></returns>
        [Route("manage/audit/{allotid}")]
        [HttpPost]
        public ApiResponse Audit(int allotid)
        {
            var result = employeeService.Audit(allotid);
            return result ? new ApiResponse(ResponseType.OK, "提交成功") : new ApiResponse(ResponseType.Fail, "提交失败");
        }

        /// <summary>
        /// 获取人员补充绩效列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("apr/getlist")]
        [HttpPost]
        public ApiResponse GetAprList([FromBody] per_apr_amount request)
        {
            if (request.AllotId == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            var employee = employeeService.GetAprList(request.AllotId, claim.GetUserId());
            return new ApiResponse(ResponseType.OK, "ok", employee);
        }

        /// <summary>
        /// 医院其他绩效审核
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("apr/getdeptlist")]
        [HttpPost]
        public ApiResponse GetAprGroupList([FromBody] per_apr_amount request)
        {
            if (request.AllotId == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            var employee = employeeService.GetAprList(request.AllotId, claim.GetUserId());
            if (employee == null || !employee.Any())
                return new ApiResponse(ResponseType.OK, "ok", employee);

            var result = employee.GroupBy(t => new { TypeInDepartment = t.TypeInDepartment ?? "" })
                .Select(t => new per_apr_amount
                {
                    TypeInDepartment = t.Key.TypeInDepartment,
                    Amount = t.Sum(s => s.Amount ?? 0),
                    Status = t.Any(s => s.Status == 2) ? 2 : t.Any(s => s.Status == 4) ? 4 : t.FirstOrDefault().Status,
                });
            return new ApiResponse(ResponseType.OK, "ok", result);
        }

        /// <summary>
        /// 医院其他绩效审核详情
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("apr/getdeptdetail")]
        [HttpPost]
        public ApiResponse GetAprDetail([FromBody] per_apr_amount request)
        {
            if (request.AllotId == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            var employee = employeeService.GetAprList(request.AllotId, request.TypeInDepartment);
            if (employee == null || !employee.Any())
                return new ApiResponse(ResponseType.OK, "ok", employee);

            var result = employee.GroupBy(t => new { t.AccountingUnit, t.PersonnelNumber, t.DoctorName }).Select(t => new
            {
                PersonnelNumber = t.Key.PersonnelNumber,
                DoctorName = t.Key.DoctorName,
                AccountingUnit = t.Key.AccountingUnit,
                Status = t.Any(s => s.Status == 2) ? 2 : t.Any(s => s.Status == 4) ? 4 : t.FirstOrDefault().Status,
                Detail = t.GroupBy(group => group.PerforType).Select(s => new TitleValue<decimal>
                {
                    Title = string.IsNullOrEmpty(s.Key) ? "未知" : s.Key,
                    Value = s.Sum(sum => sum.Amount ?? 0)
                })
            });
            return new ApiResponse(ResponseType.OK, "ok", result);
        }

        /// <summary>
        /// 新增人员补充绩效
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("apr/insert")]
        [HttpPost]
        public ApiResponse InsertApr([FromBody] per_apr_amount request)
        {
            if (request.AllotId == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            var result = employeeService.InsertApr(request, claim.GetUserId());
            return result ? new ApiResponse(ResponseType.OK, "添加成功", request) :
                new ApiResponse(ResponseType.Fail, "添加失败");
        }

        /// <summary>
        /// 修改人员补充绩效
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("apr/update")]
        [HttpPost]
        public ApiResponse UpdateApr([FromBody] per_apr_amount request)
        {
            if (request.AllotId == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数AllotId无效！");

            var result = employeeService.UpdateApr(request);
            return result ? new ApiResponse(ResponseType.OK, "修改成功", request) :
                new ApiResponse(ResponseType.Fail, "修改失败");
        }

        /// <summary>
        /// 删除人员补充绩效
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("apr/delete")]
        [HttpPost]
        public ApiResponse DeleteApr([FromBody] per_apr_amount request)
        {
            if (request.Id == 0)
                return new ApiResponse(ResponseType.ParameterError, "参数无效！");

            if (!employeeService.DeleteApr(request.Id))
                return new ApiResponse(ResponseType.Fail);
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 医院其他绩效审核;驳回、成功
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("apr/audit")]
        public ApiResponse AuditResult([FromBody] AprAmountAuditRequest request)
        {
            var userid = claim.GetUserId();
            var result = employeeService.ConfirmAudit(userid, request);
            return result ? new ApiResponse(ResponseType.OK, "操作成功") : new ApiResponse(ResponseType.Fail, "操作失败");
        }

        /// <summary>
        /// 上传人员绩效文件
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [Route("apr/import")]
        [HttpPost]
        public ApiResponse Import([FromForm] IFormCollection form)
        {
            var allotid = form.ToDictionary().GetValue("allotid", 0);
            if (allotid <= 0)
                return new ApiResponse(ResponseType.Fail, "参数错误", "allotid无效");

            var file = ((FormFileCollection)form.Files).FirstOrDefault();
            if (file == null)
                return new ApiResponse(ResponseType.Fail, "参数错误", "文件无效");

            if (!ExtractHelper.IsXlsxFile(file.FileName))
                return new ApiResponse(ResponseType.Fail, "文件格式错误", "文件暂只支持xlsx文件");

            var allot = allotService.GetAllot(allotid);
            if (allot == null)
                return new ApiResponse(ResponseType.Fail, "allotid不存在");

            var name = FileHelper.GetFileNameNoExtension(file.FileName) + DateTime.Now.ToString("yyyyMMddHHmmssfff");
            var ext = FileHelper.GetExtension(file.FileName);
            var dpath = Path.Combine(evn.ContentRootPath, "Files", $"{allot.HospitalId}", $"{allot.Year}{allot.Month.ToString().PadLeft(2, '0')}");
            FileHelper.CreateDirectory(dpath);

            var path = Path.Combine(dpath, $"{name}{ext}");

            using (var stream = file.OpenReadStream())
            {
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);
                if (!FileHelper.CreateFile(path, bytes))
                    return new ApiResponse(ResponseType.Fail, $"{file.FileName}上传失败");
            }
            employeeService.ImpoerAprEmployees(allotid, path, claim.GetUserId());
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 自动获取人员信息
        /// </summary>
        /// <remarks>
        /// Sample request:
        ///
        ///     POST /Todo
        ///     {
        ///       "allotid": 7,
        ///       "personnelnumber": "***************(用户输入信息)"
        ///     }
        ///
        /// </remarks>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("autocomplate")]
        public ApiResponse<per_apr_amount> GetEmployeeMessage([FromBody] per_apr_amount request)
        {
            var result = employeeService.GetEmployeeMessage(request.AllotId, request.PersonnelNumber, claim.GetUserId());
            return new ApiResponse<per_apr_amount>(ResponseType.OK, "人员信息", result);
        }

        /// <summary>
        /// 绩效类型字典
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpPost("apr/perfortype/{allotId}")]
        public ApiResponse<List<TitleValue>> GetPerforTypeDict([FromRoute] int allotId)
        {
            var result = employeeService.GetPerforTypeDict(allotId);
            return new ApiResponse<List<TitleValue>>(ResponseType.OK, "绩效类型字典", result);
        }
    }
}
