using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos;
using Hotline.Share.Requests;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using Hotline.Application.Quality;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Share.Dtos.Quality;
using Hotline.Tools;
using Hotline.Quality;
using Hotline.Share.Enums.Quality;
using Hotline.Caching.Services;
using Hotline.Settings;
using Hotline.Share.Enums.FlowEngine;
using Hotline.Share.Enums.Order;
using XF.Utility.EnumExtensions;
using Hotline.Caching.Interfaces;
using Hotline.Users;
using XF.Domain.Repository;
using Hotline.Api.Filter;

namespace Hotline.Api.Controllers.Bi
{
	public class BiQualityController : BaseController
	{
		private readonly IMapper _mapper;
		private readonly IQualityApplication _qualityApplication;
		private readonly IQualityRepository _qualityRepository;
		private readonly ISystemSettingCacheManager _systemSettingCacheManager;
		private readonly IRepository<User> _userRepository;

		public BiQualityController(
			IMapper mapper,
			IQualityApplication qualityApplication,
			IQualityRepository qualityRepository,
			ISystemSettingCacheManager systemSettingCacheManager,
			IRepository<User> userRepository
			)
		{
			_mapper = mapper;
			_qualityApplication = qualityApplication;
			_qualityRepository = qualityRepository;
			_systemSettingCacheManager = systemSettingCacheManager;
			_userRepository = userRepository;
		}


		/// <summary>
		/// 坐席质检分析
		/// </summary>
		/// <param name="dto"></param>
		/// <returns></returns>
		[HttpGet("seats_quality_analyse")]
		public async Task<PagedDto<SeatsQualityAnalyseDto>> SeatsQualityAnalyse([FromQuery] PagedKeywordRequest dto)
		{
			var (total, items) = await _qualityApplication.SeatsQualityAnalyse(dto, HttpContext.RequestAborted).ToPagedListAsync(dto, HttpContext.RequestAborted);

			return new PagedDto<SeatsQualityAnalyseDto>(total, _mapper.Map<IReadOnlyList<SeatsQualityAnalyseDto>>(items));
		}

		/// <summary>
		/// 坐席质检分析导出
		/// </summary>
		/// <param name="dto"></param>
		/// <returns></returns>
		[HttpPost("seats_quality_analyse/export")]
		[LogFilterAlpha("导出日志")]
		public async Task<FileStreamResult> SeatsQualityAnalyseExport([FromBody] ExportExcelDto<PagedKeywordRequest> dto)
		{
			var query = _qualityApplication.SeatsQualityAnalyse(dto.QueryDto, HttpContext.RequestAborted);

			List<Hotline.Quality.Quality> lists;
			if (dto.IsExportAll)
			{
				lists = await query.ToListAsync(HttpContext.RequestAborted);
			}
			else
			{
				var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
				lists = items;
			}

			var listDtos = _mapper.Map<ICollection<SeatsQualityAnalyseDto>>(lists);

			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<SeatsQualityAnalyseDto>(dto.ColumnInfos);

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

			var stream = ExcelHelper.CreateStream(dtos);

			return ExcelStreamResult(stream, "坐席质检分析");

		}

		#region 质检工作分析

		/// <summary>
		/// 质检工单概览
		/// </summary>
		/// <param name="dto"></param>
		/// <returns></returns>
		[HttpGet("quality_order_overview")]
		public async Task<List<QualityOrderOverviewDto>> QualityOrderOverview([FromQuery] QualityWorkAnalysisRequest dto)
		{
			var allOrderNum =  await _qualityRepository.Queryable().Where(x => x.Source == EQualitySource.Accepted && x.QualityTime >= dto.StartTime && x.QualityTime <= dto.EndTime && x.State == EQualityState.End).CountAsync();
			var items = await _qualityApplication.QualityOrderOverview(dto,allOrderNum, HttpContext.RequestAborted).ToListAsync(HttpContext.RequestAborted);
			return items;
		}

		/// <summary>
		/// 质检工单概览导出
		/// </summary>
		/// <param name="dto"></param>
		/// <returns></returns>
		[HttpPost("quality_order_overview/export")]
		[LogFilterAlpha("导出日志")]
		public async Task<FileStreamResult> QualityOrderOverviewExport([FromBody] ExportExcelDto<QualityWorkAnalysisRequest> dto)
		{
			var allOrderNum = await _qualityRepository.Queryable().Where(x => x.Source == EQualitySource.Accepted && x.QualityTime >= dto.QueryDto.StartTime && x.QualityTime <= dto.QueryDto.EndTime && x.State == EQualityState.End).CountAsync();
			var query = _qualityApplication.QualityOrderOverview(dto.QueryDto, allOrderNum, HttpContext.RequestAborted);

			List<QualityOrderOverviewDto> listDtos;

			listDtos = await query.ToListAsync(HttpContext.RequestAborted);

			//var listDtos = _mapper.Map<ICollection<SeatsQualityAnalyseDto>>(lists);

			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<QualityOrderOverviewDto>(dto.ColumnInfos);

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

			var stream = ExcelHelper.CreateStream(dtos);

			return ExcelStreamResult(stream, "质检工单概览");

		}

		/// <summary>
		/// 坐席质检分值分析
		/// </summary>
		/// <param name="dto"></param>
		/// <returns></returns>
		[HttpGet("seats_quality_grade_analyse")]
		public async Task<SeatsQualityGradeAnalyseDto> SeatsQualityGradeAnalyse([FromQuery] QualityWorkAnalysisRequest dto)
		{
			var temps = await _qualityApplication.SeatsQualityGradeAnalyse(dto, HttpContext.RequestAborted).ToListAsync(HttpContext.RequestAborted);
			var temp = new SeatsQualityGradeAnalyseDto()
			{
				NinetyGrade = temps.Sum(x => x.NinetyGrade),
			    EightyGrade = temps.Sum(x => x.EightyGrade),
				SeventyGrade = temps.Sum(x => x.SeventyGrade),
				SixtyGrade = temps.Sum(x => x.SixtyGrade),
				FiftyGrade = temps.Sum(x => x.FiftyGrade)
			};
			return temp;
		}


		/// <summary>
		/// 质检分值分析/坐席质检工单分析
		/// </summary>
		/// <param name="dto"></param>
		/// <returns></returns>
		[HttpGet("month_quality_grade")]
		public async Task<List<MonthQualityGradeDto>> MonthQualityGrade([FromQuery] QualityWorkAnalysisRequest dto)
		{
			var items = await _qualityApplication.MonthQualityGrade(dto, HttpContext.RequestAborted);
			return items;
		}


		/// <summary>
		/// 列表页面基础数据
		/// </summary>
		/// <returns></returns>
		[HttpGet("quality_work/base")]
		public async Task<object> QualityWorkBaseData()
		{
			var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi);
			var roles = setting?.SettingValue.ToList();
			var users = await _userRepository.Queryable()
				.Includes(d => d.Organization)
				.Includes(d => d.Roles)
				.Where(d => d.Roles.Any(x => roles.Contains(x.Name)))
				.Select(x => new Kv {
					Key = x.Id,
					Value = x.Name
				})
				.ToListAsync(HttpContext.RequestAborted);

			var rsp = new
			{
				Seats = users
			};
			return rsp;
		}
		#endregion
	}
}
