using Masuit.Tools.Models;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Newtonsoft.Json;
using Performance.DtoModels;
using Performance.DtoModels.Request;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Infrastructure.Models;
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/assess")]
    public class AssessNewController : Controller
    {
        private readonly AssessNewService _service;
        private ClaimService claim;


        public AssessNewController(AssessNewService service, ClaimService claim)
        {
            _service = service;
            this.claim = claim;
        }
        #region 考核类别
        /// <summary>
        /// 考核类别列表
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("category/list")]
        public ApiResponse<List<per_assess_category>> CategoryList([FromQuery] int allotId)
        {
            return _service.CategoryList(allotId);
        }
        /// <summary>
        /// 考核类别新增
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("category/add")]
        public ApiResponse CategoryAdd([FromBody] AddAssessCategoryRequest request)
        {
            var userid = claim.GetUserId();
            return _service.CategoryAdd(request, userid);
        }
        /// <summary>
        /// 考核类别修改
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("category/update")]
        public ApiResponse CategoryUpdate([FromBody] UpdateAssessCategoryRequest request)
        {
            var userid = claim.GetUserId();
            return _service.CategoryUpdate(request, userid);
        }
        /// <summary>
        /// 考核类别删除
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("category/delete")]
        public ApiResponse CategoryDelete([FromBody] BatchAssessCategoryRequest request)
        {
            return _service.CategoryDelete(request);
        }

        /// <summary>
        /// 考核下发（检查下发受影响的上报内容）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("category/issue/check")]
        public ApiResponse<List<PerAssessmentStatisticsResponse>> CategoryIssueCheck([FromBody] UpdateAssessCategoryRequest request)
        {
            return _service.CategoryIssueCheck(request);
        }
        /// <summary>
        /// 考核下发
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("category/issue/confirm")]
        public ApiResponse CategoryIssueConfirm([FromBody] UpdateAssessCategoryRequest request)
        {
            var userid = claim.GetUserId();
            return _service.CategoryIssueConfirm(request, userid);
        }
        #endregion

        #region 考核方案
        /// <summary>
        /// 考核方案列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/list")]
        [ProducesResponseType(typeof(PagedList<AssessSchemeDataResponse>), StatusCodes.Status200OK)]
        public ApiResponse SchemeList([FromBody] QuerySchemeList query)
        {
            return new ApiResponse(ResponseType.OK, "", _service.SchemeList(query));
        }
        /// <summary>
        /// 考核方案新增
        /// </summary>
        /// <param name="request"></param>
        /// <remarks>
        /// 编码自动生成，不能修改
        /// </remarks>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/add")]
        public ApiResponse SchemeAdd([FromBody] AddAssessSchemeRequest request)
        {
            var userid = claim.GetUserId();
            return _service.SchemeAdd(request, userid);
        }
        /// <summary>
        /// 考核方案修改
        /// </summary>
        /// <param name="request"></param>
        /// <remarks>
        /// 编码不能修改
        /// </remarks>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/update")]
        public ApiResponse<UpdateAssessSchemeRequest> SchemeUpdate([FromBody] UpdateAssessSchemeRequest request)
        {
            var userid = claim.GetUserId();
            return _service.SchemeUpdate(request, userid);
        }
        /// <summary>
        /// 考核方案删除
        /// </summary>
        /// <param name="request"></param>
        /// <remarks>
        /// 允许批量删除，删除时要检查有没有外表引用，提示一起删除
        /// </remarks>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/delete")]
        public ApiResponse SchemeDelete([FromBody] BatchAssessSchemeRequest request)
        {
            return _service.SchemeDelete(request);
        }
        /// <summary>
        /// 考核方案下载
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/download")]
        [Produces("application/octet-stream", Type = typeof(FileResult))]
        public IActionResult SchemeDownload([FromBody] AddAssessSchemeRequest query)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "考核方案ID", Name = nameof(RecordAssessScheme.SchemeCode) },
                new ExcelDownloadHeads { Alias = "考核方案名称", Name = nameof(RecordAssessScheme.SchemeName) },
                new ExcelDownloadHeads { Alias = "考核方案类型", Name = nameof(RecordAssessScheme.AssessName) },
                new ExcelDownloadHeads { Alias = "备注", Name = nameof(RecordAssessScheme.SchemeRemarks) },
            };
            var q = new QuerySchemeList
            {
                Page = 1,
                PageSize = int.MaxValue,
                AllotId = query.AllotId,
                CategoryId = query.CategoryId,
                SchemeName = query.SchemeName,
            };
            var result = _service.SchemeList(q).Data;
            var ser = JsonConvert.SerializeObject(result);
            var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

            var filepath = _service.ExcelDownload(rows, "考核方案", excelDownloadHeads);

            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="categoryId"></param>
        ///// <param name="form"></param>
        ///// <remarks>
        ///// 上传文件中的编码无效，不能修改，自动生成，按编码作为匹配依据，进行增删改
        ///// </remarks>
        ///// <returns></returns>
        //[HttpPost]
        //[Route("scheme/upload")]
        //public ApiResponse SchemeUpload([FromQuery] int categoryId, [FromForm] IFormCollection form)
        //{
        //    return _service.SchemeUpload(categoryId, form);
        //}
        #endregion

        #region 考核指标
        /// <summary>
        /// 考核指标项列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/list")]
        [ProducesResponseType(typeof(PagedList<per_assess_scheme_items>), StatusCodes.Status200OK)]
        public ApiResponse SchemeItemsList([FromBody] QuerySchemeItemsList query)
        {
            return new ApiResponse(ResponseType.OK, "", _service.SchemeItemsList(query));
        }
        /// <summary>
        /// 考核指标项新增
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/add")]
        public ApiResponse<AddAssessSchemeItemsRequest> SchemeItemsAdd([FromBody] AddAssessSchemeItemsRequest request)
        {
            var userid = claim.GetUserId();
            return _service.SchemeItemsAdd(request, userid);
        }
        /// <summary>
        /// 考核指标项修改
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/update")]
        public ApiResponse<UpdateAssessSchemeItemsRequest> SchemeItemsUpdate([FromBody] UpdateAssessSchemeItemsRequest request)
        {
            var userid = claim.GetUserId();
            return _service.SchemeItemsUpdate(request, userid);
        }
        /// <summary>
        /// 考核指标项删除
        /// </summary>
        /// <param name="request"></param>       
        /// <remarks>
        /// 允许批量删除，删除时要检查有没有外表引用，提示一起删除
        /// </remarks>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/delete")]
        public ApiResponse SchemeItemsDelete([FromBody] BatchAssessSchemeItemsRequest request)
        {
            return _service.SchemeItemsDelete(request);
        }
        /// <summary>
        /// 考核指标项下载
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/download")]
        [Produces("application/octet-stream", Type = typeof(FileResult))]
        public IActionResult SchemeItemsDownload([FromBody] QuerySchemeItemsList query)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "考核指标编码", Name = nameof(per_assess_scheme_items.ItemCode) },
                new ExcelDownloadHeads { Alias = "一级指标名称", Name = nameof(per_assess_scheme_items.ItemName1) },
                new ExcelDownloadHeads { Alias = "二级指标名称", Name = nameof(per_assess_scheme_items.ItemName2) },
                new ExcelDownloadHeads { Alias = "考核分值", Name = nameof(per_assess_scheme_items.AssessScore) },
                new ExcelDownloadHeads { Alias = "考核标准", Name = nameof(per_assess_scheme_items.AssessNorm) },
                new ExcelDownloadHeads { Alias = "考核单元组别", Name = nameof(per_assess_scheme_items.UnitType) },
                new ExcelDownloadHeads { Alias = "考核单元名称", Name = nameof(per_assess_scheme_items.AccountingUnit) },
            };
            query.Page = 1;
            query.PageSize = int.MaxValue;
            var result = _service.SchemeItemsList(query).Data;
            var ser = JsonConvert.SerializeObject(result);
            var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

            var filepath = _service.ExcelDownload(rows, "考核指标项", excelDownloadHeads);

            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="schemeId"></param>
        /// <param name="allotId"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/upload")]
        public ApiResponse SchemeItemsUpload([FromQuery] int schemeId, int allotId, [FromForm] IFormCollection form)
        {
            var userid = claim.GetUserId();
            return _service.SchemeItemsUpload(schemeId, allotId, form, userid);
        }

        /// <summary>
        /// 考核对象核算单元列表清单
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/target/list")]
        [ProducesResponseType(typeof(PagedList<AssessSchemeTargetResponse>), StatusCodes.Status200OK)]
        public ApiResponse SchemeItemsTargetList([FromBody] QuerySchemeItemsTargetList query)
        {
            return new ApiResponse(ResponseType.OK, "", _service.SchemeItemsTargetList(query));
        }

        /// <summary>
        /// 考核对象核算单元保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/target/save")]
        public ApiResponse SchemeItemsTargetSave([FromBody] TargetAssessSchemeItemsRequest request)
        {
            var userid = claim.GetUserId();
            return _service.SchemeItemsTargetSave(request, userid);
        }

        /// <summary>
        /// 考核对象核算单元修改
        /// </summary>
        /// <param name="edit"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/target/edit")]
        public ApiResponse SchemeItemsTargetEdit([FromBody] TargetSchemeItemsTargetEdit edit)
        {
            var userid = claim.GetUserId();
            return _service.SchemeItemsTargetEdit(edit, userid);
        }

        /// <summary>
        /// 考核对象核算单元删除
        /// </summary>
        /// <param name="delete"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/items/target/delete")]
        public ApiResponse SchemeItemsTargetDelete([FromBody] TargetSchemeItemsTargetDelete delete)
        {
            return _service.SchemeItemsTargetDelete(delete);
        }

        #endregion

        #region 核算单元上报考核结果
        /// <summary>
        /// 考核结果列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/result/list")]
        [ProducesResponseType(typeof(PagedList<AssessSchemeResultListResponse>), StatusCodes.Status200OK)]
        public ApiResponse SchemeResultList([FromBody] QuerySchemeResultList query)
        {
            return new ApiResponse(ResponseType.OK, "", _service.SchemeResultList(query));
        }
        /// <summary>
        /// 考核结果下载
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/result/download")]
        public IActionResult SchemeEnterDownload([FromBody] QuerySchemeResultList query)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "核算组别", Name = nameof(AssessSchemeResultListResponse.TargetUnitType) },
                new ExcelDownloadHeads { Alias = "核算单元名称", Name = nameof(AssessSchemeResultListResponse.TargetAccountingUnit) },
            };
            query.Page = 1;
            query.PageSize = int.MaxValue;
            var result = _service.SchemeResultList(query).Data;
            foreach (var item in result.SelectMany(w => w.DictionaryResults).Select(w => w.Title).Distinct())
            {
                excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = item, Name = item });
            }
            excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = "合计", Name = "TotalAssessScore" });
            var ser = JsonConvert.SerializeObject(result);
            var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

            var filepath = _service.ExcelDownload(rows, "考核结果", excelDownloadHeads);

            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="allotId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/enter/list")]
        public ApiResponse<List<AssessSchemeEnterListResponse>> SchemeEnterList([FromQuery] int allotId)
        {
            var userid = claim.GetUserId();
            return _service.SchemeEnterList(allotId, userid);
        }
        /// <summary>
        /// 核算单元上报考核指标项清单
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/enter/detail/list")]
        [ProducesResponseType(typeof(PagedList<AssessSchemeEnterDetaiListResponse>), StatusCodes.Status200OK)]
        public ApiResponse SchemeEnterDetailList([FromBody] QuerySchemeEnterDetailList query)
        {
            return new ApiResponse(ResponseType.OK, "", _service.SchemeEnterDetailList(query));
        }

        /// <summary>
        /// 核算单元上报考核指标项修改
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/enter/detail/edit")]
        public ApiResponse SchemeEnterEdit([FromBody] EditAssessSchemeEnterRequest request)
        {
            var userid = claim.GetUserId();
            return _service.SchemeEnterEdit(request, userid);
        }
        ///// <summary>
        ///// 核算单元上报考核结果确认前检查
        ///// </summary>
        ///// <param name="issueId"></param>
        ///// <remarks>
        ///// 编辑：真实用途只是保存数据
        ///// 确认：数据编辑完成了，需要确认下，确认类似于确认无误，没有实际意义
        ///// 提交：数据必须全部确认完成才能提交
        ///// 需要检查确认的考核指标项中，有没有没有填写的数据
        ///// </remarks>
        ///// <returns></returns>
        //[HttpPost]
        //[Route("scheme/enter/detail/check")]
        //public ApiResponse SchemeEnterCheck([FromQuery] int schemeId, int issueId)
        //{
        //    //return _service.SchemeEnterCheck(schemeId, issueId);
        //    throw new NotImplementedException();
        //}



        ///// <summary>
        ///// 核算单元上报考核结果确认
        ///// </summary>
        ///// <param name="issueId"></param>
        ///// <remarks>
        ///// 编辑：真实用途只是保存数据
        ///// 确认：数据编辑完成了，需要确认下，确认类似于确认无误，没有实际意义
        ///// 提交：数据必须全部确认完成才能提交
        ///// </remarks>
        ///// <returns></returns>
        //[HttpPost]
        //[Route("scheme/enter/detail/confirm")]
        //public IActionResult SchemeEnterConfirm([FromQuery] int issueId)
        //{
        //    throw new NotImplementedException();
        //}



        /// <summary>
        /// 核算单元上报考核结果提交
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="itemId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        [Route("scheme/enter/submit")]
        public ApiResponse SchemeEnterSubmit([FromQuery] int allotId, int itemId)
        {
            var userid = claim.GetUserId();
            return _service.SchemeEnterSubmit(allotId, itemId, userid);
        }

        /// <summary>
        /// 核算单元上报考核结果审核
        /// </summary>
        /// <param name="audit"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/enter/audit")]
        public ApiResponse SchemeEnterAudit([FromBody] EditSchemeEnterAudit audit)
        {
            var realName = claim.GetUserClaim(JwtClaimTypes.RealName);
            return _service.SchemeEnterAudit(audit, realName);
        }



        /// <summary>
        /// 核算单元上报考核指标项下载
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/enter/download")]
        public IActionResult SchemeEnterDownload([FromBody] QuerySchemeEnterDetailList query)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "核算组别", Name = nameof(AssessSchemeEnterDetaiListResponse.TargetUnitType) },
                new ExcelDownloadHeads { Alias = "核算单元名称", Name = nameof(AssessSchemeEnterDetaiListResponse.TargetAccountingUnit) },
                new ExcelDownloadHeads { Alias = "一级指标名称", Name = nameof(AssessSchemeEnterDetaiListResponse.ItemName1) },
                new ExcelDownloadHeads { Alias = "考核项目", Name = nameof(AssessSchemeEnterDetaiListResponse.ItemName2) },
                new ExcelDownloadHeads { Alias = "考核标准", Name = nameof(AssessSchemeEnterDetaiListResponse.AssessNorm) },
                new ExcelDownloadHeads { Alias = "考核分值", Name = nameof(AssessSchemeEnterDetaiListResponse.AssessScore) },
                new ExcelDownloadHeads { Alias = "考核扣分", Name = nameof(AssessSchemeEnterDetaiListResponse.Score) },
                new ExcelDownloadHeads { Alias = "扣分原因", Name = nameof(AssessSchemeEnterDetaiListResponse.ScoreRemark) },
            };
            query.Page = 1;
            query.PageSize = int.MaxValue;
            var result = _service.SchemeEnterDetailList(query).Data;
            var ser = JsonConvert.SerializeObject(result);
            var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

            var filepath = _service.ExcelDownload(rows, "考核详情", excelDownloadHeads);

            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="itemId"></param>
        /// <param name="form"></param>
        /// <remarks>
        /// 上传文件中只有考核扣分、扣分原因有效，其他只做展示不参与修改操作
        /// </remarks>
        /// <returns></returns>
        [HttpPost]
        [Route("scheme/enter/upload")]
        public ApiResponse SchemeEnterUpload([FromQuery] int itemId, [FromForm] IFormCollection form)
        {
            var userid = claim.GetUserId();
            return _service.SchemeEnterUpload(itemId, form, userid);
        }
        #endregion
    }
}