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 ForceClaimTenantReviewCommandHandler(
    ITenantRepository tenantRepository,
    ICurrentUserAccessor currentUserAccessor,
    IAdminAuthService adminAuthService)
    : IRequestHandler<ForceClaimTenantReviewCommand, TenantReviewClaimDto>
{
    /// <inheritdoc />
    public async Task<TenantReviewClaimDto> Handle(ForceClaimTenantReviewCommand request, CancellationToken cancellationToken)
    {
        // 1. 校验租户存在
        var tenant = await tenantRepository.FindByIdAsync(request.TenantId, cancellationToken)
            ?? throw new BusinessException(ErrorCodes.NotFound, "租户不存在");

        // 2. 获取当前用户显示名（用于展示快照）
        var profile = await adminAuthService.GetProfileAsync(currentUserAccessor.UserId, cancellationToken);
        var displayName = string.IsNullOrWhiteSpace(profile.DisplayName)
            ? $"user:{currentUserAccessor.UserId}"
            : profile.DisplayName;

        // 3. (空行后) 读取当前领取记录（可跟踪用于更新）
        var claim = await tenantRepository.FindActiveReviewClaimAsync(request.TenantId, cancellationToken);
        if (claim == null)
        {
            // 4. 未领取则直接创建（记录强制接管动作）
            var now = DateTime.UtcNow;
            var created = new TenantReviewClaim
            {
                TenantId = request.TenantId,
                ClaimedBy = currentUserAccessor.UserId,
                ClaimedByName = displayName,
                ClaimedAt = now,
                ReleasedAt = null
            };

            var auditLog = new TenantAuditLog
            {
                TenantId = tenant.Id,
                Action = TenantAuditAction.ReviewForceClaimed,
                Title = "强制接管审核",
                Description = $"接管人：{displayName}",
                OperatorId = currentUserAccessor.UserId,
                OperatorName = displayName,
                PreviousStatus = tenant.Status,
                CurrentStatus = tenant.Status
            };

            var success = await tenantRepository.TryAddReviewClaimAsync(created, auditLog, cancellationToken);
            if (!success)
            {
                var current = await tenantRepository.GetActiveReviewClaimAsync(request.TenantId, cancellationToken);
                if (current != null)
                {
                    return current.ToDto();
                }

                throw new BusinessException(ErrorCodes.Conflict, "审核接管失败，请刷新后重试");
            }

            return created.ToDto();
        }

        // 5. (空行后) 已由自己领取则直接返回
        if (claim.ClaimedBy == currentUserAccessor.UserId)
        {
            return claim.ToDto();
        }

        // 6. (空行后) 更新领取人并记录审计
        var previousOwner = claim.ClaimedByName;
        claim.ClaimedBy = currentUserAccessor.UserId;
        claim.ClaimedByName = displayName;
        claim.ClaimedAt = DateTime.UtcNow;

        await tenantRepository.UpdateReviewClaimAsync(claim, cancellationToken);
        await tenantRepository.AddAuditLogAsync(new TenantAuditLog
        {
            TenantId = tenant.Id,
            Action = TenantAuditAction.ReviewForceClaimed,
            Title = "强制接管审核",
            Description = $"原领取人：{previousOwner}，接管人：{displayName}",
            OperatorId = currentUserAccessor.UserId,
            OperatorName = displayName,
            PreviousStatus = tenant.Status,
            CurrentStatus = tenant.Status
        }, cancellationToken);

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