using Hotline.Caching.Interfaces;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.CallCenter.Calls;
using Hotline.CallCenter.Tels;
using Hotline.DI;
using Hotline.Repository.SqlSugar.CallCenter;
using Hotline.Settings;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Share.Dtos.TrCallCenter;
using Hotline.Share.Enums.CallCenter;
using Hotline.Share.Enums.User;
using Hotline.Share.Requests;
using Hotline.Users;
using SqlSugar;
using XF.Domain.Dependency;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using Microsoft.AspNetCore.Http;
using Hotline.Share.Dtos;
using MapsterMapper;
using System.Threading;
using NPOI.SS.Formula.Functions;

namespace Hotline.Application.StatisticalReport.CallReport;

[Injection(AppScopes = EAppScope.YiBin)]
public class YiBinCallReportApplication : CallReportApplicationBase, ICallReportApplication, IScopeDependency
{
    private readonly IRepository<TrCallRecord> _trCallRecordRepository;
    private readonly IMapper _mapper;
    private readonly ITrCallRecordRepository _trCallRecordRepositoryEx;
    private readonly ISystemSettingCacheManager _systemSettingCacheManager;
    private readonly IRepository<User> _userRepository;
    private readonly IRepository<Work> _workRepository;
    private readonly IRepository<TelRest> _telRestRepository;
    private readonly ICallNativeRepository _callNativeRepository;

    public YiBinCallReportApplication(
        IRepository<TrCallRecord> trCallRecordRepository,
        ISystemSettingCacheManager systemSettingCacheManager,
        IRepository<User> userRepository,
        IRepository<Work> workRepository,
        IRepository<TelRest> telRestRepository,
        ICallNativeRepository callNativeRepository,
        ITrCallRecordRepository trCallRecordRepositoryEx,
        IMapper mapper,
        ISystemDicDataCacheManager systemDicDataCacheManager) : base(systemSettingCacheManager, callNativeRepository, userRepository, workRepository, telRestRepository, systemDicDataCacheManager)
    {
        _trCallRecordRepository = trCallRecordRepository;
        _systemSettingCacheManager = systemSettingCacheManager;
        _userRepository = userRepository;
        _workRepository = workRepository;
        _telRestRepository = telRestRepository;
        _callNativeRepository = callNativeRepository;
        _trCallRecordRepositoryEx = trCallRecordRepositoryEx;
        _mapper = mapper;
    }

    public override async Task<List<BiCallDto>> QueryCallsAsync(BiQueryCallsDto dto, CancellationToken cancellationToken)
    {
        return await _trCallRecordRepositoryEx.GetQueryCalls(dto.StartTime.Value, dto.EndTime.Value, dto.Keyword);
    }

    /// <summary>
    /// 话务日期明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override async Task<List<QueryCallsDetailDto>> QueryCallsDetailAsync(BiQueryCallsDto dto)
    {
        //超时接通量
        int CallInOverConnRingTime = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.CallInOverConnRingTime)?.SettingValue[0]);
        //坐席超时挂断时间
        int SeatChaoTime = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.SeatChaoTime)?.SettingValue[0]);
        //未接秒挂时间
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        //呼入有效时间
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        //接通秒挂时间
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;

        var callData = await _trCallRecordRepository.Queryable()
                .Where(p => p.CreatedTime >= dto.StartTime && p.CreatedTime <= dto.EndTime)
                 // .Where(p => p.Gateway != "82826886" && SqlFunc.Length(p.Gateway) != 4)
                 .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Gateway == dto.Keyword)
                 .GroupBy(p => p.CreatedTime.ToString("yyyy-MM-dd"))
                .Select(p => new QueryCallsDetailDto
                {
                    Date = p.CreatedTime.ToString("yyyy-MM-dd"),
                    InTotal = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In, 1, 0)),//呼入总量
                    InConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.In && p.AnsweredTime != null, 1, 0)),//呼入接通量
                    NotAcceptedHang = SqlFunc.AggregateSum(SqlFunc.IIF(p.Duration == 0 && p.RingTimes <= noConnectByeTimes && p.RingTimes > 0 && p.CallDirection == ECallDirection.In, 1, 0)), //未接通秒挂
                    TotalDurationIncomingCalls = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.OnState == EOnState.On, p.Duration, 0)), //呼入总时长
                    InAvailableAnswer = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration >= effectiveTimes, 1, 0)),//有效接通量
                    InHangupImmediateWhenAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.Duration > 0 && p.Duration <= connectByeTimes, 1, 0)), //呼入接通秒挂
                    TimeoutConnection = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.RingTimes >= CallInOverConnRingTime, 1, 0)),//超时接通量
                    TimeoutSuspension = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration >= SeatChaoTime, 1, 0)),//超时挂断量
                    QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.QueueTims > 0 && p.RingTimes == 0 && p.OnState == EOnState.NoOn, 1, 0)), //队列挂断
                    IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.BeginIvrTime.HasValue && !p.BeginQueueTime.HasValue && !p.BeginRingTime.HasValue && p.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
                    OutTotal = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.Out, 1, 0)),//呼出总量
                    OutConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.Out && p.AnsweredTime != null, 1, 0))
                })
                .OrderBy(p => p.Date)
                .ToListAsync();

        return callData;
    }

    /// <summary>
    /// 话务日期明细-呼入总量/接通总量
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override async Task<(int, List<CallRecordOutDto>)> QueryCallsDetailInTotalAsync(BiQueryCallsDto dto, bool isAll)
    {
        var query = _trCallRecordRepository.Queryable()
                 .Includes(p => p.Order)
                .Where(p => p.CreatedTime >= dto.StartTime && p.CreatedTime <= dto.EndTime && p.CallDirection == ECallDirection.In)
                .WhereIF(dto.TypeCode == "2", p => p.OnState == EOnState.On && p.AnsweredTime != null)
                 .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Gateway == dto.Keyword)
                 .OrderByDescending(p => p.CreatedTime)
                 .Select(m => new CallRecordOutDto()
                 {
                     FromNo = m.CPN,
                     ToNo = m.CDPN,
                     Direction = m.CallDirection,
                     EndTime = m.OverTime,
                     OrderId = m.Order.Id,
                     OrderTitle = m.Order.Title,
                     OrderNo = m.Order.No,
                     CreatedTime = m.CreationTime
                 }, true);
        if (isAll)
        {
            return (0, await query.ToListAsync());
        }
        return await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
    }

    /// <summary>
    /// 话务日期明细-呼入总量/接通总量
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public virtual async Task<(int, List<CallRecordOutDto>)> QuerySeatCallsListAsync(BiQueryCallsListDto dto, bool isAll)
    {
        //获取配置
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
        int ringTims = _systemSettingCacheManager.RingTimes;
        var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi).SettingValue;

        var recordPrefix = _systemSettingCacheManager.RecordPrefix;
        var query = _trCallRecordRepository.Queryable()
                 .Includes(p => p.Order)
                 .LeftJoin<User>((p, u) => p.UserId == u.Id && !u.IsDeleted)
                 .Where((p, u) => p.CreatedTime >= dto.StartTime && p.CreatedTime <= dto.EndTime)
                 .Where((p, u) => u.Roles.Any(x => setting.Contains(x.Name)))
                 .WhereIF(!string.IsNullOrEmpty(dto.UserId), (p, u) => p.UserId == dto.UserId)
                 .WhereIF(!string.IsNullOrEmpty(dto.UserName), (p, u) => p.UserName == dto.UserName)
                 .WhereIF(dto.FieldName == "inTotal", (p, u) => p.CallDirection == ECallDirection.In)                                                                                   //呼入总量
                 .WhereIF(dto.FieldName == "inAnswered", (p, u) => p.CallDirection == ECallDirection.In && p.AnsweredTime != null)                                                      //接通总量
                 .WhereIF(dto.FieldName == "inHangupImmediate", (p, u) => p.CallDirection == ECallDirection.In && p.AnsweredTime == null && p.RingTimes < noConnectByeTimes)            //呼入秒挂
                 .WhereIF(dto.FieldName == "inHanguped", (p, u) => p.CallDirection == ECallDirection.In && p.AnsweredTime == null && p.RingTimes > ringTims)                            //呼入超时未接
                 .WhereIF(dto.FieldName == "inAvailableAnswer", (p, u) => p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration >= effectiveTimes)               //有效接通量
                 .WhereIF(dto.FieldName == "inHangupImmediateWhenAnswered", (p, u) => p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration < connectByeTimes)   //接通秒挂
                 .WhereIF(dto.FieldName == "outTotal", (p, u) => p.CallDirection == ECallDirection.Out)                                                                                 //呼出总量
                 .WhereIF(dto.FieldName == "outAnswered", (p, u) => p.CallDirection == ECallDirection.Out && p.AnsweredTime != null)                                                    //呼出接通量
                 .OrderByDescending((p, u) => p.BeginIvrTime)
                 .Select(p => new CallRecordOutDto()
                 {
                     FromNo = p.CPN,
                     ToNo = p.CDPN,
                     Direction = p.CallDirection,
                     EndTime = p.OverTime,
                     OrderId = p.Order.Id,
                     OrderTitle = p.Order.Title,
                     OrderNo = p.Order.No,
                     CreatedTime = p.CreationTime
                 }, true);

        if (isAll)
        {
            return (0, await query.ToListAsync());
        }
        return await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
    }

    /// <summary>
    /// 坐席话务统计分析
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override async Task<List<BiSeatCallsDto>> QuerySeatCallAsync(ReportRequiredPagedRequest dto, CancellationToken cancellationToken)
    {
        //获取配置
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
        int ringTims = _systemSettingCacheManager.RingTimes;
        var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi).SettingValue;

        var list = await _userRepository.Queryable()
           .Includes(u => u.Roles)
              .LeftJoin<TrCallRecord>((u, c) => u.Id == c.UserId)
              .Where((u, c) => u.Roles.Any(x => setting.Contains(x.Name)))
              .Where(u => !u.IsDeleted)
              .Where((u, c) => c.CreatedTime >= dto.StartTime)
              .Where((u, c) => c.CreatedTime <= dto.EndTime)
              .GroupBy((u, c) => new { c.UserName, c.UserId })
              .Select((u, c) => new BiSeatCallsDto
              {
                  Name = c.UserName,
                  UserId = c.UserId,
                  InTotal = SqlFunc.AggregateSum(SqlFunc.IIF(c.CallDirection == ECallDirection.In, 1, 0)),
                  OutTotal = SqlFunc.AggregateSum(SqlFunc.IIF(c.CallDirection == ECallDirection.Out, 1, 0)),
                  InAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(c.CallDirection == ECallDirection.In && c.AnsweredTime != null, 1, 0)),
                  OutAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(c.CallDirection == ECallDirection.Out && c.AnsweredTime != null, 1, 0)),
                  InHangupImmediate = SqlFunc.AggregateSum(SqlFunc.IIF(c.CallDirection == ECallDirection.In && c.AnsweredTime == null && c.RingTimes < noConnectByeTimes, 1, 0)),
                  InHanguped = SqlFunc.AggregateSum(SqlFunc.IIF(c.CallDirection == ECallDirection.In && c.AnsweredTime == null && c.RingTimes > ringTims, 1, 0)),
                  InDurationAvg = SqlFunc.Ceil(SqlFunc.AggregateAvg(SqlFunc.IIF(c.CallDirection == ECallDirection.In && c.AnsweredTime != null, c.Duration, 0))),
                  OutDurationAvg = SqlFunc.Ceil(SqlFunc.AggregateAvg(SqlFunc.IIF(c.CallDirection == ECallDirection.Out && c.AnsweredTime != null, c.Duration, 0))),
                  InAvailableAnswer = SqlFunc.AggregateSum(SqlFunc.IIF(c.CallDirection == ECallDirection.In && c.AnsweredTime != null && c.Duration >= effectiveTimes, 1, 0)),
                  InHangupImmediateWhenAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(c.CallDirection == ECallDirection.In && c.AnsweredTime != null && c.Duration < connectByeTimes, 1, 0)),
              })
              .MergeTable()
              .ToListAsync(cancellationToken);


        list.ForEach(d =>
        {
            d.LoginDuration = _workRepository.Queryable().Where(q => q.UserId == d.UserId && q.CreationTime >= dto.StartTime && q.CreationTime <= dto.EndTime).Sum(q => q.WorkingDuration);
            if (d.LoginDuration != null)
            {
                d.LoginDuration = Math.Round(d.LoginDuration.Value, digits: 2);
            }
            d.RestDuration = _telRestRepository.Queryable().Where(q => q.UserId == d.UserId && q.CreationTime >= dto.StartTime && q.CreationTime <= dto.EndTime).Sum(q => q.RestDuration);
            d.RestDuration = Math.Round(d.RestDuration, digits: 2);
        });


        return list;
    }

    public override async Task<List<QueryCallsDetailDto>> QueryCallsHourDetailAsync(BiQueryCallsDto dto, CancellationToken cancellationToken)
    {
        //超时接通量
        int CallInOverConnRingTime = _systemSettingCacheManager.CallInOverConnRingTime;
        //坐席超时挂断时间
        int SeatChaoTime = _systemSettingCacheManager.SeatChaoTime;
        //未接秒挂时间
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        //呼入有效时间
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        //接通秒挂时间
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
        return await _trCallRecordRepositoryEx.QueryCallsHourDetail(dto.StartTime.Value, dto.EndTime.Value, noConnectByeTimes, effectiveTimes
              , connectByeTimes, CallInOverConnRingTime, SeatChaoTime, dto.Keyword);
    }

    public override async Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, bool isAll, CancellationToken cancellationToken)
    {
        var query = _trCallRecordRepository.Queryable()
                      .Where(x => !string.IsNullOrEmpty(x.AgentTransferNumber))
                      .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
                      .WhereIF(!string.IsNullOrEmpty(dto.CDPN), x => x.CDPN.Contains(dto.CDPN))
                      .Where(x => x.CreatedTime >= dto.StartTime)
                      .Where(x => x.CreatedTime <= dto.EndTime)
                      .Select(x => new BiSeatSwitchDto
                      {
                          UserId = x.UserId,
                          CPN = x.CPN,
                          CDPN = x.CDPN,
                          CreatedTime = x.CreatedTime,
                          TelNo = x.AgentTransferNumber,
                          UserName = x.UserName,
                      })
                      .OrderByDescending(x => x.CreatedTime);

        if (isAll)
        {
            return (0, await query.ToListAsync(cancellationToken));
        }
        return await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, cancellationToken);
    }

    public override async Task<List<TrCallHourDto>> GetCallHourListAsync(BiQueryHourCallDto dto, CancellationToken requestAborted)
    {
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
        return await _trCallRecordRepositoryEx.GetCallHourList(dto.StartTime, dto.EndTime, noConnectByeTimes, effectiveTimes, connectByeTimes, dto.Source);
    }

    public override async Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, CancellationToken requestAborted)
    {
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
        var ringTims = _systemSettingCacheManager.RingTimes;
        return await _trCallRecordRepositoryEx.GetCallHotLineList(dto.StartTime, dto.EndTime, dto.Gateway, noConnectByeTimes, effectiveTimes, connectByeTimes, ringTims); ;
    }

    public override Task<TotalData<BiSeatSwitchDto>> GetCallListAsync(QueryCallListDto dto, CancellationToken requestAborted)
    {
        //获取配置
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
        var list = _trCallRecordRepositoryEx.GetCallList(dto, noConnectByeTimes, effectiveTimes, connectByeTimes);
        return list;
    }

    /// <summary>
    /// 话务日期统计明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override async Task<List<QueryCallDateStatisticsDetailResp>> QueryCallDateStatisticsDetail(QueryCallDateStatisticsDetailDto dto)
    {
        return await _trCallRecordRepositoryEx.QueryCallDateStatisticsDetail(dto.StartTime.Value, dto.EndTime.Value);
    }

    /// <summary>
    /// 个人服务话务明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override async Task<List<QueryPersonCallDateStatisticsDetailResp>> QueryPersonCallDateStatisticsDetail(QueryCallDateStatisticsDetailDto dto)
    {
        return await _trCallRecordRepositoryEx.QueryPersonCallDateStatisticsDetail(dto.StartTime.Value, dto.EndTime.Value);
    }

    /// <summary>
    /// 企业服务话务明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override async Task<List<QueryEnterpriseCallDateStatisticsDetailResp>> QueryEnterpriseCallDateStatisticsDetail(QueryCallDateStatisticsDetailDto dto)
    {
        return await _trCallRecordRepositoryEx.QueryEnterpriseCallDateStatisticsDetail(dto.StartTime.Value, dto.EndTime.Value);
    }

    /// <summary>
    /// 高效服务话务明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override async Task<List<QueryGaoXiaoCallDateStatisticsDetailResp>> QueryGaoXiaoCallDateStatisticsDetail(QueryCallDateStatisticsDetailDto dto)
    {
        return await _trCallRecordRepositoryEx.QueryGaoXiaoCallDateStatisticsDetail(dto.StartTime.Value, dto.EndTime.Value);
    }

    /// <summary>
    /// 呼出话务统计明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override async Task<List<QueryCallOutDateStatisticsDetailResp>> QueryCallOutDateStatisticsDetail(QueryCallDateStatisticsDetailDto dto, List<string> enterpriseTels)
    {
        return await _trCallRecordRepositoryEx.QueryCallOutDateStatisticsDetail(dto.StartTime.Value, dto.EndTime.Value, enterpriseTels);
    }

    public override async Task<List<QuerySeatMonthCallResp>> QuerySeatMonthCall(QuerySeatMonthCallRequest dto)
    {
        //获取配置
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
        int ringTimes = _systemSettingCacheManager.RingTimes;
        var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi).SettingValue;

        var list = await _userRepository.Queryable()
              .Includes(u => u.Roles)
              .LeftJoin<TrCallRecord>((u, c) => u.Id == c.UserId)
              .Where((u, c) => u.Roles.Any(x => setting.Contains(x.Name)))
              .Where(u => !u.IsDeleted)
              .Where((u, c) => c.BeginRingTime >= dto.StartTime)
              .Where((u, c) => c.BeginRingTime <= dto.EndTime)
              .Where((u, c) => c.CallDirection == ECallDirection.In)
              .GroupBy((u, c) => new { c.UserName, c.UserId })
              .Select((u, c) => new QuerySeatMonthCallResp
              {
                  Name = c.UserName,
                  UserId = c.UserId,
                  InAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime != null, 1, 0)), //呼入接通量
                  InAvailableAnswer = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime != null && c.Duration >= effectiveTimes, 1, 0)), //有效接通量
                  InHangupImmediateWhenAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime != null && c.Duration < connectByeTimes, 1, 0)),//接通秒挂
                  OverTimeImmediate = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime != null && c.RingTimes > ringTimes, 1, 0)),//超时接通量
                  InTimeImmediate = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime != null && c.RingTimes <= ringTimes, 1, 0)),//按时接通量
                  InHanguped = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime == null, 1, 0)), //呼入未接通
                  InHangupImmediate = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime == null && c.RingTimes <= noConnectByeTimes, 1, 0)),//未接通秒挂量
                  OverTimeInHanguped = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime == null && c.RingTimes > ringTimes, 1, 0)), //超时未接通量
              }).ToListAsync();
        return list;
    }

    /// <summary>
    /// 坐席月接通明细
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    public override ISugarQueryable<QuerySeatMonthCallDetailResp> QuerySeatMonthCallDetail(QuerySeatMonthCallDetailRequest dto)
    {
        //获取配置
        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
        int ringTimes = _systemSettingCacheManager.RingTimes;

        return _trCallRecordRepository.Queryable()
            .WhereIF(dto.RingStartTime.HasValue, x => x.BeginRingTime >= dto.RingStartTime)
            .WhereIF(dto.RingEndTime.HasValue, x => x.BeginRingTime <= dto.RingEndTime)
            .WhereIF(dto.EndRingStartTime.HasValue, x => x.EndRingTimg >= dto.EndRingStartTime)
            .WhereIF(dto.EndRingEndTime.HasValue, x => x.EndRingTimg <= dto.EndRingEndTime)
            .WhereIF(!string.IsNullOrEmpty(dto.EmpId), x => x.UserId == dto.EmpId)
            .WhereIF(dto.AnsweredStartTime.HasValue, x => x.AnsweredTime >= dto.AnsweredStartTime)
            .WhereIF(dto.AnsweredEndTime.HasValue, x => x.AnsweredTime <= dto.AnsweredEndTime)
            .WhereIF(!string.IsNullOrEmpty(dto.TelNo), x => x.TelNo.Contains(dto.TelNo!))
            .WhereIF(!string.IsNullOrEmpty(dto.Cpn), x => x.CPN.Contains(dto.Cpn!))
            .WhereIF(!string.IsNullOrEmpty(dto.Cdpn), x => x.CDPN.Contains(dto.Cdpn!))
            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 1, x => x.AnsweredTime != null) //呼入接通总量
            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 2, x => x.AnsweredTime != null && x.Duration >= effectiveTimes) //有效接通量
            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 3, x => x.AnsweredTime != null && x.Duration < connectByeTimes) //接通秒挂量
            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 4, x => x.AnsweredTime != null && x.RingTimes > ringTimes) //超时接通量
            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 5, x => x.AnsweredTime != null && x.RingTimes <= ringTimes) //按时接通量
            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 6, x => x.AnsweredTime == null) //呼入未接通量
            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 7, x => x.AnsweredTime == null && x.RingTimes <= noConnectByeTimes) //未接通秒挂量
            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 8, x => x.AnsweredTime == null && x.RingTimes > ringTimes) //超时未接通量
            .Where(x => x.CallDirection == ECallDirection.In)
            .OrderBy(x => x.BeginRingTime)
            .MergeTable()
            .Select(x => new QuerySeatMonthCallDetailResp
            {
                Cpn = x.CPN,
                Cdpn = x.CDPN,
                TelNo = x.TelNo,
                AnsweredTime = x.AnsweredTime,
                RingTimeBegin = x.BeginRingTime,
                RingTimeEnd = x.EndRingTimg,
                SeatName = x.UserName
            });
    }



    //public override async Task<PagedDto<TrCallDto>> GetCallDetailListAsync(GetCallListDto dto, CancellationToken cancellationToken)
    //{
    //    var (total, items) = await _trCallRecordRepository.Queryable()
    //        .Includes(x => x.Order)
    //        .WhereIF(!string.IsNullOrEmpty(dto.CPN), x => x.CPN.Contains(dto.CPN))
    //        .WhereIF(!string.IsNullOrEmpty(dto.CDPN), x => x.CDPN.Contains(dto.CDPN))
    //        .WhereIF(!string.IsNullOrEmpty(dto.TelNo), x => x.TelNo.Contains(dto.TelNo))
    //        .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
    //        .WhereIF(dto.CallDirection != null, x => x.CallDirection == dto.CallDirection)
    //        .WhereIF(dto.OnState != null, x => x.OnState == dto.OnState)
    //        .WhereIF(dto.EndBy != null, x => x.EndBy == dto.EndBy)
    //        .WhereIF(dto.BeginIvrTimeStart.HasValue, x => x.BeginIvrTime >= dto.BeginIvrTimeStart)
    //        .WhereIF(dto.BeginIvrTimeEnd.HasValue, x => x.BeginIvrTime <= dto.BeginIvrTimeEnd)
    //        .WhereIF(dto.EndIvrTimeStart.HasValue, x => x.EndIvrTime >= dto.EndIvrTimeStart)
    //        .WhereIF(dto.EndIvrTimeEnd.HasValue, x => x.EndIvrTime <= dto.EndIvrTimeEnd)
    //        .WhereIF(dto.BeginQueueTimeStart.HasValue, x => x.BeginQueueTime >= dto.BeginQueueTimeEnd)
    //        .WhereIF(dto.BeginQueueTimeEnd.HasValue, x => x.BeginQueueTime <= dto.BeginQueueTimeEnd)
    //        .WhereIF(dto.EndQueueTimeStart.HasValue, x => x.EndQueueTime >= dto.EndQueueTimeStart)
    //        .WhereIF(dto.EndQueueTimeEnd.HasValue, x => x.EndQueueTime <= dto.EndQueueTimeEnd)
    //        .WhereIF(dto.AnsweredTimeStart.HasValue, x => x.AnsweredTime >= dto.AnsweredTimeStart)
    //        .WhereIF(dto.AnsweredTimeEnd.HasValue, x => x.AnsweredTime <= dto.AnsweredTimeEnd)
    //        .WhereIF(dto.OverTimeStart.HasValue, x => x.OverTime >= dto.OverTimeStart)
    //        .WhereIF(dto.OverTimeEnd.HasValue, x => x.OverTime <= dto.OverTimeEnd)
    //        .WhereIF(dto.BeginRingTimeStart.HasValue, x => x.BeginRingTime >= dto.BeginRingTimeStart)
    //        .WhereIF(dto.BeginRingTimeEnd.HasValue, x => x.BeginRingTime <= dto.BeginRingTimeEnd)
    //        .WhereIF(dto.EndRingTimeStart.HasValue, x => x.EndRingTimg >= dto.EndRingTimeStart)
    //        .WhereIF(dto.EndRingTimeEnd.HasValue, x => x.EndRingTimg <= dto.EndRingTimeEnd)
    //        .WhereIF(dto.CallTimeStart.HasValue, x => x.CreatedTime >= dto.CallTimeStart)
    //        .WhereIF(dto.CallTimeEnd.HasValue, x => x.CreatedTime <= dto.CallTimeEnd)
    //        .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.Order.No.Contains(dto.OrderNo))
    //        .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title))
    //        .WhereIF(!string.IsNullOrEmpty(dto.Gateway), x => x.Gateway.Contains(dto.Gateway))
    //        .WhereIF(dto.IsAiAnswered == true, x => string.IsNullOrEmpty(x.UserId) == true && x.BeginIvrTime.HasValue && x.EndIvrTime.HasValue)
    //        .WhereIF(dto.PhoneTypes != null, x => x.PhoneTypes == dto.PhoneTypes)
    //        .OrderByDescending(x => x.CreatedTime)
    //        .ToPagedListAsync(dto.PageIndex, dto.PageSize);
    //    return new PagedDto<TrCallDto>(total, _mapper.Map<IReadOnlyList<TrCallDto>>(items));
    //}
}
