using MediatR;
using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Tenants.Commands;
using TakeoutSaaS.Application.App.Tenants.Contracts;
using TakeoutSaaS.Domain.Identity.Repositories;
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.Ids;
using TakeoutSaaS.Shared.Abstractions.Security;

namespace TakeoutSaaS.Application.App.Tenants.Handlers;

/// <summary>
/// 强制接管租户审核命令处理器。
/// </summary>
public sealed class ForceClaimTenantReviewCommandHandler(
    ITenantRepository tenantRepository,
    IIdentityUserRepository identityUserRepository,
    ICurrentUserAccessor currentUserAccessor,
    IIdGenerator idGenerator,
    ILogger<ForceClaimTenantReviewCommandHandler> logger)
    : IRequestHandler<ForceClaimTenantReviewCommand, TenantReviewClaimDto>
{
    /// <inheritdoc />
    public async Task<TenantReviewClaimDto> Handle(ForceClaimTenantReviewCommand request, CancellationToken cancellationToken)
    {
        // 1. 校验租户是否存在
        var tenant = await tenantRepository.FindByIdAsync(request.TenantId, cancellationToken);
        if (tenant is null)
        {
            throw new BusinessException(ErrorCodes.NotFound, "租户不存在");
        }

        // 2. 校验租户状态（只有待审核状态才能领取）
        if (tenant.Status != TenantStatus.PendingReview)
        {
            throw new BusinessException(ErrorCodes.BadRequest, "租户不在待审核状态，无法领取审核");
        }

        // 3. 检查是否已被领取，如果有则释放
        var existingClaim = await tenantRepository.GetActiveReviewClaimAsync(request.TenantId, cancellationToken);
        if (existingClaim is not null)
        {
            existingClaim.ReleasedAt = DateTime.UtcNow;
        }

        // 4. 创建新的领取记录
        var now = DateTime.UtcNow;

        // 5. 查询当前用户的显示名称
        var actorName = "system";
        if (currentUserAccessor.IsAuthenticated && currentUserAccessor.UserId != 0)
        {
            var user = await identityUserRepository.FindByIdAsync(currentUserAccessor.UserId, cancellationToken);
            actorName = user?.DisplayName ?? $"用户{currentUserAccessor.UserId}";
        }

        var claim = new TenantReviewClaim
        {
            Id = idGenerator.NextId(),
            TenantId = request.TenantId,
            ClaimedBy = currentUserAccessor.UserId,
            ClaimedByName = actorName,
            ClaimedAt = now
        };

        // 6. 保存领取记录
        await tenantRepository.AddReviewClaimAsync(claim, cancellationToken);

        // 7. 添加审核日志
        var previousClaimInfo = existingClaim is not null ? $"，原领取人：{existingClaim.ClaimedByName}" : "";
        await tenantRepository.AddAuditLogAsync(new TenantAuditLog
        {
            Id = idGenerator.NextId(),
            TenantId = request.TenantId,
            Action = TenantAuditAction.ReviewForceClaimed,
            Title = "强制接管审核",
            Description = $"接管人：{actorName}{previousClaimInfo}",
            OperatorId = currentUserAccessor.UserId,
            OperatorName = actorName,
            CurrentStatus = tenant.Status
        }, cancellationToken);

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

        logger.LogInformation("租户 {TenantId} 审核已被 {UserId} 强制接管", request.TenantId, currentUserAccessor.UserId);

        return new TenantReviewClaimDto
        {
            Id = claim.Id,
            TenantId = claim.TenantId,
            ClaimedBy = claim.ClaimedBy,
            ClaimedByName = claim.ClaimedByName,
            ClaimedAt = claim.ClaimedAt
        };
    }
}
