using Hotline.Api.Controllers;
using Hotline.Application.Snapshot.Contracts;
using Hotline.Caching.Interfaces;
using Hotline.Identity.Accounts;
using Hotline.Identity.Roles;
using Hotline.Repository.SqlSugar.Snapshot;
using Hotline.Settings;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Snapshot;
using Hotline.Share.Enums.Snapshot;
using Hotline.Share.Tools;
using Hotline.Snapshot.IRepository;
using Hotline.Tests.Mock;
using Hotline.ThirdAccountDomainServices;
using Hotline.ThirdAccountDomainServices.Interfaces;
using Hotline.Users;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XF.Domain.Cache;
using XF.Domain.Repository;

namespace Hotline.Tests.Application;
public class RedPackApplicationTest : TestBase
{
    private readonly IRedPackApplication _redPackApplication;
    private readonly IRedPackRecordRepository _redPackRecordRepository;
    private readonly OrderServiceMock _orderServiceMock;
    private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
    private readonly IIndustryRepository _industryRepository;
    private readonly ISpecialRedPackAuditRepository _specialRedPackAuditRepository;
    private readonly ISnapshotPointsRecordRepository _pointsRecordRepository;

    public RedPackApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IRedPackApplication redPackApplication, IRedPackRecordRepository redPackRecordRepository, ITypedCache<SystemSetting> cacheSettingData, OrderServiceMock orderServiceMock, ISystemDicDataCacheManager systemDicDataCacheManager, IIndustryRepository industryRepository, ISpecialRedPackAuditRepository specialRedPackAuditRepository, ThirdAccounSupplierFactory thirdAccountDomainFactory, ISnapshotPointsRecordRepository pointsRecordRepository, IServiceProvider serviceProvider) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData, thirdAccountDomainFactory, serviceProvider)
    {
        _redPackApplication = redPackApplication;
        _redPackRecordRepository = redPackRecordRepository;
        _orderServiceMock = orderServiceMock;
        _systemDicDataCacheManager = systemDicDataCacheManager;
        _industryRepository = industryRepository;
        _specialRedPackAuditRepository = specialRedPackAuditRepository;
        _pointsRecordRepository = pointsRecordRepository;
    }

    /// <summary>
    /// 获取特殊红包集合
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task GetRedPackSpecialAuditItems_Test()
    {
        var dhzy = _systemDicDataCacheManager.OrderTag.Where(m => m.DicDataName == "动火作业").FirstOrDefault();
        dhzy.ShouldNotBeNull("SysDicTypeConsts.OrderTag 缺少动作火作业基础信息");
        SetZuoXi();
        var industryItems = await _industryRepository.Queryable().Where(m => m.Name == "安全隐患").Select(d => new { d.Id, d.Name, }).ToListAsync();
        var industry = industryItems.First();
        var order = _orderServiceMock.CreateOrder(industryId: industry.Id, industryName: industry.Name, tags: [dhzy.Id])
            .StepHandle(async order => 
            {
                SetSettingCache(SettingConstants.OvertimeBack, "0.00027778");
            })
            .办理到网格员(SetZuoXi)
            .StepHandle(async order =>
            {
                Thread.Sleep(5 * 1000);
                SetSettingCache(SettingConstants.OvertimeBack, "4");
            })
            .办理到派单员(Set班长)
            .办理到一级部门(SetPaiDanYuan)
            .办理到归档(Set一级部门)
            .发布工单(SetZuoXi, _systemDicDataCacheManager.SnapshotOrderLabel.Where(m => m.DicDataValue == "bss").Select(m => new Kv(m.DicDataName, m.DicDataName)).ToList())
            .部门审核市民红包(Set应急管理局)
            .StepHandle(async order =>
            {
                var items = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0)).ToListAsync();
                items.Where(m => m.No == order.No).Count().ShouldBe(1);
                items = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, -1)).ToListAsync();
                items.Where(m => m.No == order.No).Count().ShouldBe(1);
                items = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 1)).ToListAsync();
                items.Where(m => m.No == order.No).Count().ShouldBe(0, "审批同意不应该存在数据");
                items = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2)).ToListAsync();
                items.Where(m => m.No == order.No).Count().ShouldBe(0);
            })
            .部门审核特殊红包(Set应急管理局, 29)
            .StepHandle(async order =>
            {
                var special = await _specialRedPackAuditRepository.Queryable().Where(m => m.OrderId == order.Id).FirstAsync();
                special.ApprovedAmount.ShouldBe(29);
                special.Status.ShouldBe(ERedPackAuditStatus.Agree);
                special.AuditRemark.ShouldBe("红包审核通过");
                var redPackAudit = await _redPackApplication.GetRedPackSpecialAuditBaseDataAsync(order.Id);
                redPackAudit.AuditDetail.AuditId.ShouldNotBeNull();
                redPackAudit.AuditDetail.AuditName.ShouldNotBeNull();
                redPackAudit.AuditDetail.AuditOrgId.ShouldNotBeNull();
                redPackAudit.AuditDetail.AuditOrgName.ShouldNotBeNull();
                redPackAudit.AuditDetail.AuditRemark.ShouldNotBeNull("审核意见不能为空");
                redPackAudit.AuditDetail.AuditRemark.ShouldBe("红包审核通过");

                var items = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto(order.No, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 1)).FirstAsync();
                items.ApprovedAmount.ShouldBe(29);
            })
            .GetCreateResult();
        order.Id.ShouldNotBeNull();
    }

    /// <summary>
    /// 获取审核集合
    /// 获取审核短信模板
    /// 审核通过
    /// 获取红包记录
    /// </summary>
    /// <returns></returns>
    //[Fact]
    public async Task AuditRedPackAudit_Test()
    {
        var items = await _redPackApplication.GetRedPackAuditItems(new SnapshotOrderAuditItemsInDto(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0)).ToListAsync();
        var audit = items.First();
        var smsTemplate = await _redPackApplication.GetRedPackAuditSMSTemplateAsync(new GetRedPackAuditSMSTemplateInDto(audit.OrderId, ESnapshotSMSStatus.Agree));
        var inDto = new UpdateRedPackAuditInDto
        {
            Status = ESnapshotSMSStatus.Agree,
            Opinion = "单元测试" + DateTime.Now.ToShortDateString(),
            SMSTemplateId = smsTemplate.First().Id,
            IsSendSms = true,
            RedPackAuditId = audit.Id,
        };
        await _redPackApplication.AuditRedPackAuditAsync(inDto, CancellationToken.None);

        var pointRecord = await _pointsRecordRepository.GetByOrderIdAsync(audit.OrderId, CancellationToken.None);
        pointRecord.Where(m => m.Source == EPointsSource.Audit).Count().ShouldBe(1);
        var suInDto = new UpdateRedPackRecordInDto
        {
            RedPackAuditId = audit.Id,
            Name = "单元测试Name",
            BankCardNo = "单元测试银行号",
            OpenBank = "单元测试开户行",
            ReplenishAmount = 100.01,
            ReplenishTime = DateTime.Now,
            ReplenishRemark = "单元测试补发备注",
            IsSendSMS = false,
            ReplenishType = "%15",
            ReplenishTypeId = "1",
        };
        await _redPackApplication.UpdateRedPackRecordAsync(suInDto);

        items = await _redPackApplication.GetRedPackAuditItems(new SnapshotOrderAuditItemsInDto(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 1)).ToListAsync();
        items.Any(m => m.Id == audit.Id).ShouldBeTrue();

        var record = await _redPackRecordRepository.Queryable()
            .Where(m => m.OrderId == audit.OrderId)
            .FirstAsync();
        record.ShouldNotBeNull();
        var recordItems = await _redPackApplication.GetRedPackRecordItems(new SnapshotRedPackRecordItemsInDto { Status =2}).ToListAsync();
        recordItems.Count.ShouldNotBe(0);

        var redPackRecord = recordItems.First();
        var redPackRecordEntity = await _redPackRecordRepository.GetAsync(redPackRecord.Id);
        redPackRecordEntity.PickupStatus = ERedPackPickupStatus.Received;
        redPackRecordEntity.DistributionState = EReadPackSendStatus.Successful;
        redPackRecordEntity.ReceiveTime = DateTime.Now;
        await _redPackRecordRepository.UpdateAsync(redPackRecordEntity);

        var sendRecordItems = await _redPackApplication.GetRedPackRecordDetail(new SnapshotRedPackRecordSendInDto
        {
            IsReceive = true,
        }).ToListAsync();
        sendRecordItems.Count.ShouldNotBe(0);
    }

    [Fact]
    public async Task GetRedPackRecordSupplementItems_Test()
    {
        var items = await _redPackApplication.GetRedPackRecordSupplementItems(new SnapshotRedPackRecordSupplementItemsInDto()).ToListAsync();
        items.Any(m => m.FromName.NotNullOrEmpty()).ShouldBeTrue();
        items.Any(m => m.Remark.NotNullOrEmpty()).ShouldBeTrue();
        items.Any(m => m.AuditType.NotNullOrEmpty()).ShouldBeTrue();
        items.ShouldNotBeNull();
    }
}
