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

namespace Hotline.Application.OrderApp.Handlers.OrderScreenHandler;
public class OrderScreenNextWorkflowHandler : INotificationHandler<NextStepNotify>
{
    private readonly ICapPublisher _capPublisher;
    private readonly IMapper _mapper;
    private readonly IOrderScreenRepository _orderScreenRepository;
    private readonly ISessionContext _sessionContext;
    private readonly IRepository<OrderScreenDetail> _orderScreenDetailRepository;
    private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
	private readonly IFileRepository _fileRepository;

	public OrderScreenNextWorkflowHandler(
        ICapPublisher capPublisher,
        IMapper mapper,
        IOrderScreenRepository orderScreenRepository,
        ISessionContext sessionContext,
        IOptionsSnapshot<AppConfiguration> appOptions,
        IRepository<OrderScreenDetail> orderScreenDetailRepository,
		IFileRepository fileRepository)
    {
        _capPublisher = capPublisher;
        _mapper = mapper;
        _orderScreenRepository = orderScreenRepository;
        _sessionContext = sessionContext;
        _orderScreenDetailRepository = orderScreenDetailRepository;
        _appOptions = appOptions;
		_fileRepository = fileRepository;

	}

    /// <summary>Handles a notification</summary>
    /// <param name="notification">The notification</param>
    /// <param name="cancellationToken">Cancellation token</param>
    public async Task Handle(NextStepNotify notification, CancellationToken cancellationToken)
    {
        if (notification.Workflow.ModuleCode == WorkflowModuleConsts.OrderScreen)
        {
            var workflow = notification.Workflow;
            var nextTag = notification.NextStepDefine.Tag.TryDeserialize<DefinitionTag>();
            var screen = await _orderScreenRepository.Queryable().Includes(x => x.Order)
                .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
            if (screen != null)
            {
                screen.Status = EScreenStatus.Approval;
                screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
                //如果下个节点是省审批，则修改为省甄别
                if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org && nextTag.Value == TagDefaults.TagValue.Province)
                    screen.IsProScreen = true;
                await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
            }

            if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org)
            {
                switch (nextTag.Value)
                {
                    case TagDefaults.TagValue.Province:
                        if (screen != null)
                        {
                            var screenDto = _mapper.Map<OrderScreenListDto>(screen);
                            if (screen.Order != null && screen.Order.Source == ESource.ProvinceStraight)
                            {
                                var screenOrderDto = _mapper.Map<OrderDto>(screen.Order);
                                //省件甄别--以省审批前一个节点整理的甄别意见为准推送省上 宜宾
                                if (_appOptions.Value.IsYiBin)
                                {
                                    screenDto.Content = notification.Dto.Opinion;
									screenDto.Files = new List<Share.Dtos.File.FileDto>();
                                    screenDto.FileJson = screenDto.ProvinceFileJson;
									if (screenDto.ProvinceFileJson != null && screenDto.ProvinceFileJson.Any())
                                    {
                                        var fileIds = screenDto.ProvinceFileJson.Select(x => x.Id).ToList();
										screenDto.Files = await _fileRepository.GetFilesAsync(fileIds, cancellationToken);
									}
                                }
								if (_appOptions.Value.IsLuZhou)
								{
									screenDto.Content = notification.Dto.Opinion;
								}
								//推省上
								_capPublisher.Publish(EventNames.HotlineOrderScreenApply, new PublishScreenDto()
                                {
                                    Order = screenOrderDto,
                                    Screen = screenDto,
                                    ClientGuid = ""
                                });
                            }
                        }

                        break;
                }
            }
            OrderScreenDetail detail = new OrderScreenDetail
            {
                ScreenId = screen.Id
            };
            detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
            await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
        }
    }
}