using DocumentFormat.OpenXml.Office2010.ExcelAc;
using Exam.Infrastructure.Data.Entity;
using Exam.Share.Dtos.Trains;
using Exam.Share.ViewResponses.Exam;
using Exam.Share.ViewResponses.Train;
using Hotline.Application.Exam.Constants.ApiRoutes;
using Hotline.Application.Exam.Interface.Train;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.Trains;
using Hotline.Share.Requests.Exam;
using Hotline.Share.Requests.Train;
using Hotline.Share.ViewResponses.Trains;
using Hotline.Tools;
using MapsterMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Train.Application.Interface.Train;

namespace Hotline.Api.Controllers.Exam
{
    public class TrainRecordController : BaseController
    {
        private readonly ITrainRecordService _trainRecordService;
        private readonly IMapper _mapper;

        public TrainRecordController(ITrainRecordService trainRecordService,IMapper mapper)
        {
            this._trainRecordService = trainRecordService;
            this._mapper = mapper;
        }

        /// <summary>
        /// 获取培训记录
        /// </summary>
        /// <param name="trainRecordPagedRequest"></param>
        /// <returns></returns>
        [HttpPost(TrainRecordApiRoute.GetPagedList)]
        public async Task<TrainRecordPageViewResponse> GetPagedList([FromBody]TrainRecordPagedRequest trainRecordPagedRequest)
        {
            var trainRecordPageViewResponse = await _trainRecordService.GetPagedListAsync(trainRecordPagedRequest);
            return trainRecordPageViewResponse as TrainRecordPageViewResponse;
        }

        /// <summary>
        /// 初次培训
        /// </summary>
        /// <param name="addTrainDto"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpPost(TrainRecordApiRoute.Train)]
        public async Task Train([FromBody] AddTrainDto addTrainDto, CancellationToken cancellationToken)
        {
            await _trainRecordService.TrainAsync(addTrainDto, cancellationToken);
        }

        /// <summary>
        /// 获取培训习题
        /// </summary>
        /// <param name="trainPracticeRequest"></param>
        /// <returns></returns>
        [HttpGet(TrainRecordApiRoute.GetTrainPractice)]
        public async Task<TrainPracticeDto> GetTrainPractice([FromQuery]TrainPracticeRequest trainPracticeRequest)
        {
            return await _trainRecordService.GetTrainPracticeAsync(trainPracticeRequest);
        }

        /// <summary>
        /// 获取培训习题
        /// </summary>
        /// <param name="trainPracticeRequest"></param>
        /// <returns></returns>
        [HttpGet(TrainRecordApiRoute.GetSimpleTrainPractice)]
        public async Task<SimpleTrainPracticeDto> GetSimpleTrainPractice([FromQuery] TrainPracticeRequest trainPracticeRequest)
        {
            return await _trainRecordService.GetSimpleTrainPracticeAsync(trainPracticeRequest);
        }

        /// <summary>
        /// 完成培训课件学习
        /// </summary>
        /// <param name="completeTrainPracticeDto"></param>
        /// <returns></returns>
        [HttpPost(TrainRecordApiRoute.CompleteTrainKnowladge)]
        public async Task CompleteTrainKnowladge([FromBody] CompleteTrainKnowladgeDto completeTrainPracticeDto, CancellationToken cancellationToken)
        {
             await _trainRecordService.CompleteTrainKnowladgeAsync(completeTrainPracticeDto, cancellationToken);
        }

        /// <summary>
        /// 结束培训
        /// </summary>
        /// <param name="completeTrainRecordDto"></param>
        /// <returns></returns>
        [HttpPost(TrainRecordApiRoute.CompleteTrainRecord)]
        public async Task CompleteTrainRecord(CompleteTrainRecordDto completeTrainRecordDto, CancellationToken cancellationToken)
        {
            await _trainRecordService.CompleteTrainRecordAsync(completeTrainRecordDto, cancellationToken);
        }

        /// <summary>
        /// 培训结果统计
        /// </summary>
        /// <param name="trainResultReportPagedRequest"></param>
        /// <returns></returns>
        [HttpPost(TrainRecordApiRoute.AnalysisTrainResult)]
        public async Task<TrainResultPagedViewResponse> AnalysisTrainResult([FromBody]TrainResultReportPagedRequest trainResultReportPagedRequest)
        {
            return await _trainRecordService.AnalysisTrainResult(trainResultReportPagedRequest);
        }

        /// <summary>
        /// 导出培训结果统计
        /// </summary>
        /// <param name="exportExcelDto"></param>
        /// <returns></returns>
        [HttpPost(TrainRecordApiRoute.ExportTrainResult)]
        public async Task<FileStreamResult> ExportTrainResult([FromBody] ExportExcelDto<TrainResultReportPagedRequest> exportExcelDto)
        {
            if (exportExcelDto.IsExportAll)
            {
                exportExcelDto.QueryDto.IsPaged = false;
            }

            var result = await _trainRecordService.AnalysisTrainResult(exportExcelDto.QueryDto);

            var items = result.Items;

            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<TrainResultViewResponse>(exportExcelDto.ColumnInfos ?? new List<ColumnInfo>());

            var dtos = items
                .Select(stu => _mapper.Map(stu, typeof(TrainResultViewResponse), dynamicClass))
                .Cast<object>()
                .ToList();

            var stream = ExcelHelper.CreateStream(dtos);

            return ExcelStreamResult(stream, "导出培训结果统计");

        }

        /// <summary>
        /// 计算培训结果比例
        /// </summary>
        /// <param name="trainResultReportPagedRequest"></param>
        /// <returns></returns>
        [HttpPost(TrainRecordApiRoute.CalcuteAnalysisRate)]
        public async Task<TrainResultRateViewResponse> CalcuteAnalysisRate([FromBody] TrainResultReportPagedRequest trainResultReportPagedRequest)
        {
            return await _trainRecordService.CalcuteAnalysisRate(trainResultReportPagedRequest);
        }

        /// <summary>
        /// 获取培训记录
        /// </summary>
        /// <returns></returns>
        [HttpPost(TrainRecordApiRoute.Get)]
        public async Task<TrainRecordDto> GetAsync([FromBody] EntityQueryRequest entityQueryRequest)
        {
            return await _trainRecordService.GetAsync(entityQueryRequest);
        }
    }
}
