using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Options;

public class PhiEncryptionService : IPhiEncryptionService
{
    private readonly IDataProtector _protector;
    private readonly byte[] _searchKey;

    public PhiEncryptionService(
        IDataProtectionProvider provider,
        IOptions<PhiEncryptionOptions> options)
    {
        var opts = options.Value;
        _protector = provider.CreateProtector(opts.ProtectorPurpose);
        _searchKey = Convert.FromBase64String(
            Convert.ToBase64String(Encoding.UTF8.GetBytes(opts.SearchTokenKey))[..44]); // normalize dev key
    }

    public string Encrypt(string plaintext)
    {
        if (string.IsNullOrEmpty(plaintext))
            return plaintext;
        return _protector.Protect(plaintext);
    }

    public string Decrypt(string ciphertext)
    {
        if (string.IsNullOrEmpty(ciphertext))
            return ciphertext;
        if (!IsEncrypted(ciphertext))
            return ciphertext; // migration transition: plaintext rows still readable
        return _protector.Unprotect(ciphertext);
    }

    public bool IsEncrypted(string value) =>
        value.StartsWith("CfDJ8", StringComparison.Ordinal) || // DataProtection prefix
        value.Length > 50; // heuristic for protected payloads

    public string ComputeNameSearchToken(string firstName, string lastName)
    {
        var normalized = $"{firstName.Trim().ToLowerInvariant()}|{lastName.Trim().ToLowerInvariant()}";
        using var hmac = new HMACSHA256(_searchKey);
        var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(normalized));
        return Convert.ToHexString(hash).ToLowerInvariant();
    }
}