using Hotline.Api.Controllers;
using Hotline.Application.Snapshot;
using Hotline.Caching.Interfaces;
using Hotline.Identity.Accounts;
using Hotline.Identity.Roles;
using Hotline.Orders;
using Hotline.Repository.SqlSugar.Extensions;
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.Requests;
using Hotline.Share.Tools;
using Hotline.Snapshot.Interfaces;
using Hotline.Tests.Mock;
using Hotline.Users;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using NPOI.SS.Formula.Functions;
using Shouldly;
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 OrderSnapshotApplicationTest : TestBase
{
    private readonly OrderServiceMock _orderServiceMock;
    private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
    private readonly IOrderSnapshotRepository _orderSnapshotRepository;
    private readonly IOrderSnapshotApplication _orderSnapshotApplication;
    private readonly ISnapshotApplication _snapshotApplication;
    private readonly IIndustryLogRepository _industryLogRepository;
    private readonly ICommunityInfoRepository _communityInfoRepository;
    private readonly IRedPackAuditRepository _redPackAuditRepository;
    private readonly IRedPackRecordRepository _redPackRecordRepository;
    private readonly ISnapshotLabelLogRepository _snapshotLabelLogRepository;
    private readonly IOrderRepository _orderRepository;

    public OrderSnapshotApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, OrderServiceMock orderServiceMock, ISystemDicDataCacheManager systemDicDataCacheManager, IOrderSnapshotRepository orderSnapshotRepository, IOrderSnapshotApplication orderSnapshotApplication, ISnapshotApplication snapshotApplication, IIndustryLogRepository industryLogRepository, ICommunityInfoRepository communityInfoRepository, IRedPackAuditRepository redPackAuditRepository, IRedPackRecordRepository redPackRecordRepository, ISnapshotLabelLogRepository snapshotLabelLogRepository, ITypedCache<SystemSetting> cacheSettingData, IOrderRepository orderRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData)
    {
        _orderServiceMock = orderServiceMock;
        _systemDicDataCacheManager = systemDicDataCacheManager;
        _orderSnapshotRepository = orderSnapshotRepository;
        _orderSnapshotApplication = orderSnapshotApplication;
        _snapshotApplication = snapshotApplication;
        _industryLogRepository = industryLogRepository;
        _communityInfoRepository = communityInfoRepository;
        _redPackAuditRepository = redPackAuditRepository;
        _redPackRecordRepository = redPackRecordRepository;
        _snapshotLabelLogRepository = snapshotLabelLogRepository;
        _orderRepository = orderRepository;
    }

    /// <summary>
    /// 随手拍网格员超时:
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task SnapshotWorkflow_Guider_Timeout_Test()
    {
        SetSettingCache(SettingConstants.OvertimeBack, "0.00027778");
        var order = _orderServiceMock.CreateSnapshotOrder(SetWeiXin)
            .办理到网格员(SetZuoXi)
            .StepHandle(async order =>
            {
                Thread.Sleep(5 * 1000);
                var orderEntity = await _orderRepository.GetAsync(order.Id);
                orderEntity.ActualHandleStepName.ShouldBe("工单标记");
            }
            ).GetCreateResult();
    }

    /// <summary>
    /// 随手拍办理流程:
    ///     坐席
    ///     网格员
    ///     派单员
    ///     一级部门
    ///     归档
    ///     发布工单
    ///     政法委部门审核网格红包
    ///     应急局部门审核网格员红包
    ///     部门审核市民红包
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task SnapshotWorkflow_Guider_Test()
    {
        SetSettingCache(SettingConstants.OvertimeBack, "4");
        var snapshotLabels = _systemDicDataCacheManager.SnapshotOrderLabel;
        var inputLable = snapshotLabels.Where(m => m.DicDataValue == "bss").ToList();
        var order = _orderServiceMock.CreateSnapshotOrder(SetWeiXin)
            .办理到网格员(SetZuoXi)
            .StepHandle(async order =>
            {
                await _snapshotApplication.PostOrderGuiderSystemAsync(order.Id, CancellationToken.None);
                var orderSnapshot = await _orderSnapshotRepository.GetAsync(order.Id);
                orderSnapshot.IndustryName = "修改行业名称";
                await _orderSnapshotRepository.UpdateAsync(orderSnapshot);
                var industryLog = await _industryLogRepository.Queryable()
                    .Where(m => m.OrderId == order.Id)
                    .FirstAsync();
                industryLog.ShouldNotBeNull();
                industryLog.IndustryName.ShouldBe("修改行业名称");
                await _orderSnapshotRepository.Updateable()
                    .SetColumns(m => m.IndustryName, industryLog.OldIndustryName)
                    .Where(m => m.Id == order.Id)
                    .ExecuteCommandAsync();
                orderSnapshot = await _orderSnapshotRepository.GetAsync(order.Id);
                var replyDto = new GuiderSystemInDto
                {
                    ReplyCode = order.No,
                    AppealNumber = orderSnapshot.NetworkENumber,
                    ReplyDate = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                    ReplyUserName = "18181552753@zgsg",
                    ReplyBMName = "瓦市村村民委员会",
                    ReplyResultType = "2",
                    ReplyISTrue = "1",
                    IsRepeat = "0",
                    IsHiddenDanger = "1",
                    MemberName = "许利洪",
                    MemberMobile = "18181552753",
                    ReplyContent = "到现场查实，存在安全隐患",
                    OrgId = "4828",
                    OrgName = "瓦市村民委员会" + DateTime.Now.ToString("ss"),
                    OrgFullName = "四川省/自贡市/沿滩区/永安镇/瓦市村村民委员会" + DateTime.Now.ToString("ss"),
                    DepartmentNo = "510311106206",
                    ParentOrgId = "4821",
                    ReplyFileList = new List<string>
                    {
                        "http://10.0.188.11:1234/tqOssManager/getObjectByUri/sichuan/scgrid/jpg/2024/12/5/095020318625.jpg"
                    }
                };
                await _snapshotApplication.SaveGuiderSystemReplyAsync(replyDto, CancellationToken.None);
                var orderReply = await _orderSnapshotRepository.GetByNetworkENumberAsync(replyDto.AppealNumber);
                orderReply.IsDanger.ShouldBe(true);
                orderReply.MemberMobile.ShouldBe(replyDto.MemberMobile);
                orderReply.MemberName.ShouldBe(replyDto.MemberName);
                orderReply.NetworkRemark.ShouldBe(replyDto.ReplyContent);
                orderReply.ReplyDate.Value.ToString("yyyy-MM-dd hh:mm:ss").ShouldBe(replyDto.ReplyDate);
                var community = await _communityInfoRepository.GetAsync(replyDto.OrgId);
                community.ShouldNotBeNull();
                community.Name.ShouldBe(replyDto.OrgName);
                community.FullName.ShouldBe(replyDto.OrgFullName);
                var orderEntity = await _orderRepository.GetAsync(order.Id);
                orderEntity.ActualHandleStepName.ShouldBe("工单标记");
            })
            .办理到派单员(Set班长)
            .办理到一级部门(SetPaiDanYuan)
            .办理到归档(Set一级部门)
            .发布工单(SetZuoXi, inputLable.Select(m => new Kv(m.DicDataName, m.DicDataName)).ToList())
            .StepHandle(async order =>
            {
                var log = _snapshotLabelLogRepository.Queryable().Where(m => m.OrderId == order.Id).First();
                log.ShouldNotBeNull();
                var snapshot = _orderSnapshotRepository.Get(order.Id);
                snapshot.LabelName.ShouldBe(string.Join(',', inputLable.Select(m => m.DicDataName)), "label异常");
            })
            .部门审核网格员红包(Set政法委)
            .部门审核网格员红包(Set应急管理局)
            .StepHandle(async order =>
            {
                var redPackRecord = _redPackRecordRepository.Queryable()
                .Where(m => m.OrderId == order.Id && m.PeopleType == EReadPackUserType.Guider)
                .First();
                redPackRecord.Amount.ShouldNotBe(0);
            })
            .部门审核市民红包(Set应急管理局)
            .StepHandle(async order =>
            {
                var redPackAudit = _redPackAuditRepository.Queryable().Where(m => m.OrderId == order.Id).First();
                redPackAudit.Status.ShouldBe(ERedPackAuditStatus.Agree);
                var redPackRecord = _redPackRecordRepository.Queryable().Where(m => m.OrderId == order.Id).First();
                redPackRecord.ShouldNotBeNull();
            })
            .GetCreateResult();
        order.Id.ShouldNotBeNull();
    }

    /// <summary>
    /// 随手拍办理流程
    /// 工单标注 : 验证数据是否保存正确
    /// 获取已标注集合: 验证是否有已标注的数据
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task SnapshotWrokflow_Test()
    {
        var snapshotLabels = _systemDicDataCacheManager.SnapshotOrderLabel;
        var inputLable = snapshotLabels.Where(m => m.DicDataValue == "bss").ToList();
        var order = _orderServiceMock.CreateSnapshotOrder(SetWeiXin)
            .办理到工单标注(SetZuoXi)
            .办理到派单员(SetZuoXi, false)
            .办理到归档(SetZuoXi)
            .发布工单(SetZuoXi, inputLable.Select(m => new Kv { Key = m.DicDataValue, Value = m.DicDataName }).ToList())
            .GetCreateResult();
        order.Id.ShouldNotBeNull();

        var snapshot = await _orderSnapshotRepository.GetAsync(order.Id);
        // 验证工单标注是否生效
        snapshot.ShouldNotBeNull();
        snapshot.IsTruthDepartment.ShouldBe(false);
        snapshot.LabelName.ShouldBe(string.Join('|', inputLable.Select(m => m.DicDataName)));
        snapshot.Labels.ShouldNotBeNull();
        snapshot.Labels.Count.ShouldBe(inputLable.Count);

        snapshot.IsSafetyDepartment.ShouldBe(false);

        var labelLog = await _orderSnapshotApplication.GetLabelOrderSnapshotLogItems(new LabelOrderSnapshotLogItemsInDto()).ToPagedListAsync(new PagedRequest());
        labelLog.Items.Any(m => m.Title.IsNullOrEmpty()).ShouldBe(false);
        labelLog.Items.Any(m => m.SourceChannel.IsNullOrEmpty()).ShouldBe(false);

        var sigedItems = await _orderSnapshotApplication.GetLabeledOrderSnapshotItems(new LabeledOrderSnapshotItemsInDto()).ToListAsync();
        sigedItems.Any(m => m.OrderId == order.Id).ShouldBe(true);
    }
}

