using Hotline.EventBus;
using Hotline.Orders;
using Hotline.Push.FWMessage;
using Hotline.Push.Notifies;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Push;
using Hotline.Share.Enums.Order;
using Hotline.Share.Enums.Push;
using Hotline.Share.Tools;
using Mapster;
using Shouldly;
using XF.Domain.Repository;

namespace Hotline.Application.Tests.Domain;
public class OrderVisitDomainServiceTest
{
    private readonly IOrderVisitDomainService _orderVisitDomainService;
    private readonly IOrderVisitRepository _orderVisitRepository;
    private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
    private readonly Publisher _publisher;
    private readonly IOrderRepository _orderRepository;


    public OrderVisitDomainServiceTest(IOrderVisitDomainService orderVisitDomainService, IOrderVisitRepository orderVisitRepository, IRepository<OrderVisitDetail> orderVisitDetailRepository, Publisher publisher, IOrderRepository orderRepository)
    {
        _orderVisitDomainService = orderVisitDomainService;
        _orderVisitRepository = orderVisitRepository;
        _orderVisitDetailRepository = orderVisitDetailRepository;
        _publisher = publisher;
        _orderRepository = orderRepository;
    }

    //[Fact]
    public async Task UpdateSmsReplyDefault_Test()
    {
        var visit = await _orderVisitRepository
            .Queryable()
            .Where(m => m.VisitState == EVisitState.SMSVisiting)
            .OrderByDescending(m => m.CreationTime)
            .FirstAsync();
        visit.ShouldNotBeNull("缺少测试数据");

        var msg = new MessageDto()
        { 
            ExternalId = visit.Id,
        };

        await _orderVisitDomainService.UpdateSmsReplyDefaultAsync(msg);
        var replyTxt = "默认满意";
        var kv = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<Kv>("默认满意");
        var order = await _orderRepository.Queryable()
            .Includes(m => m.OrderVisits)
            .Where(m => m.OrderVisits.Any(o => o.Id == visit.Id))
            .FirstAsync();
        order.Status.ShouldBe(EOrderStatus.Visited);

        var visitDetail = await _orderVisitDetailRepository.Queryable()
            .Where(m => m.VisitId == visit.Id)
            .ToListAsync();
        foreach (var detail in visitDetail)
        {
            if (detail.VisitTarget == EVisitTarget.Seat)
            {
                var seatEvaluate = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<ESeatEvaluate>(replyTxt);
                var voiceEvaluate = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<EVoiceEvaluate>(replyTxt);

                detail.SeatEvaluate.ShouldBe(seatEvaluate);
                detail.VoiceEvaluate.ShouldBe(voiceEvaluate);
            }
            if (detail.VisitTarget == EVisitTarget.Org)
            {
                detail.OrgProcessingResults.Key.ShouldBe(kv.Key);
                detail.OrgProcessingResults.Value.ShouldBe(kv.Value);

                detail.OrgHandledAttitude.Key.ShouldBe(kv.Key);
                detail.OrgHandledAttitude.Value.ShouldBe(kv.Value);
            }
        }
    }

    //[Fact]
    public async Task OnSmsUpdate_Test()
    {
        var data = new Message() { IsSmsReply = true, SmsReplyContent = "1", PushBusiness = EPushBusiness.VisitSms };
        await _publisher.PublishAsync(data.Adapt<ReceiveMessageNotify>(), PublishStrategy.ParallelNoWait, new CancellationToken());
    }

    [Theory]
    [InlineData("4", "SMSUnsatisfied", "2", "不满意")]
    [InlineData("1", "Visited", "5", "非常满意")]
    [InlineData("非常满意", "Visited", "5", "非常满意")]
    [InlineData("满意", "Visited", "4", "满意")]
    [InlineData("一般", "Visited", "4", "满意")]
    [InlineData("不满意", "SMSUnsatisfied", "2", "不满意")]
    [InlineData("非常不满意", "SMSUnsatisfied", "2", "不满意")]
    public async Task UpdateSmsReply_Test(string content, string visitState, string orgResuktKey, string orgResuktValue)
    {
        var visit = await _orderVisitRepository.Queryable()
            .Where(m => m.VisitState == EVisitState.SMSVisiting)
            .OrderByDescending(m => m.CreationTime)
            .FirstAsync();
        if (visit == null) return;
        visit.ShouldNotBeNull("缺少测试数据");

        var message = new MessageDto { ExternalId = visit.Id, IsSmsReply = true, SmsReplyContent = content };
        var dto = new PushReceiveMessageDto();
        await _orderVisitDomainService.UpdateSmsReplyAsync(message);
        visit = _orderVisitRepository.Get(visit.Id);
        visit.VisitState.ShouldBe(visitState.ToEnum<EVisitState>());
        visit.NowEvaluate.Key.ShouldBe(orgResuktKey);
        visit.NowEvaluate.Value.ShouldBe(orgResuktValue);

        if (content == "4" || content == "5" || content == "不满意" || content == "非常不满意")
            visit.VisitType.ShouldBeNull();

        await _orderVisitDetailRepository.Queryable()
            .Where(m => m.VisitId == visit.Id && m.VisitTarget == EVisitTarget.Org)
            .FirstAsync()
            .Then(async org =>
            {
                org.OrgProcessingResults.Key.ShouldBe(orgResuktKey);
                org.OrgProcessingResults.Value.ShouldBe(orgResuktValue);
                org.OrgHandledAttitude.Key.ShouldBe(orgResuktKey);
                org.OrgHandledAttitude.Value.ShouldBe(orgResuktValue);
            });
    }

    [Theory]
    [InlineData("1", "非常满意", "Visited", "VerySatisfied", "VerySatisfied", "非常满意|5")]
    [InlineData("2", "满意", "Visited", "Satisfied", "Satisfied", "满意|4")]
    [InlineData("3", "一般", "Visited", "Normal", "Normal", "满意|4")]
    [InlineData("4", "不满意", "SMSUnsatisfied", "NoSatisfied", "NoSatisfied", "不满意|2")]
    [InlineData("5", "非常不满意", "SMSUnsatisfied", "NoSatisfied", "VeryNoSatisfied", "不满意|2")]
    [InlineData("默认满意", "默认满意", "Visited", "DefaultSatisfied", "DefaultSatisfied", "满意|4")]
    public void GetVisitEvaluateByReplyTxt_Test(string replyTxt, string assertReplyTxt, string visitState, string seatEvaluate, string voiceEvaluate, string kv)
    {
        var replyString = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<string>(replyTxt);
        replyString.ShouldBe(assertReplyTxt);

        var visitStateEnum = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<EVisitState>(replyTxt);
        visitStateEnum.ShouldBe(visitState.ToEnum<EVisitState>());

        var seatEvaluateEnum = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<ESeatEvaluate>(replyTxt);
        seatEvaluateEnum.ShouldBe(seatEvaluate.ToEnum<ESeatEvaluate>());

        var voiceEvaluateEnum = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<EVoiceEvaluate>(replyTxt);
        voiceEvaluateEnum.ShouldBe(voiceEvaluate.ToEnum<EVoiceEvaluate>());

        var kvResult = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<Kv>(replyTxt);
        var sp = kv.Split('|');
        var kV = new Kv(sp[1].ToString(), sp[0].ToString());
        kvResult.Key.ShouldBe(kV.Key);
        kvResult.Value.ShouldBe(kV.Value);
    }
}
