using Hotline.Application.ExportExcel;
using Hotline.Share.Tools;
using Hotline.Application.StatisticalReport;
using Hotline.Application.Systems;
using Hotline.Caching.Interfaces;
using Hotline.CallCenter.Calls;
using Hotline.CallCenter.Tels;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.TrCallCenter;
using Hotline.Share.Requests;
using Hotline.Tools;
using Hotline.Users;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System.Data;
using System.Linq.Dynamic.Core;
using XF.Domain.Repository;
using Hotline.Settings;
using XF.Utility.EnumExtensions;
using Hotline.Share.Enums.CallCenter;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Api.Filter;
using Hotline.Share.Dtos.Order.Publish;
using Hotline.Application.StatisticalReport.CallReport;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Wordprocessing;
using NPOI.SS.Formula.Functions;

namespace Hotline.Api.Controllers.Bi;

/// <summary>
/// 话务报表
/// </summary>
public class BiCallController : BaseController
{
    private readonly IRepository<TrCallRecord> _trCallRecordRepository;
    private readonly BaseDataApplication _baseDataApplication;
    private readonly IRepository<User> _userRepository;
    private readonly IRepository<TelRest> _telRestRepository;
    private readonly IMapper _mapper;
    private readonly ISystemSettingCacheManager _systemSettingCacheManager;
    private readonly IRepository<Work> _workRepository;
    private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
    private readonly ICallReportApplication _callReportApplication;
    private readonly IExportApplication _exportApplication;



    public BiCallController(
        IRepository<TrCallRecord> trCallRecordRepository,
        IRepository<User> userRepository,
        IRepository<TelRest> telRestRepository,
        IMapper mapper,
        ISystemSettingCacheManager systemSettingCacheManager,
        ISystemDicDataCacheManager sysDicDataCacheManager,
        IRepository<Work> workRepository,
        ICallReportApplication callReportApplication,
        IExportApplication exportApplication,
        BaseDataApplication baseDataApplication)
    {
        _trCallRecordRepository = trCallRecordRepository;
        _userRepository = userRepository;
        _telRestRepository = telRestRepository;
        _mapper = mapper;
        _systemSettingCacheManager = systemSettingCacheManager;
        _workRepository = workRepository;
        _sysDicDataCacheManager = sysDicDataCacheManager;
        _callReportApplication = callReportApplication;
        _exportApplication = exportApplication;
        _baseDataApplication = baseDataApplication;
    }

    /// <summary>
    /// 话务统计分析
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("calls")]
    [AllowAnonymous]
    public async Task<List<BiCallDto>> QueryCallsAsync([FromQuery] BiQueryCallsDto dto)
        => await _callReportApplication.QueryCallsAsync(dto, HttpContext.RequestAborted);

    /// <summary>
    /// 话务统计分析---导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("calls_export")]
    [LogFilterAlpha("导出日志")]
    [AllowAnonymous]
    public async Task<FileStreamResult> ExportQueryCallsAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
        => ExcelStreamResult(
            _exportApplication.GetExcelStream(
                dto,
                await _callReportApplication.QueryCallsAsync(dto.QueryDto, HttpContext.RequestAborted),
                list =>
                {
                    return new BiCallDto()
                    {
                        HourRange = "合计",
                        Hour = 13,
                        Total = list.Sum(p => p.Total),
                        Answered = list.Sum(p => p.Answered),
                        Hanguped = list.Sum(p => p.Hanguped)
                    };
                }),
            "话务统计分析");

    /// <summary>
    /// 话务日期统计
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query_calls_statistics")]
    public async Task<TotalList<QueryCallsDetailStatistics>> QueryCallsStatisticsAsync([FromQuery] StartEndTimeDto dto)
    {
        var items = await _callReportApplication.QueryCallsDetailStatisticsAsync(dto, HttpContext.RequestAborted);

        var total = new QueryCallsDetailStatistics
        {
            Date = "合计",
            //InTotal = items.Sum(m => m.InTotal),
            NotAcceptedHang = items.Sum(m => m.NotAcceptedHang),
            InConnectionQuantity = items.Sum(m => m.InConnectionQuantity),
            InNotAnswered = items.Sum(m => m.InNotAnswered),
            IvrByeCount = items.Sum(m => m.IvrByeCount),
            OutConnectionQuantity = items.Sum(m => m.OutConnectionQuantity),
            OutNotAnswered = items.Sum(m => m.OutNotAnswered)
        };

        return new TotalList<QueryCallsDetailStatistics>(items, total);
    }

    /// <summary>
    /// 话务日期统计-导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query_calls_statistics_export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryCallsStatisticsExportAsync([FromBody] ExportExcelDto<StartEndTimeDto> dto)
    {
        var items = (await _callReportApplication.QueryCallsDetailStatisticsAsync(dto.QueryDto, HttpContext.RequestAborted));
        return _exportApplication.GetExcelFile(dto, items, "话务日期统计", "Date");
    }

    /// <summary>
    /// 话务日期统计详情
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query_calls_statistics_detail")]
    public async Task<PagedDto<QueryCallsStatisticsDetailOutDto>> QueryCallsStatisticsDetailAsync([FromQuery] QueryCallsStatisticsDetailInDto dto)
        => (await _callReportApplication.QueryCallsStatisticsDetailAsync(dto, HttpContext.RequestAborted))
            .ToPaged();

    /// <summary>
    /// 话务日期统计详情--导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query_calls_statistics_detail/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryCallsStatisticsDetailAsync([FromBody] ExportExcelDto<QueryCallsStatisticsDetailInDto> dto)
    {
        var items = (await _callReportApplication.QueryCallsStatisticsDetailAsync(dto.QueryDto, HttpContext.RequestAborted)).Item2;
        return _exportApplication.GetExcelFile(dto, items, "话务日期统计详情", "OrderNo");
    }

    /// <summary>
    /// 话务日期统计详情页面基础数据
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query_calls_statistics_detail/base-data")]
    public Dictionary<string, dynamic> QueryCallsStatisticsDetailBaseData()
    {
        return new Dictionary<string, dynamic>
        {
            { "endBy", EnumExts.GetDescriptions<EEndBy>() }
        };
    }

    /// <summary>
    /// 话务日期明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query_calls_detail")]
    public async Task<object> QueryCallsDetailAsync([FromQuery] BiQueryCallsDto dto)
    {
        var items = await _callReportApplication.QueryCallsDetailAsync(dto);

        var total = new QueryCallsDetailDto
        {
            Date = "合计",
            Hour = "",
            InTotal = items.Sum(p => p.InTotal),
            InConnectionQuantity = items.Sum(p => p.InConnectionQuantity),
            NotAcceptedHang = items.Sum(p => p.NotAcceptedHang),
            TotalDurationIncomingCalls = items.Sum(p => p.TotalDurationIncomingCalls),
            InAvailableAnswer = items.Sum(p => p.InAvailableAnswer),
            InHangupImmediateWhenAnswered = items.Sum(p => p.InHangupImmediateWhenAnswered),
            TimeoutConnection = items.Sum(p => p.TimeoutConnection),
            TimeoutSuspension = items.Sum(p => p.TimeoutSuspension),
            QueueByeCount = items.Sum(p => p.QueueByeCount),
            IvrByeCount = items.Sum(p => p.IvrByeCount),
            OutTotal = items.Sum(p => p.OutTotal),
            OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
        };

        return new { List = items, Total = total };

    }

    /// <summary>
    /// 话务日期明细--导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query_calls_detail_export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryCallsDetailExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
    {
        return ExcelStreamResult(
            _exportApplication.GetExcelStream(
                dto,
                await _callReportApplication.QueryCallsDetailAsync(dto.QueryDto),
                items =>
                {
                    return new QueryCallsDetailDto
                    {
                        Date = "合计",
                        Hour = "",
                        InTotal = items.Sum(p => p.InTotal),
                        InConnectionQuantity = items.Sum(p => p.InConnectionQuantity),
                        NotAcceptedHang = items.Sum(p => p.NotAcceptedHang),
                        TotalDurationIncomingCalls = items.Sum(p => p.TotalDurationIncomingCalls),
                        InAvailableAnswer = items.Sum(p => p.InAvailableAnswer),
                        InHangupImmediateWhenAnswered = items.Sum(p => p.InHangupImmediateWhenAnswered),
                        TimeoutConnection = items.Sum(p => p.TimeoutConnection),
                        TimeoutSuspension = items.Sum(p => p.TimeoutSuspension),
                        QueueByeCount = items.Sum(p => p.QueueByeCount),
                        IvrByeCount = items.Sum(p => p.IvrByeCount),
                        OutTotal = items.Sum(p => p.OutTotal),
                        OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
                    };
                })
            , "话务日期明细数据");

    }

    /// <summary>
    /// 话务日期明细--呼入明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query_incall_calls_list")]
    public async Task<PagedDto<CallRecordOutDto>> GetInCallCallListAsync([FromQuery] BiQueryCallsDto dto)
    {
        var (total, items) = await _callReportApplication.QueryCallsDetailInTotalAsync(dto, false);
        return new PagedDto<CallRecordOutDto>(total, items);
    }

    /// <summary>
    /// 话务日期明细----导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query_incall_calls_list_export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> GetInCallCallListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
    {
        var (total, data) = await _callReportApplication.QueryCallsDetailInTotalAsync(dto.QueryDto, dto.IsExportAll);

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

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

        var stream = ExcelHelper.CreateStream(dtos);


        return ExcelStreamResult(
            _exportApplication.GetExcelStream(
            dto,
            (await _callReportApplication.QueryCallsDetailInTotalAsync(dto.QueryDto, dto.IsExportAll)).Item2
            ),
            dto.QueryDto.TypeCode == "2" ? "话务日期-接通明细数据" : "话务日期-总量明细数据");

    }

    /// <summary>
    /// 话务日期明细--时间段
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query_calls_hour_detail_list")]
    public async Task<TotalList<QueryCallsDetailDto>> QueryCallsHourDetailListAsync([FromQuery] BiQueryCallsDto dto)
    {
        var items = await _callReportApplication.QueryCallsHourDetailAsync(dto, HttpContext.RequestAborted);
        var total = new QueryCallsDetailDto
        {
            Date = "",
            Hour = "合计",
            InTotal = items.Sum(p => p.InTotal),
            InConnectionQuantity = items.Sum(p => p.InConnectionQuantity),
            NotAcceptedHang = items.Sum(p => p.NotAcceptedHang),
            TotalDurationIncomingCalls = items.Sum(p => p.TotalDurationIncomingCalls),
            InAvailableAnswer = items.Sum(p => p.InAvailableAnswer),
            InHangupImmediateWhenAnswered = items.Sum(p => p.InHangupImmediateWhenAnswered),
            TimeoutConnection = items.Sum(p => p.TimeoutConnection),
            TimeoutSuspension = items.Sum(p => p.TimeoutSuspension),
            QueueByeCount = items.Sum(p => p.QueueByeCount),
            IvrByeCount = items.Sum(p => p.IvrByeCount),
            OutTotal = items.Sum(p => p.OutTotal),
            OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
        };

        return new TotalList<QueryCallsDetailDto>(items, total);

    }

    /// <summary>
    /// 话务日期明细--时间段--导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query_calls_hour_detail_list_export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryCallsHourDetailListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
        => ExcelStreamResult(
            _exportApplication.GetExcelStream(
                dto,
                await _callReportApplication.QueryCallsHourDetailAsync(dto.QueryDto, HttpContext.RequestAborted),
                items =>
                {
                    return new QueryCallsDetailDto
                    {
                        Date = "",
                        Hour = "合计",
                        InTotal = items.Sum(p => p.InTotal),
                        InConnectionQuantity = items.Sum(p => p.InConnectionQuantity),
                        NotAcceptedHang = items.Sum(p => p.NotAcceptedHang),
                        TotalDurationIncomingCalls = items.Sum(p => p.TotalDurationIncomingCalls),
                        InAvailableAnswer = items.Sum(p => p.InAvailableAnswer),
                        InHangupImmediateWhenAnswered = items.Sum(p => p.InHangupImmediateWhenAnswered),
                        TimeoutConnection = items.Sum(p => p.TimeoutConnection),
                        TimeoutSuspension = items.Sum(p => p.TimeoutSuspension),
                        QueueByeCount = items.Sum(p => p.QueueByeCount),
                        IvrByeCount = items.Sum(p => p.IvrByeCount),
                        OutTotal = items.Sum(p => p.OutTotal),
                        OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
                    };
                })
            , "话务日期明细-时间段");


    /// <summary>
    /// 坐席话务统计分析
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("seats/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> ExportSeatss([FromBody] ExportExcelDto<ReportRequiredPagedRequest> dto)
    {
        return ExcelStreamResult(
            _exportApplication.GetExcelStream(
                dto,
                await _callReportApplication.QuerySeatCallAsync(dto.QueryDto, HttpContext.RequestAborted),
                list =>
                {
                    return new BiSeatCallsDto()
                    {
                        Name = "合计",
                        InTotal = list.Sum(p => p.InTotal),
                        InAnswered = list.Sum(p => p.InAnswered),
                        InHangupImmediate = list.Sum(p => p.InHangupImmediate),
                        InHanguped = list.Sum(m => m.InHanguped),
                        OutDurationAvg = list.Sum(m => m.OutDurationAvg),
                        InAvailableAnswer = list.Sum(m => m.InAvailableAnswer),
                        InHangupImmediateWhenAnswered = list.Sum(m => m.InHangupImmediateWhenAnswered),
                        OutTotal = list.Sum(m => m.OutTotal),
                        OutAnswered = list.Sum(m => m.OutAnswered),
                        LoginDuration = list.Sum(m => m.LoginDuration),
                        RestDuration = list.Sum(m => m.RestDuration),
                        InDurationAvg = list.Sum(m => m.InDurationAvg)
                    };
                })
            , "坐席话务统计分析");
    }

    /// <summary>
    /// 坐席话务统计分析
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("seats")]
    [AllowAnonymous]
    public async Task<TotalList<BiSeatCallsDto>> QuerySeatCallsAsync([FromQuery] ReportRequiredPagedRequest dto)
    {
        var items = await _callReportApplication.QuerySeatCallAsync(dto, HttpContext.RequestAborted);
        var total = new BiSeatCallsDto
        {
            Name="合计",                                                  // 坐席姓名
            UserId="",                                                    // 用户ID
            StaffNo="",                                                   // 工号
            TelNo="",                                                     // 分机号
            InTotal = items.Sum(m => m.InTotal),                          // 呼入总量 
            OutTotal = items.Sum(m => m.OutTotal),                        // 呼出总量
            InAnswered = items.Sum(m => m.InAnswered),                    // 呼入接通量
            OutAnswered = items.Sum(m => m.OutAnswered),                  // 呼出接通量
            InHangupImmediate = items.Sum(m => m.InHangupImmediate),      // 呼入秒挂
            InHanguped = items.Sum(m => m.InHanguped),                    // 呼入未接
            InDurationAvg = items.Sum(m => m.InDurationAvg),              // 呼入平均时长
            OutDurationAvg = items.Sum(m => m.OutDurationAvg),            // 呼出平均时长
            InAvailableAnswer = items.Sum(m => m.InAvailableAnswer),      // 有效接通量
            InHangupImmediateWhenAnswered = items.Sum(m => m.InHangupImmediateWhenAnswered),      // 呼入接通秒挂
            LoginDuration = items.Sum(m => m.LoginDuration),              // 登录时长（秒)
            RestDuration = items.Sum(m => m.RestDuration),                // 小休+摘机时长 (秒)
        };
        return new TotalList<BiSeatCallsDto>(items, total);
    }

    /// <summary>
    /// 坐席话务统计分析明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("seats/list")]
    public async Task<PagedDto<CallRecordOutDto>> QuerySeatCallsListAsync([FromQuery] BiQueryCallsListDto dto)
    {
        var (total, items) = await _callReportApplication.QuerySeatCallsListAsync(dto, false);
        return new PagedDto<CallRecordOutDto>(total, items);
    }

    /// <summary>
    /// 坐席话务统计分析明细导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("seats/list/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QuerySeatCallsListExportAsync([FromBody] ExportExcelDto<BiQueryCallsListDto> dto)
    {
        var (total, data) = await _callReportApplication.QuerySeatCallsListAsync(dto.QueryDto, dto.IsExportAll);

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

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

        var stream = ExcelHelper.CreateStream(dtos);


        return ExcelStreamResult(
            _exportApplication.GetExcelStream(
            dto,
            (await _callReportApplication.QuerySeatCallsListAsync(dto.QueryDto, dto.IsExportAll)).Item2
            ),
            "坐席话务统计分析明细");
    }


    /// <summary>
    /// 小休统计
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("rests")]
    [AllowAnonymous]
    public async Task<IReadOnlyList<BiSeatRestDto>> QuerySeatRest([FromQuery] QuerySeatRestRequest dto)
    {
        return await _telRestRepository.Queryable()
            .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
            .WhereIF(!string.IsNullOrEmpty(dto.StaffNo), x => x.StaffNo.Contains(dto.StaffNo))
            .Where(x => x.CreationTime >= dto.StartTime)
            .Where(x => x.CreationTime <= dto.EndTime)
            .GroupBy(x => new { x.UserId, x.StaffNo, x.UserName })
            .Select(x => new BiSeatRestDto
            {
                UserId = x.UserId,
                StaffNo = x.StaffNo,
                UserName = x.UserName,
                RestCount = SqlFunc.AggregateCount(x.Id),
                RestDuration = SqlFunc.AggregateSum(x.RestDuration / 60) / SqlFunc.AggregateCount(x.Id),
                CumulativeDuration = SqlFunc.AggregateSum(x.RestDuration / 60)
            })
            .OrderByIF(dto.SortRule is 0, a => a.RestDuration, OrderByType.Asc)
            .OrderByIF(dto.SortRule is 1, a => a.RestDuration, OrderByType.Desc)
            .MergeTable()
            .ToListAsync(HttpContext.RequestAborted);
    }

    /// <summary>
    /// 小休统计
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("rests/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QuerySeatRestExport([FromBody] ExportExcelDto<QuerySeatRestRequest> dto)
    {
        var query = await _telRestRepository.Queryable()
            .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.UserName), x => x.UserName.Contains(dto.QueryDto.UserName))
            .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.StaffNo), x => x.StaffNo.Contains(dto.QueryDto.StaffNo))
            .Where(x => x.CreationTime >= dto.QueryDto.StartTime)
            .Where(x => x.CreationTime <= dto.QueryDto.EndTime)
            .GroupBy(x => new { x.UserId, x.StaffNo, x.UserName })
            .Select(x => new BiSeatRestDto
            {
                UserId = x.UserId,
                StaffNo = x.StaffNo,
                UserName = x.UserName,
                RestCount = SqlFunc.AggregateCount(x.Id),
                RestDuration = SqlFunc.AggregateSum(x.RestDuration / 60) / SqlFunc.AggregateCount(x.Id),
                CumulativeDuration = SqlFunc.AggregateSum(x.RestDuration / 60)
            })
            .OrderByIF(dto.QueryDto.SortRule is 0, a => a.RestDuration, OrderByType.Asc)
            .OrderByIF(dto.QueryDto.SortRule is 1, a => a.RestDuration, OrderByType.Desc)
            .MergeTable()
            .ToListAsync(HttpContext.RequestAborted);

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

        var dtos = _mapper.Map<ICollection<BiSeatRestDto>>(query)
                          .Select(stu => _mapper.Map(stu, typeof(BiSeatRestDto), dynamicClass))
                          .Cast<object>()
                          .ToList();

        var stream = ExcelHelper.CreateStream(dtos);
        return ExcelStreamResult(stream, "座席小休统计表");
    }

    /// <summary>
    /// 坐席转接统计
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("seatswitch")]
    [AllowAnonymous]
    public async Task<PagedDto<BiSeatSwitchDto>> QuerySeatSwitch([FromQuery] QuerySeatSwitchRequest dto)
    {
        var (total, items) = await _callReportApplication.QuerySeatSwitchAsync(dto, false, HttpContext.RequestAborted);
        return new PagedDto<BiSeatSwitchDto>(total, items);
    }

    /// <summary>
    /// 坐席转接统计导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("seatswitch/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QuerySeatSwitchExport([FromBody] ExportExcelDto<QuerySeatSwitchRequest> dto)
    {
        var (total, items) = await _callReportApplication.QuerySeatSwitchAsync(dto.QueryDto, dto.IsExportAll, HttpContext.RequestAborted);

        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<BiSeatSwitchDto>(dto.ColumnInfos);
        var dtos = _mapper.Map<ICollection<BiSeatSwitchDto>>(items)
                          .Select(stu => _mapper.Map(stu, typeof(BiSeatSwitchDto), dynamicClass))
                          .Cast<object>()
                          .ToList();
        var stream = ExcelHelper.CreateStream(dtos);
        return ExcelStreamResult(stream, "转外线统计分析");
    }



    /// <summary>
    /// 小时统计
    /// </summary>
    /// <returns></returns>
    [HttpGet("hourcall")]
    [AllowAnonymous]
    public async Task<List<TrCallHourDto>> QueryHourCall([FromQuery] BiQueryHourCallDto dto)
        => await _callReportApplication.GetCallHourListAsync(dto, HttpContext.RequestAborted);

    /// <summary>
    /// 小时统计--导出
    /// </summary>
    /// <returns></returns>
    [HttpPost("hourcall/export")]
    [LogFilterAlpha("导出日志")]
    [AllowAnonymous]
    public async Task<FileStreamResult> ExportQueryHourCall([FromBody] ExportExcelDto<BiQueryHourCallDto> dto)
        => ExcelStreamResult(
            _exportApplication.GetExcelStream(
                dto,
                await _callReportApplication.GetCallHourListAsync(dto.QueryDto, HttpContext.RequestAborted),
                list =>
                {
                    return new TrCallHourDto()
                    {
                        HourTo = "合计",
                        EffectiveCount = list.Sum(p => p.EffectiveCount),
                        ConnectByeCount = list.Sum(p => p.ConnectByeCount),
                        NoConnectByeCount = list.Sum(p => p.NoConnectByeCount),
                        QueueByeCount = list.Sum(m => m.QueueByeCount),
                        IvrByeCount = list.Sum(m => m.IvrByeCount)
                    };
                })
            , "通话时段分析");


    /// <summary>
    /// 通话时段统计明细
    /// </summary>
    /// <returns></returns>
    [HttpGet("hourcall_list")]
    public async Task<PagedDto<BiSeatSwitchDto>> QueryCallList([FromQuery] QueryCallListDto dto)
    {
        var res = await _callReportApplication.GetCallListAsync(dto, HttpContext.RequestAborted);
        return new PagedDto<BiSeatSwitchDto>(res.Total, res.Data);
    }

    /// <summary>
    /// 通话时段统计明细 导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("hourcall_list/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> ExportQueryCallList([FromBody] ExportExcelDto<QueryCallListDto> dto)
    {
        foreach (var item in dto.ColumnInfos)
        {
            if (item.Prop == "cpn" || item.Prop == "cdpn")
            {
                item.Prop = item.Prop.ToUpper();
            }
        }
        return ExcelStreamResult(
          _exportApplication.GetExcelStream(
              dto,
              (await _callReportApplication.GetCallListAsync(dto.QueryDto, HttpContext.RequestAborted)).Data)
          , "通话时段分析");
    }

    /// <summary>
    /// 通话时段统计明细获取基本信息
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("hourcall_list_base")]
    public async Task<object> ReTransactBaseData()
    {
        var rsp = new
        {
            CallForwardingSource = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.CallForwardingSource),
            CallForwardingType = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.CallForwardingType),
        };
        return rsp;
    }

    /// <summary>
    /// 热线号码统计
    /// </summary>
    /// <param name="StartTime"></param>
    /// <param name="EndTime"></param>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet("gateway-query")]
    public async Task<List<CallHotLineDto>> QueryGateWay([FromQuery] BiQueryGateWayDto dto)
        => await _callReportApplication.GetCallHotLineListAsync(dto, HttpContext.RequestAborted);

    /// <summary>
    /// 热线号码统计导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("gateway-query/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> ExportQueryGatetWay(ExportExcelDto<BiQueryGateWayDto> dto)
        => ExcelStreamResult(
            _exportApplication.GetExcelStream(
                dto,
                await _callReportApplication.GetCallHotLineListAsync(dto.QueryDto, HttpContext.RequestAborted)
                )
            , "热线号码统计");


    #region 宜宾话务表

    /// <summary>
    /// 话务日期统计明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query-calldate-statistics")]
    public async Task<object> QueryCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
    {
        var list = await _callReportApplication.QueryCallDateStatisticsDetail(dto);

        var total = new QueryCallDateStatisticsDetailResp()
        {
            Date = "合计",
            IvrCallInTotal = list.Sum(x => x.IvrCallInTotal),
            PersonCallInCount = list.Sum(x => x.PersonCallInCount),
            EnterpriseCallInCount = list.Sum(x => x.EnterpriseCallInCount),
            GaoXiaoCallInCount = list.Sum(x => x.GaoXiaoCallInCount), //高效办成一件事
            AiCallInCount = list.Sum(x => x.AiCallInCount),
            PersonCallInPutthroughCount = list.Sum(x => x.PersonCallInPutthroughCount),
            EnterpriseCallInPutthroughCount = list.Sum(x => x.EnterpriseCallInPutthroughCount),
            GaoXiaoCallInPutthroughCount = list.Sum(x => x.GaoXiaoCallInPutthroughCount),
            AiCallInPutthroughCount = list.Sum(x => x.AiCallInPutthroughCount),
            PersonRingOffCount = list.Sum(x => x.PersonRingOffCount),//个人服务挂断
            EnterpriseRingOffCount = list.Sum(x => x.EnterpriseRingOffCount), //企业挂断
            GaoXiaoRingOffCount = list.Sum(x => x.GaoXiaoRingOffCount),
            IvrRingOffCount = list.Sum(x => x.IvrRingOffCount), //IVR挂断
        };

        return new { List = list, Total = total };
    }

    /// <summary>
    /// 话务日期统计明细导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query-calldate-statistics/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
         =>
            _exportApplication.GetExcelFile(
                dto,
                await _callReportApplication.QueryCallDateStatisticsDetail(dto.QueryDto)
            , "话务日期统计明细", "Date");

    /// <summary>
    /// 个人服务话务明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query-person-calldate-statistics")]
    public async Task<object> QueryPersonCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
    {
        var list = await _callReportApplication.QueryPersonCallDateStatisticsDetail(dto);
        var total = new QueryPersonCallDateStatisticsDetailResp()
        {
            Date = "合计",
            PersonCallInCount = list.Sum(x => x.PersonCallInCount),
            PersonCallInPutthroughCount = list.Sum(x => x.PersonCallInPutthroughCount),
            //PersonRingOffCount = list.Sum(x=>x.PersonRingOffCount),//个人服务挂断
            PersonQueueOffCount = list.Sum(x => x.PersonQueueOffCount),//个人服务队列挂断
            PersonWaitOffCount = list.Sum(x => x.PersonWaitOffCount) //个人服务等待挂断
        };
        return new { List = list, Total = total };
    }

    /// <summary>
    /// 个人服务话务明细导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query-person-calldate-statistics/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryPersonCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
     => _exportApplication.GetExcelFile(
                dto,
                await _callReportApplication.QueryPersonCallDateStatisticsDetail(dto.QueryDto)
            , "个人服务话务明细", "Date");


    /// <summary>
    /// 企业服务话务明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query-enterprise-calldate-statistics")]
    public async Task<object> QueryEnterpriseCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
    {
        var list = await _callReportApplication.QueryEnterpriseCallDateStatisticsDetail(dto);
        var total = new QueryEnterpriseCallDateStatisticsDetailResp()
        {
            Date = "合计",
            EnterpriseCallInCount = list.Sum(x => x.EnterpriseCallInCount),
            EnterpriseCallInPutthroughCount = list.Sum(x => x.EnterpriseCallInPutthroughCount),
            //EnterpriseRingOffCount = list.Sum(x=>x.EnterpriseRingOffCount), //企业挂断
            EnterpriseQueueOffCount = list.Sum(x => x.EnterpriseQueueOffCount),//个人服务队列挂断
            EnterpriseWaitOffCount = list.Sum(x => x.EnterpriseWaitOffCount) //个人服务等待挂断
        };
        return new { List = list, Total = total };
    }

    /// <summary>
    /// 企业服务话务明细导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query-enterprise-calldate-statistics/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryEnterpriseCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
    => _exportApplication.GetExcelFile(
                dto,
                await _callReportApplication.QueryEnterpriseCallDateStatisticsDetail(dto.QueryDto)
            , "企业服务话务明细", "Date");

    /// <summary>
    /// 高效服务话务明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query-gaoxiao-calldate-statistics")]
    public async Task<object> QueryGaoXiaoCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
    {
        var list = await _callReportApplication.QueryGaoXiaoCallDateStatisticsDetail(dto);
        var total = new QueryGaoXiaoCallDateStatisticsDetailResp()
        {
            Date = "合计",
            GaoXiaoCallInCount = list.Sum(x => x.GaoXiaoCallInCount),
            GaoXiaoCallInPutthroughCount = list.Sum(x => x.GaoXiaoCallInPutthroughCount),
            GaoXiaoQueueOffCount = list.Sum(x => x.GaoXiaoQueueOffCount),//企业服务队列挂断
            GaoXiaoWaitOffCount = list.Sum(x => x.GaoXiaoWaitOffCount) //企业服务等待挂断
        };
        return new { List = list, Total = total };
    }

    /// <summary>
    /// 高效服务话务明细导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query-gaoxiao-calldate-statistics/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryGaoXiaoCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
    => _exportApplication.GetExcelFile(
                dto,
                await _callReportApplication.QueryGaoXiaoCallDateStatisticsDetail(dto.QueryDto)
            , "高效服务话务明细", "Date");

    /// <summary>
    /// 呼出话务统计明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query-callout-date-statistics")]
    public async Task<object> QueryCallOutDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
    {
        List<string> enterpriseTels = _systemSettingCacheManager.GetSetting(SettingConstants.EnterpriseTel)?.SettingValue;
        var list = await _callReportApplication.QueryCallOutDateStatisticsDetail(dto, enterpriseTels);

        var total = new QueryCallOutDateStatisticsDetailResp()
        {
            Date = "合计",
            PersonCallOutCount = list.Sum(x => x.PersonCallOutCount),
            EnterpriseCallOutCount = list.Sum(x => x.EnterpriseCallOutCount),
            AiVisitCallOutCount = list.Sum(x => x.AiVisitCallOutCount),
            AiCallOutCount = list.Sum(x => x.AiCallOutCount),
            PersonCallOutPutthroughCount = list.Sum(x => x.PersonCallOutPutthroughCount),
            EnterpriseCallOutPutthroughCount = list.Sum(x => x.EnterpriseCallOutPutthroughCount),
            AiVisitCallOutPutthroughCount = list.Sum(x => x.AiVisitCallOutPutthroughCount),
            AiCallOutPutthroughCount = list.Sum(x => x.AiCallOutPutthroughCount)
        };

        return new { List = list, Total = total };
    }


    /// <summary>
    /// 呼出话务统计明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query-callout-date-statistics/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QueryCallOutDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
    {
        List<string> enterpriseTels = _systemSettingCacheManager.GetSetting(SettingConstants.EnterpriseTel)?.SettingValue;

        return _exportApplication.GetExcelFile(
                dto,
                await _callReportApplication.QueryCallOutDateStatisticsDetail(dto.QueryDto, enterpriseTels)
            , "呼出话务统计明细", "Date");
    }

    /// <summary>
    /// 坐席月接通率统计
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query-seat-monthcall")]
    public async Task<object> QuerySeatMonthCall([FromQuery] QuerySeatMonthCallRequest dto)
    {
        var list = await _callReportApplication.QuerySeatMonthCall(dto);
        var total = new QuerySeatMonthCallResp()
        {
            Name = "合计",
            InAnswered = list.Sum(x => x.InAnswered),
            InAvailableAnswer = list.Sum(x => x.InAvailableAnswer),
            InHangupImmediateWhenAnswered = list.Sum(x => x.InHangupImmediateWhenAnswered),
            OverTimeImmediate = list.Sum(x => x.OverTimeImmediate),
            InTimeImmediate = list.Sum(x => x.InTimeImmediate),
            InHanguped = list.Sum(x => x.InHanguped),
            InHangupImmediate = list.Sum(x => x.InHangupImmediate),
            OverTimeInHanguped = list.Sum(x => x.OverTimeInHanguped),
        };

        return new { List = list, Total = total };
    }

    /// <summary>
    /// 坐席月接通率统计基础数据
    /// </summary>
    /// <returns></returns>
    [HttpGet("query-seat-monthcall-basedata")]
    public async Task<object> QuerySeatMonthCallBaseData()
    {
        var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi).SettingValue;

        return new
        {
            SeatUser = await _userRepository.Queryable().Includes(d => d.Roles).Where(d => d.Roles.Any(x => setting.Contains(x.Name))).ToListAsync()
        };
    }

    /// <summary>
    /// 坐席月接通率统计导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query-seat-monthcall/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QuerySeatMonthCallExport([FromBody] ExportExcelDto<QuerySeatMonthCallRequest> dto)
    => _exportApplication.GetExcelFile(
            dto,
            await _callReportApplication.QuerySeatMonthCall(dto.QueryDto)
            , "坐席月接通率统计", "Name");


    /// <summary>
    /// 坐席月接通明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpGet("query-seat-monthcall-detail")]
    public async Task<PagedDto<QuerySeatMonthCallDetailResp>> QuerySeatMonthCallDetail([FromQuery] QuerySeatMonthCallDetailRequest dto)
    {
        var query = _callReportApplication.QuerySeatMonthCallDetail(dto);
        var (total, items) = await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
        return new PagedDto<QuerySeatMonthCallDetailResp>(total, items);
    }

    /// <summary>
    /// 坐席月接通明细导出
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("query-seat-monthcall-detail/export")]
    [LogFilterAlpha("导出日志")]
    public async Task<FileStreamResult> QuerySeatMonthCallDetailExport([FromBody] ExportExcelDto<QuerySeatMonthCallDetailRequest> dto)
    {
        var query = _callReportApplication.QuerySeatMonthCallDetail(dto.QueryDto);
        List<QuerySeatMonthCallDetailResp> data;
        if (dto.IsExportAll)
        {
            data = await query.ToListAsync(HttpContext.RequestAborted);
        }
        else
        {
            var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
            data = items;
        }

        var dataDtos = _mapper.Map<ICollection<QuerySeatMonthCallDetailResp>>(data);

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

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

        var stream = ExcelHelper.CreateStream(dtos);

        return ExcelStreamResult(stream, "坐席月接通明细");
    }

    #endregion
}
