using DotNetCore.CAP;
using Hotline.Configurations;
using Hotline.FlowEngine.Notifications;
using Hotline.FlowEngine.WorkflowModules;
using Hotline.Orders;
using Hotline.Push.Notifies;
using Hotline.SeedData;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Enums.Order;
using Hotline.Share.Enums.Push;
using Hotline.Users;
using MapsterMapper;
using MediatR;
using Microsoft.Extensions.Options;
using XF.Domain.Authentications;
using XF.Domain.Repository;

namespace Hotline.Application.OrderApp.Handlers.OrderScreenHandler;
public class OrderScreenEndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
{
    private readonly IOrderRepository _orderRepository;
    private readonly ICapPublisher _capPublisher;
    private readonly IMapper _mapper;
    private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
    private readonly IRepository<Hotline.Orders.OrderScreen> _orderScreenRepository;
    private readonly IRepository<OrderVisit> _orderVisitRepository;
    private readonly ISessionContext _sessionContext;
    private readonly IRepository<OrderScreenDetail> _orderScreenDetailRepository;
    private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
    private readonly IMediator _mediator;
    private readonly IRepository<User> _userRepository;

    public OrderScreenEndWorkflowHandler(
        IOrderRepository orderRepository,
        ICapPublisher capPublisher,
        IMapper mapper,
        IRepository<OrderVisitDetail> orderVisitedDetailRepository,
        IRepository<Hotline.Orders.OrderScreen> orderScreenRepository,
        IRepository<OrderVisit> orderVisitRepository,
        ISessionContext sessionContext,
        IRepository<OrderScreenDetail> orderScreenDetailRepository,
        IOptionsSnapshot<AppConfiguration> appOptions,
        IMediator mediator,
        IRepository<User> userRepository)
    {
        _orderRepository = orderRepository;
        _capPublisher = capPublisher;
        _mapper = mapper;
        _orderScreenRepository = orderScreenRepository;
        _orderVisitedDetailRepository = orderVisitedDetailRepository;
        _orderVisitRepository = orderVisitRepository;
        _sessionContext = sessionContext;
        _orderScreenDetailRepository = orderScreenDetailRepository;
        _appOptions = appOptions;
        _mediator = mediator;
        _userRepository = userRepository;
    }

    /// <summary>Handles a notification</summary>
    /// <param name="notification">The notification</param>
    /// <param name="cancellationToken">Cancellation token</param>
    public async Task Handle(EndWorkflowNotify notification, CancellationToken cancellationToken)
    {
        if (notification.Workflow.ModuleCode == WorkflowModuleConsts.OrderScreen)
        {
            var workflow = notification.Workflow;
            //审批是否通过
            var isReviewPass = workflow.IsReviewPass();

            var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
            if (screen != null)
            {
                screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
                if (isReviewPass)
                {
                    screen.Status = EScreenStatus.End;
                    screen.ReplyContent = workflow.ActualOpinion;
                    //await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
                    var visitDetail =
                        await _orderVisitedDetailRepository.GetAsync(screen.VisitDetailId, cancellationToken);
                    if (visitDetail != null)
                    {
                        if (screen.ScreenType == EOrderScreenType.Seat)
                        {
                            visitDetail.SeatEvaluate = ESeatEvaluate.DefaultSatisfied;
                            if (_appOptions.Value.IsZiGong)
                            {
								visitDetail.VoiceEvaluate = EVoiceEvaluate.DefaultSatisfied;
							}
							await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
                        }
                        else
                        {
                            var screenSatisfy = new Kv() { Key = "-1", Value = "视为满意" };
                            visitDetail.OrgProcessingResults = screenSatisfy;
                            //if (_appOptions.Value.IsYiBin)
                            //    visitDetail.OrgNoSatisfiedReason = new List<Kv>();

                            //visitDetail.OrgHandledAttitude = screenSatisfy;
                            await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
                            // 修改主表当前评价结果
                            await _orderVisitRepository.Updateable().SetColumns(v => new OrderVisit() { NowEvaluate = screenSatisfy }).Where(v => v.Id == visitDetail.VisitId).ExecuteCommandAsync(cancellationToken);
                            //获取回访信息
                            var visit = await _orderVisitRepository.Queryable().Includes(x => x.Order)
                                .Includes(x => x.OrderVisitDetails)
                                .Where(x => x.Id == screen.VisitId).FirstAsync(cancellationToken);
                            if (visit != null)
                            {
                                //获取回访明细
                                var visitDe = visit.OrderVisitDetails.First(x => x.Id == screen.VisitDetailId);
                                //推省上
                                await _capPublisher.PublishAsync(Share.Mq.EventNames.HotlineOrderScreenApplyed,
                                    new PublishVisitDto()
                                    {
                                        Order = _mapper.Map<OrderDto>(visit.Order),
                                        No = visit.No,
                                        VisitType = visit.VisitType,
                                        VisitName = visit.CreatorName,
                                        VisitTime = visit.VisitTime,
                                        VisitRemark = string.IsNullOrEmpty(visitDe.VisitContent) ? screenSatisfy.Value : visitDe.VisitContent,
                                        AreaCode = visit.Order.AreaCode!,
                                        SubjectResultSatifyCode = visitDe.OrgProcessingResults?.Key,
                                        FirstSatisfactionCode = visit.Order.FirstVisitResultCode!,
                                        ClientGuid = ""
                                    });

                                //推门户
                                await _capPublisher.PublishAsync(Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
                                {
                                    Id = visit.Id,
                                    Order = _mapper.Map<OrderDto>(visit.Order),
                                    OrderVisitDetails = _mapper.Map<List<VisitDetailDto>>(visit.OrderVisitDetails),
                                    VisitName = visit.CreatorName,
                                    VisitTime = visit.VisitTime,
                                    VisitType = visit.VisitType,
                                    VisitState = visit.VisitState,
                                    PublishTime = visit.PublishTime,
                                }, cancellationToken: cancellationToken);
                            }
                        }
                    }
                }
                else
                {
                    screen.Status = EScreenStatus.Refuse;
                    screen.ReplyContent = workflow.ActualOpinion;
                }
                await _orderRepository.OrderScreenRevisionVisit(screen.VisitId, true, cancellationToken);
                screen.NewestAuditTime = DateTime.Now;
                await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
                OrderScreenDetail detail = new OrderScreenDetail
                {
                    ScreenId = screen.Id
                };
                detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
                await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);

                //这里处理甄别完成后发送短信
                if (_appOptions.Value.IsZiGong)
                {
                    var user = await _userRepository.GetAsync(p => p.Id == screen.CreatorId, cancellationToken);
                    if (user != null && user.OrgId != OrgSeedData.CenterId)
                    {
                        var isReviewPassText = isReviewPass == true ? "审批通过" : "审批拒绝";
                        var messageDto = new Share.Dtos.Push.MessageDto
                        {
                            PushBusiness = EPushBusiness.ScreenEnd,
                            ExternalId = screen.Id,
                            OrderId = screen.Id,
                            PushPlatform = EPushPlatform.Sms,
                            Remark = screen.No + isReviewPassText,
                            Name = screen.CreatorName,
                            TemplateCode = "1019",
                            Params = new List<string>() { screen.No, isReviewPassText },
                            TelNumber = user.PhoneNo,
                        };
                        await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
                    }
                }
            }
        }
    }
}