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

namespace Baya.Infrastructure.CrossCutting.Seams;

/// <summary>
/// Mock <see cref="IShahkarVerifier"/>: a deterministic fake شاهکار phone↔national-id inquiry — no real
/// Shahkar/KYC call. Matches every pair except the configured <see cref="ShahkarOptions.SharedSimPhone"/>
/// (returns the explicit shared-SIM failure state) and <see cref="ShahkarOptions.MismatchNationalId"/>
/// (returns a plain mismatch). The vendor ref is derived from the inputs, so re-running is idempotent. A
/// real Finnotech/KYC client swaps in by a registration change — callers are unchanged.
/// </summary>
public sealed class MockShahkarVerifier(IOptions<SeamOptions> options) : IShahkarVerifier
{
    private readonly ShahkarOptions _options = options.Value.Shahkar;

    public Task<ShahkarMatchResult> MatchAsync(string? phoneNumber, string? nationalId, CancellationToken cancellationToken = default)
    {
        var phone = (phoneNumber ?? string.Empty).Trim();
        var vendorRef = $"MOCK-SHAHKAR-{Token(phone + "|" + (nationalId ?? string.Empty))}";

        if (string.Equals(phone, _options.SharedSimPhone, StringComparison.Ordinal))
        {
            var json = Payload("shared_sim", phone, nationalId, matched: false);
            return Task.FromResult(new ShahkarMatchResult(
                Matched: false,
                IsSharedSim: true,
                VendorRef: vendorRef,
                ExternalResponseJson: json,
                FailureReason: "This SIM appears to be registered to a family member. Please use a SIM registered in your own name."));
        }

        if (string.Equals(nationalId, _options.MismatchNationalId, StringComparison.Ordinal))
        {
            var json = Payload("mismatch", phone, nationalId, matched: false);
            return Task.FromResult(new ShahkarMatchResult(
                Matched: false,
                IsSharedSim: false,
                VendorRef: vendorRef,
                ExternalResponseJson: json,
                FailureReason: "The phone number is not registered to your national ID."));
        }

        return Task.FromResult(new ShahkarMatchResult(
            Matched: true,
            IsSharedSim: false,
            VendorRef: vendorRef,
            ExternalResponseJson: Payload("match", phone, nationalId, matched: true),
            FailureReason: null));
    }

    private static string Payload(string outcome, string phone, string? nationalId, bool matched)
        => JsonSerializer.Serialize(new
        {
            provider = "mock_shahkar",
            outcome,
            matched,
            phone_last4 = phone.Length >= 4 ? phone[^4..] : phone,
            national_id_present = !string.IsNullOrEmpty(nationalId)
        });

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