using MediatR;
using TakeoutSaaS.Application.App.Tenants.Commands;
using TakeoutSaaS.Application.App.Tenants.Dto;
using TakeoutSaaS.Application.Identity.Abstractions;
using TakeoutSaaS.Domain.Tenants.Entities;
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 ReleaseTenantReviewClaimCommandHandler(
    ITenantRepository tenantRepository,
    ICurrentUserAccessor currentUserAccessor,
    IAdminAuthService adminAuthService)
    : IRequestHandler<ReleaseTenantReviewClaimCommand, TenantReviewClaimDto?>
{
    /// <inheritdoc />
    public async Task<TenantReviewClaimDto?> Handle(ReleaseTenantReviewClaimCommand request, CancellationToken cancellationToken)
    {
        // 1. 校验租户存在
        var tenant = await tenantRepository.FindByIdAsync(request.TenantId, cancellationToken)
            ?? throw new BusinessException(ErrorCodes.NotFound, "租户不存在");

        // 2. 查询当前领取记录
        var claim = await tenantRepository.FindActiveReviewClaimAsync(request.TenantId, cancellationToken);
        if (claim == null)
        {
            return null;
        }

        // 3. (空行后) 非领取人不允许释放（如需接管请使用强制接管）
        if (claim.ClaimedBy != currentUserAccessor.UserId)
        {
            throw new BusinessException(ErrorCodes.Conflict, $"该审核已被 {claim.ClaimedByName} 领取");
        }

        // 4. (空行后) 释放领取并记录审计
        var profile = await adminAuthService.GetProfileAsync(currentUserAccessor.UserId, cancellationToken);
        var displayName = string.IsNullOrWhiteSpace(profile.DisplayName)
            ? $"user:{currentUserAccessor.UserId}"
            : profile.DisplayName;

        claim.ReleasedAt = DateTime.UtcNow;
        await tenantRepository.UpdateReviewClaimAsync(claim, cancellationToken);
        await tenantRepository.AddAuditLogAsync(new TenantAuditLog
        {
            TenantId = tenant.Id,
            Action = TenantAuditAction.ReviewClaimReleased,
            Title = "释放审核",
            Description = $"释放人：{displayName}",
            OperatorId = currentUserAccessor.UserId,
            OperatorName = displayName,
            PreviousStatus = tenant.Status,
            CurrentStatus = tenant.Status
        }, cancellationToken);

        await tenantRepository.SaveChangesAsync(cancellationToken);
        return claim.ToDto();
    }
}

