#nullable enable
using Baya.Application.Contracts.Common;
using Baya.Application.Contracts.Persistence;
using Baya.Application.Models.Common;
using Baya.Domain.Entities.User;
using Mediator;

namespace Baya.Application.Features.Identity.Commands.SetPrimaryBankAccount;

internal sealed class SetPrimaryBankAccountCommandHandler(ICurrentUser currentUser, IUnitOfWork unitOfWork)
    : IRequestHandler<SetPrimaryBankAccountCommand, OperationResult<bool>>
{
    public async ValueTask<OperationResult<bool>> Handle(SetPrimaryBankAccountCommand request, CancellationToken cancellationToken)
    {
        if (currentUser.UserId is not { } userId)
            return OperationResult<bool>.UnauthorizedResult("Not authenticated.");

        if (currentUser.Roles?.Contains(RoleNames.Nurse) != true)
            return OperationResult<bool>.ForbiddenResult("Only a nurse can manage payout accounts.");

        var nurseId = await unitOfWork.NurseProfileRepository.GetProfileIdByUserIdAsync(userId, cancellationToken);
        if (nurseId is not { } nid)
            return OperationResult<bool>.NotFoundResult("Bank account not found.");

        // Verify tenancy before touching any row — a non-owned/nonexistent id must never clear the
        // existing primary.
        var account = await unitOfWork.NurseBankAccountRepository.GetOwnedAsync(request.Id, nid, cancellationToken);
        if (account is null)
            return OperationResult<bool>.NotFoundResult("Bank account not found.");

        if (!account.IsPrimary)
            await unitOfWork.NurseBankAccountRepository.SetPrimaryAsync(nid, request.Id, cancellationToken);

        return OperationResult<bool>.SuccessResult(true);
    }
}
