#nullable enable
using System.Security.Cryptography;
using System.Text;
using Baya.Application.Contracts.Common;
using Microsoft.Extensions.Options;

namespace Baya.Infrastructure.CrossCutting.Seams;

/// <summary>
/// Mock <see cref="IBankAccountOwnershipVerifier"/>: a deterministic fake استعلام شبا inquiry — no real
/// bank/KYC call and no money moves. Every IBAN returns a match except the configured
/// <see cref="BankOwnershipOptions.MismatchIban"/>, which returns <c>MatchedNationalId = false</c> so the
/// ownership-mismatch path is testable. The vendor ref is derived from the IBAN, so re-running the same
/// inquiry is idempotent. The real implementation (Finnotech/banking-bridge) swaps in via a registration
/// change — callers are unchanged.
/// </summary>
public sealed class MockBankAccountOwnershipVerifier(IOptions<SeamOptions> options) : IBankAccountOwnershipVerifier
{
    private readonly BankOwnershipOptions _options = options.Value.BankOwnership;

    // nurseNationalId is part of the real vendor contract (owner ↔ national-id match); the mock decides
    // the outcome from the IBAN alone so both paths are deterministically testable.
    public Task<OwnershipInquiryResult> VerifyOwnershipAsync(string iban, string? nurseNationalId, CancellationToken cancellationToken = default)
    {
        var normalized = Normalize(iban);
        var matched = !string.Equals(normalized, Normalize(_options.MismatchIban), StringComparison.OrdinalIgnoreCase);
        var holder = matched ? _options.MatchedHolderName : _options.MismatchHolderName;
        var vendorRef = $"MOCK-SHEBA-{Token(normalized)}";

        return Task.FromResult(new OwnershipInquiryResult(matched, holder, vendorRef));
    }

    private static string Normalize(string iban)
        => string.IsNullOrEmpty(iban) ? string.Empty : iban.Replace(" ", string.Empty).ToUpperInvariant();

    private static string Token(string value)
        => Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(value)))[..12];
}
