using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Performance.DtoModels;
using Performance.Infrastructure;
using Performance.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Performance.Api.Controllers
{
    /// <summary>
    /// 报表
    /// </summary>
    [Route("api/report")]
    public class ReportController : Controller
    {
        private AllotService allotService;
        private ComputeService _computeService;
        private ReportService reportService;
        private ReportDataService reportDataService;
        private ClaimService claimService;
        private readonly DownloadService downloadService;
        public ReportController(
            ClaimService claimService,
            AllotService allotService,
            ReportService reportService,
            ReportDataService reportDataService,
            ComputeService computeService,
            DownloadService downloadService)
        {
            this.allotService = allotService;
            this.reportService = reportService;
            this.reportDataService = reportDataService;
            this.claimService = claimService;
            this._computeService = computeService;
            this.downloadService = downloadService;
        }

        [Route("rank")]
        [HttpPost]
        public ApiResponse Rank([FromBody] HospitalIdRequest request)
        {
            var allots = allotService.GetAllotList(request.HospitalId);

            int[] states = new int[] { 6, 8, 10 };
            var result = allots?.Where(w => states.Contains(w.States))
                .Select(w => new { w.Year, w.Month })
                .OrderByDescending(w => w.Year)
                .ThenByDescending(w => w.Month);

            return new ApiResponse(ResponseType.OK, result);
        }

        [Route("selection")]
        [HttpPost]
        public ApiResponse Selection([FromBody] SelectionRequest report)
        {
            var userId = claimService.GetUserId();
            var result = reportDataService.GetReportSelection(report.GroupId, userId, report.HospitalId);
            return new ApiResponse(ResponseType.OK, result);
        }

        [Route("info")]
        [HttpPost]
        public ApiResponse Info([FromBody] SelectionRequest report)
        {
            var result = reportDataService.GetReportInfo(report.GroupId);
            return new ApiResponse(ResponseType.OK, result);
        }

        [Route("search")]
        [HttpPost]
        public ApiResponse Search([FromBody] SearchReportRequest report)
        {
            if (report.Values == null || !report.Values.Any())
                return new ApiResponse(ResponseType.OK, new List<ReportData>());

            //string[] keys = new string[] { "year", "month", };
            //foreach (var item in report.Values.Where(t => keys.Contains(t.Title)))
            //{
            //    if (item.Values == null || !item.Values.Any(t => !string.IsNullOrEmpty(t)))
            //        return new ApiResponse(ResponseType.OK, new List<ReportData>());
            //}

            var userId = claimService.GetUserId();
            var result = reportDataService.GetReportData(report.HospitalId, report.GroupId, report.ReportId, report.Values ?? new List<SelectionValues>(), userId);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 首页数据概况
        /// </summary>
        /// <returns></returns>
        [Route("survey")]
        [HttpPost]
        public ApiResponse Survey([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        {
            var result = reportService.Survey(request.HospitalId);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 科室医生人均绩效（含科主任）
        /// </summary>
        /// <returns></returns>
        [Route("doctoravg")]
        [HttpPost]
        public ApiResponse DoctorAvg([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        {
            var result = reportService.DoctorAvg(request.HospitalId, request.IsIndex);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 科室护士人均绩效（含护士长）
        /// </summary>
        /// <returns></returns>
        [Route("nurseavg")]
        [HttpPost]
        public ApiResponse NurseAvg([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        {
            var result = reportService.NurseAvg(request.HospitalId, request.IsIndex);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 门诊患者均次费用
        /// </summary>
        /// <returns></returns>
        [Route("outfeeavg")]
        [HttpPost]
        public ApiResponse OutFeeAvg([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        {
            var list = reportService.OutFeeAvg(request.HospitalId);
            return new ApiResponse(ResponseType.OK, "", list);
        }

        /// <summary>
        /// 住院患者均次费用
        /// </summary>
        /// <returns></returns>
        [Route("inpatfeeavg")]
        [HttpPost]
        public ApiResponse InpatFeeAvg([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        {
            var list = reportService.InpatFeeAvg(request.HospitalId);
            return new ApiResponse(ResponseType.OK, "", list);
        }

        ///// <summary>
        ///// 科室药占比
        ///// </summary>
        ///// <returns></returns>
        //[Route("medicine")]
        //[HttpPost]
        //public ApiResponse Medicine([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        //{
        //    var list = reportService.Medicine(request.HospitalId, request.IsIndex);
        //    return new ApiResponse(ResponseType.OK, "", list);
        //}

        ///// <summary>
        ///// 科室有效收入占比
        ///// </summary>
        ///// <returns></returns>
        //[Route("income")]
        //[HttpPost]
        //public ApiResponse Income([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        //{
        //    var list = reportService.Income(request.HospitalId, request.IsIndex);
        //    return new ApiResponse(ResponseType.OK, "", list);
        //}

        /// <summary>
        /// 月群体人均绩效
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("getperforavg")]
        [HttpPost]
        public ApiResponse AvgPerfor([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        {
            var list = reportService.GetAvgPerfor(request.HospitalId);
            return new ApiResponse(ResponseType.OK, "", list);
        }


        /// <summary>
        /// 人群绩效比
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("avgratio")]
        [HttpPost]
        public ApiResponse AvgRatio([CustomizeValidator(RuleSet = "Query"), FromBody] ReportRequest request)
        {
            var list = reportService.AvgRatio(request.HospitalId);
            return new ApiResponse(ResponseType.OK, "", list);
        }

        /// <summary>
        /// 首页报表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("index")]
        [HttpPost]
        public ApiResponse IndexReport([CustomizeValidator(RuleSet = "Index"), FromBody] ReportRequest request)
        {
            var list = reportService.IndexReport(request.HospitalId, request.Source);
            return new ApiResponse(ResponseType.OK, "", list);
        }

        /// <summary>
        /// 菜单报表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("menu")]
        [HttpPost]
        public ApiResponse MenuReport([CustomizeValidator(RuleSet = "Menu"), FromBody] ReportRequest request)
        {
            var list = reportService.MenuReport(request);
            return new ApiResponse(ResponseType.OK, "", list);
        }
        /// <summary>
        /// 菜单报表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("operation")]
        [HttpPost]
        public ApiResponse Operation([FromBody] ReportRequest request)
        {
            if (request == null)
                return new ApiResponse(ResponseType.Fail, "参数错误！");

            var list = reportService.Operation(request);
            return new ApiResponse(ResponseType.OK, "", list);
        }

        /// <summary>
        /// 绩效汇报表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("table/normal")]
        [HttpPost]
        public ApiResponse TableNormal([FromBody] ConditionRequest request)
        {
            if (request == null)
                return new ApiResponse(ResponseType.OK, "", new TableData());

            var list = reportService.TableNormal(request);
            return new ApiResponse(ResponseType.OK, "", list);
        }

        /// <summary>
        /// 科室绩效对比
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("table/special")]
        [HttpPost]
        public ApiResponse TableSpecial([FromBody] ConditionRequest request)
        {
            if (request == null)
                return new ApiResponse(ResponseType.OK, "", new TableData());

            var list = reportService.TableSpecial(request);
            return new ApiResponse(ResponseType.OK, "", list);
        }

        #region 发放表视图、下载 全院发放

        /// <summary>
        /// 全院绩效发放（视图）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("getAllComputeView")]
        [HttpPost]
        public ApiResponse GetAllComputeView([FromBody] BeginEndTime request)
        {
            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out _) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out _))
                throw new PerformanceException("请输入正确的时间");
            var datas = _computeService.GetAllComputeViewByDate("view_allot_sign_emp", request);

            var list = new QueryComputeByDateGetPage
            {
                Data = datas.Skip(request.PageSize * (request.CurrentPage - 1)).Take(request.PageSize).ToList(),
                TotalData = _computeService.SumDatas(datas),
                TotalCount = datas.Count(),
                TotalPages = (int)Math.Ceiling((double)datas.Count() / request.PageSize),
                CurrentPage = request.CurrentPage,
                PageSize = request.PageSize
            };
            return new ApiResponse(ResponseType.OK, "ok", list);
        }

        /// <summary>
        /// 全院绩效发放（视图）下载
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("getAllComputeViewDown/download")]
        [HttpPost]
        public IActionResult AllComputeViewDownload([FromBody] BeginEndTime request)
        {
            if (request.HospitalId == 0)
                throw new PerformanceException("医院ID不能为空");

            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out DateTime bdate) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out DateTime edate))
                throw new PerformanceException("请输入正确的时间");

            request.PageSize = 0;
            var list = _computeService.GetAllComputeViewByDate("view_allot_sign_emp", request);
            if (null == list)
                throw new PerformanceException("当前绩效记录不存在");

            var filepath = downloadService.AllComputerViewReportByDate(request.HospitalId, list, "/report/wholehospital_grant", "全院绩效发放", bdate, edate.AddMonths(1));

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
        }

        /// <summary>
        /// 全院绩效发放汇总表（视图）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("wholehospital_grant_summary")]
        [HttpPost]
        public ApiResponse GetWholeHospitalGrantSummary([FromBody] HospitalGrantSummary request)
        {
            return new ApiResponse(ResponseType.OK, "ok", _computeService.GetPerformanceSummary(request, "view_allot_sign_emp"));

        }

        /// <summary>
        /// 全院绩效发放汇总表（视图）下载
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("wholehospital_grant_summary/download")]
        [HttpPost]
        public IActionResult WholeHospitalGrantSummaryDownload([FromBody] HospitalGrantSummaryDown request)
        {
            if (request.HospitalId == 0)
                throw new PerformanceException("医院ID不能为空");

            DateTime bdate = DateTime.Now;
            DateTime edate = DateTime.Now;
            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out bdate) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out edate))
                throw new PerformanceException("请输入正确的时间");

            var resetGroupBy = request.GroupBy.Copy();
            var list = _computeService.GetAllComputeViewByDateAndTotal("view_allot_sign_emp", request);
            if (null == list)
                throw new PerformanceException("当前绩效记录不存在");


            request.GroupBy = resetGroupBy;
            List<string> headlist = new List<string>();

            foreach (var item in request.GroupBy.Union(request.SumBy).ToList())
            {
                headlist.Add(item.ToLower());
            }

            var filepath = downloadService.AllComputerViewReportByDate(request.HospitalId, list, "/report/wholehospital_grant_summary", "全院绩效发放", bdate, edate.AddMonths(1), headlist.ToArray());

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));

        }
        #endregion

        #region 全院核算发放
        /// <summary>
        /// 全院核算绩效发放（视图）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("gethosdataView")]
        [HttpPost]
        public ApiResponse GethosdataView([FromBody] BeginEndTime request)
        {
            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out _) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out _))
                throw new PerformanceException("请输入正确的时间");

            var datas = _computeService.GetAllComputeViewByDate("view_allot_sign_dept", request);

            var list = new QueryComputeByDateGetPage
            {
                Data = datas.Skip(request.PageSize * (request.CurrentPage - 1)).Take(request.PageSize).ToList(),
                TotalData = _computeService.SumDatas(datas),
                TotalCount = datas.Count(),
                TotalPages = (int)Math.Ceiling((double)datas.Count() / request.PageSize),
                CurrentPage = request.CurrentPage,
                PageSize = request.PageSize
            };
            return new ApiResponse(ResponseType.OK, "ok", list);

        }



        /// <summary>
        /// 全院核算绩效发放（视图） 下载
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("gethosdataView/download")]
        [HttpPost]
        public IActionResult GethosdataViewDown([FromBody] BeginEndTime request)
        {
            if (request.HospitalId == 0)
                throw new PerformanceException("医院ID不能为空");

            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out DateTime bdate) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out DateTime edate))
                throw new PerformanceException("请输入正确的时间");

            request.PageSize = 0;
            var list = _computeService.GetAllComputeViewByDate("view_allot_sign_dept", request);
            if (null == list)
                throw new PerformanceException("当前绩效记录不存在");

            var filepath = downloadService.AllComputerViewReportByDate(request.HospitalId, list, "/report/wholehospital_accounting_grant", "全院核算绩效发放", bdate, edate.AddMonths(1));

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
        }

        /// <summary>
        /// 全院核算绩效发放汇总表（视图）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("wholehospital_accounting_grant_summary")]
        [HttpPost]
        public ApiResponse GetWholeHospitalAccountingGrantSummary([FromBody] HospitalGrantSummary request)
        {

            return new ApiResponse(ResponseType.OK, "ok", _computeService.GetPerformanceSummary(request, "view_allot_sign_dept"));

        }

        /// <summary>
        /// 全院核算绩效发放汇总表（视图）下载
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("wholehospital_accounting_grant_summary/download")]
        [HttpPost]
        public IActionResult WholeHospitalAccountingGrantSummaryDownload([FromBody] HospitalGrantSummaryDown request)
        {
            if (request.HospitalId == 0)
                throw new PerformanceException("医院ID不能为空");

            DateTime bdate = DateTime.Now;
            DateTime edate = DateTime.Now;
            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out bdate) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out edate))
                throw new PerformanceException("请输入正确的时间");


            var list = _computeService.GetAllComputeViewByDateAndTotal("view_allot_sign_dept", request);
            if (null == list)
                throw new PerformanceException("当前绩效记录不存在");

            List<string> headlist = new List<string>();

            foreach (var item in request.GroupBy.Union(request.SumBy).ToList())
            {
                headlist.Add(item.ToLower());
            }

            var filepath = downloadService.AllComputerViewReportByDate(request.HospitalId, list, "/report/wholehospital_accounting_grant_summary", "全院核算绩效发放", bdate, edate.AddMonths(1), headlist.ToArray());

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));

        }

        #endregion

        #region 全院财务发放
        /// <summary>
        /// 获取财务全院绩效列表（视图）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("allcomputeView/personnel")]
        [HttpPost]
        public ApiResponse AllComputeViewByPM([FromBody] BeginEndTime request)
        {
            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out _) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out _))
                throw new PerformanceException("请输入正确的时间");

            var datas = _computeService.GetAllComputeViewByDate("view_allot_sign_emp_finance", request);

            var list = new QueryComputeByDateGetPage
            {
                Data = datas.Skip(request.PageSize * (request.CurrentPage - 1)).Take(request.PageSize).ToList(),
                TotalData = _computeService.SumDatas(datas),
                TotalCount = datas.Count(),
                TotalPages = (int)Math.Ceiling((double)datas.Count() / request.PageSize),
                CurrentPage = request.CurrentPage,
                PageSize = request.PageSize
            };
            return new ApiResponse(ResponseType.OK, "ok", list);
        }

        /// <summary>
        ///  获取财务全院绩效列表（视图）下载
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("allcomputeView/personnel/download")]
        [HttpPost]
        public IActionResult AllComputeByPMViewDownLoad([FromBody] BeginEndTime request)
        {
            if (request.HospitalId == 0)
                throw new PerformanceException("医院ID不能为空");

            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out DateTime bdate) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out DateTime edate))
                throw new PerformanceException("请输入正确的时间");

            request.PageSize = 0;
            var list = _computeService.GetAllComputeViewByDate("view_allot_sign_emp_finance", request);
            if (null == list)
                throw new PerformanceException("当前绩效记录不存在");

            var filepath = downloadService.AllComputerViewReportByDate(request.HospitalId, list, "/report/wholehospital_finance_grant", "财务全院绩效发放", bdate, edate.AddMonths(1));

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
        }

        /// <summary>
        /// 财务全院绩效发放汇总表（视图）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("wholehospital_finance_grant_summary")]
        [HttpPost]
        public ApiResponse GetWholeHospitalFinanceGrantSummary([FromBody] HospitalGrantSummary request)
        {
            return new ApiResponse(ResponseType.OK, "ok", _computeService.GetPerformanceSummary(request, "view_allot_sign_emp_finance"));

        }

        /// <summary>
        /// 财务全院绩效发放汇总表（视图）下载
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("wholehospital_finance_grant_summary/download")]
        [HttpPost]
        public IActionResult WholeHospitalFinanceGrantSummaryDownload([FromBody] HospitalGrantSummaryDown request)
        {
            if (request.HospitalId == 0)
                throw new PerformanceException("医院ID不能为空");

            DateTime bdate = DateTime.Now;
            DateTime edate = DateTime.Now;
            if (string.IsNullOrEmpty(request.BeginTime) || !DateTime.TryParse(request.BeginTime, out bdate) ||
                string.IsNullOrEmpty(request.EndTime) || !DateTime.TryParse(request.EndTime, out edate))
                throw new PerformanceException("请输入正确的时间");


            var list = _computeService.GetAllComputeViewByDateAndTotal("view_allot_sign_emp_finance", request);
            if (null == list)
                throw new PerformanceException("当前绩效记录不存在");

            List<string> headlist = new List<string>();

            foreach (var item in request.GroupBy.Union(request.SumBy).ToList())
            {
                headlist.Add(item.ToLower());
            }

            var filepath = downloadService.AllComputerViewReportByDate(request.HospitalId, list, "/report/wholehospital_finance_grant_summary", "财务全院绩效发放", bdate, edate.AddMonths(1), headlist.ToArray());

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));

        }
        #endregion
    }
}