using MediatR;
using TakeoutSaaS.Application.App.Merchants.Commands;
using TakeoutSaaS.Domain.Merchants.Entities;
using TakeoutSaaS.Domain.Merchants.Enums;
using TakeoutSaaS.Domain.Merchants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Security;

namespace TakeoutSaaS.Application.App.Merchants.Handlers;

/// <summary>
/// 撤销商户审核处理器。
/// </summary>
public sealed class RevokeMerchantReviewHandler(
    IMerchantRepository merchantRepository,
    ICurrentUserAccessor currentUserAccessor)
    : IRequestHandler<RevokeMerchantReviewCommand>
{
    /// <inheritdoc />
    public async Task Handle(RevokeMerchantReviewCommand request, CancellationToken cancellationToken)
    {
        var merchant = await merchantRepository.FindByIdAsync(request.MerchantId, cancellationToken)
            ?? throw new BusinessException(ErrorCodes.NotFound, "商户不存在");

        if (merchant.Status != MerchantStatus.Approved)
        {
            throw new BusinessException(ErrorCodes.Conflict, "商户不在已审核状态");
        }

        var now = DateTime.UtcNow;
        var actorName = currentUserAccessor.IsAuthenticated
            ? $"user:{currentUserAccessor.UserId}"
            : "system";

        merchant.Status = MerchantStatus.Pending;
        merchant.IsFrozen = true;
        merchant.FrozenReason = request.Reason;
        merchant.FrozenAt = now;
        merchant.ReviewRemarks = request.Reason;
        merchant.LastReviewedAt = now;
        merchant.LastReviewedBy = currentUserAccessor.UserId == 0 ? null : currentUserAccessor.UserId;
        merchant.ClaimedBy = null;
        merchant.ClaimedByName = null;
        merchant.ClaimedAt = null;
        merchant.ClaimExpiresAt = null;

        await merchantRepository.UpdateMerchantAsync(merchant, cancellationToken);
        await merchantRepository.AddAuditLogAsync(new MerchantAuditLog
        {
            TenantId = merchant.TenantId,
            MerchantId = merchant.Id,
            Action = MerchantAuditAction.ReviewRevoked,
            Title = "撤销审核",
            Description = request.Reason,
            OperatorId = currentUserAccessor.UserId == 0 ? null : currentUserAccessor.UserId,
            OperatorName = actorName
        }, cancellationToken);
        await merchantRepository.SaveChangesAsync(cancellationToken);
    }
}
