using Hotline.BatchTask;
using Hotline.Configurations;
using Hotline.Orders;
using Hotline.Share.Dtos.BatchTask;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.Order.OrderVisit;
using Hotline.Share.Enums.BatchTask;
using Hotline.Share.Enums.Order;
using Hotline.Share.Tools;
using MapsterMapper;
using Microsoft.Extensions.Options;
using SqlSugar;
using XF.Domain.Dependency;
using XF.Domain.Repository;

namespace Hotline.Application.OrderApp.OrderVisitApp;

/// <summary>
/// 回访服务
/// </summary>
public class OrderVisitApplication : IOrderVisitApplication, IScopeDependency
{
    #region 注册

    private readonly IOrderVisitRepository _orderVisitRepository;
    private readonly IRepository<OrderVisitRecord> _orderVisitRecordRepository;
    private readonly IApptaskDomainService _apptaskDomainService;
    private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
    private readonly IMapper _mapper;

    public OrderVisitApplication(
        IOrderVisitRepository orderVisitRepository,
        IRepository<OrderVisitRecord> orderVisitRecordRepository,
        IApptaskDomainService apptaskDomainService,
        IOptionsSnapshot<AppConfiguration> appOptions,
        IMapper mapper)
    {
        _orderVisitRepository = orderVisitRepository;
        _orderVisitRecordRepository = orderVisitRecordRepository;
        _apptaskDomainService = apptaskDomainService;
        _appOptions = appOptions;
        _mapper = mapper;
    }

    #endregion

    #region 回访量统计

    public async Task<List<OrderVisitQuantityOutDto>> QueryOrderVisitQuantityAsync(QueryOrderVisitQuantity dto, CancellationToken cancellationToken)
    {
        if (_appOptions.Value.IsZiGong == true)
        {
            // 自贡回访量统计
            var queryZg = _orderVisitRecordRepository
            .Queryable()
            .WhereIF(dto.EmployeeName.NotNullOrEmpty(), x => x.Employee.Name.Contains(dto.EmployeeName))
            .WhereIF(dto.StartTime != null, x => x.VisitTime >= dto.StartTime && x.VisitType != null && x.EmployeeId != "" && x.EmployeeId != null)
            .WhereIF(dto.EndTime != null, x => x.VisitTime <= dto.EndTime && x.VisitType != null && x.EmployeeId != "" && x.EmployeeId != null)
            .GroupBy(x => x.EmployeeId)
            .Select(x => new OrderVisitQuantityOutDto
            {
                EmployeeId = x.EmployeeId,
                EmployeeName = x.Employee.Name,
                CallVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType == EVisitType.CallVisit, 1, 0)), // 电话回访量
                DefaultVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType == EVisitType.ArtificialVisit, 1, 0)), // 默认回访量(人工回访)
                SmsVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType == EVisitType.SmsVisit, 1, 0)), // 短信回访量
                // TotalVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType != null, 1, 0)) // 总回访量
            });
            return await queryZg.ToListAsync(cancellationToken);
        }
        else
        {
            var query = _orderVisitRepository
            .Queryable()
            .WhereIF(dto.EmployeeName.NotNullOrEmpty(), m => m.Employee.Name.Contains(dto.EmployeeName))
            .Where(m => m.VisitTime >= dto.StartTime && m.VisitTime <= dto.EndTime && m.VisitType != null && m.EmployeeId != "" && m.EmployeeId != null)
            .GroupBy(m => m.EmployeeId)
            .Select(m => new OrderVisitQuantityOutDto
            {
                EmployeeId = m.EmployeeId,
                EmployeeName = m.Employee.Name,
                CallVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(m.VisitType == EVisitType.CallVisit, 1, 0)), // 电话回访量
                DefaultVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(m.VisitType == EVisitType.ArtificialVisit, 1, 0)), // 默认回访量(人工回访)
                SmsVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(m.VisitType == EVisitType.SmsVisit, 1, 0)), // 短信回访量
                // TotalVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(m.VisitType != null, 1, 0)) // 总回访量
            });
            return await query.ToListAsync(cancellationToken);
        }
    }

    #endregion

    #region 已回访信息记录

    /// <summary>
    /// 已回访信息记录，做为【回访量统计】统计表的基础信息
    /// </summary>
    /// <param name="dto"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public async Task<string> AddOrderVisitRecordAsync(OrderVisitRecordDto dto, CancellationToken cancellationToken)
    {
        var data = _mapper.Map<OrderVisitRecord>(dto);
        data.InitId();
        return await _orderVisitRecordRepository.AddAsync(data, cancellationToken);
    }

    #endregion

    /// <summary>
    /// 新增批量语音回访任务
    /// </summary>
    /// <returns></returns>
    public async Task AddTaskBatchVoiceVisitAsync(BatchVoiceVisitRequest request, CancellationToken cancellation)
    {
        var visits = await _orderVisitRepository.Queryable()
            .Includes(d => d.Order)
            .Where(d => request.VisitIds.Contains(d.Id)
                        && !string.IsNullOrEmpty(d.Order.Contact))
            .ToListAsync(cancellation);

        var taskId = await _apptaskDomainService.AddAsync(new AddApptaskRequest
        {
            TaskType = ETaskType.VoiceVisit,
            TryLimit = 10,
            ApptaskItems = visits.Select(d => new AddApptaskItemRequest
            {
                BusinessId = d.Id,
                TaskParams = new VoiceVisitRequest
                {
                    VisitId = d.Id,
                    PhoneNo = d.Order.Contact!
                }
            }).ToList()
        }, cancellation);

        if (!string.IsNullOrEmpty(taskId))
        {
            var visitIds = visits.Select(d => d.Id).ToList();
            await _orderVisitRepository.Updateable()
                  .SetColumns(d => new OrderVisit
                  {
                      VisitState = EVisitState.AiVisiting
                  })
                  .Where(d =>  visitIds.Contains(d.Id))
                  .ExecuteCommandAsync(cancellation);
        }
    }
}
