using DotNetCore.CAP;
using Hotline.Authentications;
using Hotline.Caching.Interfaces;
using Hotline.Caching.Services;
using Hotline.FlowEngine.Notifications;
using Hotline.Orders;
using Hotline.Repository.SqlSugar.Orders;
using Hotline.Settings;
using Hotline.Share.Dtos.FlowEngine;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.Snapshot;
using Hotline.Share.Enums.FlowEngine;
using Hotline.Share.Mq;
using Hotline.Share.Tools;
using Hotline.Snapshot;
using Hotline.Snapshot.Notifications;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Hotline.Application.OrderApp;
using Hotline.FlowEngine.Workflows;
using XF.Domain.Dependency;
using XF.Domain.Exceptions;
using Microsoft.Extensions.Logging;
using Hotline.Orders.Notifications;
using Hotline.Snapshot.IRepository;
using Hotline.Snapshot.Contracts;
using Hotline.FlowEngine.WorkflowModules;
using XF.Domain.Entities;
using Hotline.Share.Enums.Snapshot;
using Hotline.Application.Snapshot.Contracts;

namespace Hotline.Application.Snapshot.Notifications;

public class SnapshotHandler : ICapSubscribe, IScopeDependency
{
    private readonly ISnapshotApplication _snapshotApplication;
    private readonly ISnapshotBulletinApplication _snapshotBulletinApplication;

    public SnapshotHandler(ISnapshotApplication snapshotApplication, ISnapshotBulletinApplication snapshotBulletinApplication)
    {
        _snapshotApplication = snapshotApplication;
        _snapshotBulletinApplication = snapshotBulletinApplication;
    }

    /// <summary>
    /// 推送成功后发送的延迟消息;
    /// 延迟检查网格员是否回复了工单;
    /// <param name="message"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [CapSubscribe(EventNames.GuiderSystemReplyDelay)]
    public async Task PostGuiderSystemDelayedNotificationHandler(PostGuiderSystemDelayed message, CancellationToken cancellationToken)
    {
        await _snapshotApplication.GuiderSystemReplyDelayAsync(message.OrderId, cancellationToken);
    }

    /// <summary>
    /// 通知公告审核通过
    /// </summary>
    /// <param name="bulletinId"></param>
    /// <param name="token"></param>
    /// <returns></returns>
    [CapSubscribe(EventNames.BulletinIsPass)]
    public async Task BulletinIsPassHandler(string bulletinId, CancellationToken token)
    {
        await _snapshotBulletinApplication.NotifyUserAsync(bulletinId, token);
    }
}

/// <summary>
/// 工单归档后生成红包数据
/// </summary>
public class SnapshotOrderFiledNotificationHandler : INotificationHandler<SnapshotOrderFiledNotification>
{
    private readonly ISnapshotApplication _snapshotApplication;
    private readonly IOrderSnapshotRepository _orderSnapshotRepository;
    private readonly ILogger<SnapshotOrderFiledNotificationHandler> _logger;
    public SnapshotOrderFiledNotificationHandler(ISnapshotApplication snapshotApplication, ILogger<SnapshotOrderFiledNotificationHandler> logger, IOrderSnapshotRepository orderSnapshotRepository)
    {
        _snapshotApplication = snapshotApplication;
        _logger = logger;
        _orderSnapshotRepository = orderSnapshotRepository;
    }
    public async Task Handle(SnapshotOrderFiledNotification notification, CancellationToken cancellationToken)
    {
        try
        {
            if (_orderSnapshotRepository.HasOrder(notification.OrderId))
                await _snapshotApplication.AddRedPardAsync(notification.OrderId, cancellationToken);
        }
        catch (Exception e)
        {
            _logger.LogError(e, "工单归档后生成红包数据失败");
        }
    }
}

/// <summary>
/// 网格员办结事件处理
/// 把网格员信息回填到系统中, 和小程序账号绑定
/// 同步社区信息
/// </summary>
public class GuiderSystemFieldNotificationHandler : INotificationHandler<GuiderSystemFieldNotification>
{
    private readonly ISnapshotApplication _snapshotApplication;
    private readonly IOrderApplication _orderApplication;
    private readonly ILogger<GuiderSystemFieldNotificationHandler> _logger;

    public GuiderSystemFieldNotificationHandler(
        ISnapshotApplication snapshotApplication1,
        IOrderApplication orderApplication,
        ILogger<GuiderSystemFieldNotificationHandler> logger)
    {
        _snapshotApplication = snapshotApplication1;
        _orderApplication = orderApplication;
        _logger = logger;
    }

    public async Task Handle(GuiderSystemFieldNotification notification, CancellationToken cancellationToken)
    {
        try
        {
            await _snapshotApplication.SyncGuiderInfoAsync(notification.OrderSnapshot.Id, cancellationToken);
            await _snapshotApplication.SyncCommunityInfoAsync(notification.CommunityInfo, cancellationToken);

        }
        catch (Exception e)
        {
            _logger.LogError(e, "网格员办结同步数据失败");
        }

        //流程流转至派单组
        await _orderApplication.HandleFromWanggeyuanToMaskAsync(notification.OrderSnapshot.Id, string.Empty, cancellationToken);
    }
}

/// <summary>
/// 推送网格员系统
/// </summary>
public class SnapshotPushNotificationHandler : INotificationHandler<PostGuiderSystemNotification>
{
    private readonly ISnapshotApplication _snapshotApplication;

    public SnapshotPushNotificationHandler(ISnapshotApplication snapshotApplication)
    {
        _snapshotApplication = snapshotApplication;
    }

    public async Task Handle(PostGuiderSystemNotification notification, CancellationToken cancellationToken)
    {
        await _snapshotApplication.PostOrderGuiderSystemAsync(notification.OrderId, cancellationToken);
    }
}

public class AddOrderSpecialHandler : INotificationHandler<AddOrderSpecialNotify>
{
    private readonly IOrderSnapshotApplication _orderSnapshotApplication;
    private readonly ISystemSettingCacheManager _systemSettingCacheManager;

    public AddOrderSpecialHandler(IOrderSnapshotApplication orderSnapshotApplication, ISystemSettingCacheManager systemSettingCacheManager)
    {
        _orderSnapshotApplication = orderSnapshotApplication;
        _systemSettingCacheManager = systemSettingCacheManager;
    }

    public async Task Handle(AddOrderSpecialNotify notification, CancellationToken cancellationToken)
    {
        if (notification.SourceChannel.Contains("随手拍") && _systemSettingCacheManager.Snapshot == true)
        {
            var item = notification.Reasons.FirstOrDefault();
            if (item == null) return;
            await _orderSnapshotApplication.UpdateSpecialReasonAsync(notification.OrderId, item.ErrorId, item.ErrorName);
        }
    }
}

public class SnapshotStartWorkFlow : INotificationHandler<StartWorkflowNotify>
{
    private readonly ISnapshotPointsDomainService _snapshotPointsDomainService;
    private readonly ISystemSettingCacheManager _sysSetting;

    public SnapshotStartWorkFlow(ISnapshotPointsDomainService snapshotPointsDomainService, ILogger<SnapshotStartWorkFlow> logger, ISystemSettingCacheManager sysSetting)
    {
        _snapshotPointsDomainService = snapshotPointsDomainService;
        _logger = logger;
        _sysSetting = sysSetting;
    }

    private readonly ILogger<SnapshotStartWorkFlow> _logger;

    /// <summary>
    /// 用户提交工单后，启动工作流, 给用户加积分
    /// </summary>
    /// <param name="notification"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task Handle(StartWorkflowNotify notification, CancellationToken cancellationToken)
    {
        try
        {
            if (_sysSetting.Snapshot == false || notification.Workflow.ModuleCode != WorkflowModuleConsts.OrderHandle) return;
            await _snapshotPointsDomainService.AddPointsAsync(notification.Workflow.ExternalId, EPointsSource.Report, ESnapshotSMSStatus.Agree, 0);
        }
        catch (Exception e)
        {
            _logger.LogError("增加用户上报积分失败", e);
        }
    }
}
