#nullable enable
using Baya.Application.Contracts.Common;
using Baya.Application.Contracts.Persistence;
using Baya.Application.Models.Common;
using Baya.Application.Models.PartnerCenters;
using Mediator;

namespace Baya.Application.Features.PartnerCenters.Commands.VerifyPartnerCenter;

/// <summary>
/// Runs the (mocked) licensing checks behind <see cref="ILicenseVerificationService"/> and records the admin's
/// approval. An explicit <c>Invalid</c> verdict on the establishment permit or eNamad blocks activation; a
/// <c>Valid</c> or <c>NeedsManualReview</c> verdict lets the human admin's decision stand (this command is that
/// decision). The seam call is the swap point for a real registry/API later — this handler is unchanged then.
/// </summary>
internal sealed class VerifyPartnerCenterCommandHandler(
    IUnitOfWork unitOfWork,
    ILicenseVerificationService licenseVerification,
    IDateTimeProvider dateTimeProvider)
    : IRequestHandler<VerifyPartnerCenterCommand, OperationResult<PartnerCenterDetailDto>>
{
    public async ValueTask<OperationResult<PartnerCenterDetailDto>> Handle(VerifyPartnerCenterCommand request, CancellationToken cancellationToken)
    {
        var center = await unitOfWork.PartnerCenterRepository.GetTrackedAsync(request.Id, cancellationToken);
        if (center is null)
            return OperationResult<PartnerCenterDetailDto>.NotFoundResult("Partner center not found.");

        var permitVerdict = await licenseVerification.VerifyEstablishmentPermitAsync(center.MohEstablishmentPermitNo, cancellationToken);
        if (permitVerdict.Status == LicenseVerificationStatus.Invalid)
            return OperationResult<PartnerCenterDetailDto>.FailureResult("moh_establishment_permit_no", permitVerdict.Reason);

        if (!string.IsNullOrWhiteSpace(center.EnamadCode))
        {
            var enamadVerdict = await licenseVerification.VerifyENamadAsync(center.EnamadCode, cancellationToken);
            if (enamadVerdict.Status == LicenseVerificationStatus.Invalid)
                return OperationResult<PartnerCenterDetailDto>.FailureResult("enamad_code", enamadVerdict.Reason);
        }

        center.Verify(dateTimeProvider.UtcNow);
        await unitOfWork.CommitAsync();

        var detail = await unitOfWork.PartnerCenterRepository.GetDetailAsync(center.Id, cancellationToken);
        return OperationResult<PartnerCenterDetailDto>.SuccessResult(detail!);
    }
}
