using MediatR;
using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Tenants.Commands;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Security;

namespace TakeoutSaaS.Application.App.Tenants.Handlers;

/// <summary>
/// 审核通过租户命令处理器。
/// </summary>
public sealed class ApproveTenantCommandHandler(
    ITenantRepository tenantRepository,
    ICurrentUserAccessor currentUserAccessor,
    ILogger<ApproveTenantCommandHandler> logger)
    : IRequestHandler<ApproveTenantCommand>
{
    /// <inheritdoc />
    public async Task Handle(ApproveTenantCommand request, CancellationToken cancellationToken)
    {
        // 1. 解析租户 ID
        if (!long.TryParse(request.TenantId, out var tenantId) || tenantId <= 0)
        {
            throw new BusinessException(ErrorCodes.BadRequest, "租户 ID 无效");
        }

        // 2. 获取租户（带跟踪）
        var tenant = await tenantRepository.GetByIdForUpdateAsync(tenantId, cancellationToken);
        if (tenant is null)
        {
            throw new BusinessException(ErrorCodes.NotFound, "租户不存在");
        }

        // 3. 校验租户状态（只有待审核状态才能审核通过）
        if (tenant.Status != TenantStatus.PendingReview)
        {
            throw new BusinessException(ErrorCodes.BadRequest, $"租户当前状态为 {tenant.Status}，无法审核通过");
        }

        // 4. 获取认证资料（带跟踪）
        var verification = await tenantRepository.GetVerificationForUpdateAsync(tenantId, cancellationToken);
        if (verification is null)
        {
            throw new BusinessException(ErrorCodes.NotFound, "租户认证资料不存在");
        }

        // 5. 更新租户状态
        tenant.Status = TenantStatus.Active;

        // 6. 更新认证资料状态
        verification.Status = TenantVerificationStatus.Approved;
        verification.ReviewedAt = DateTime.UtcNow;
        verification.ReviewedBy = currentUserAccessor.UserId;
        verification.ReviewedByName = request.ReviewedByName?.Trim();
        verification.ReviewRemarks = request.ReviewRemarks?.Trim();

        // 7. 保存变更
        await tenantRepository.SaveChangesAsync(cancellationToken);

        logger.LogInformation(
            "租户 {TenantId} 审核通过，审核人：{ReviewedBy}",
            tenantId,
            currentUserAccessor.UserId);
    }
}
