<?php

declare(strict_types=1);

namespace App\Shared\Infrastructure\Monitoring;

/**
 * Centralized PII (Personally Identifiable Information) patterns.
 *
 * Used by both log processors and error tracking to ensure consistent
 * PII filtering across all observability systems (RGPD compliance).
 *
 * @see Story 1.8 - NFR-OB3: RGPD compliance in logs and error reports
 */
final class PiiPatterns
{
    /**
     * Keys that may contain PII and should be redacted.
     */
    public const array SENSITIVE_KEYS = [
        // Authentication
        'password',
        'token',
        'secret',
        'key',
        'authorization',
        'cookie',
        'session',
        'refresh_token',
        'access_token',

        // Personal data
        'email',
        'phone',
        'address',
        'ip',
        'user_agent',

        // French field names
        'nom',
        'prenom',
        'adresse',
        'telephone',
        'nir',
        'numero_securite_sociale',
        'securite_sociale',

        // English field names
        'name',
        'firstname',
        'lastname',
        'first_name',
        'last_name',
    ];

    /**
     * Regex patterns that indicate PII in values.
     */
    public const array VALUE_PATTERNS = [
        '/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/',  // Email
        '/\b\d{10,}\b/',                                      // Phone numbers
        '/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/',          // IPv4
        '/\b[12]\d{2}(0[1-9]|1[0-2])\d{2}\d{3}\d{3}\d{2}\b/', // French NIR (numéro de sécurité sociale)
    ];

    /**
     * Check if a key name suggests it contains PII.
     */
    public static function isSensitiveKey(string $key): bool
    {
        $normalizedKey = strtolower($key);

        foreach (self::SENSITIVE_KEYS as $pattern) {
            if (str_contains($normalizedKey, $pattern)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if a value matches PII patterns.
     */
    public static function containsPii(string $value): bool
    {
        foreach (self::VALUE_PATTERNS as $pattern) {
            if (preg_match($pattern, $value)) {
                return true;
            }
        }

        return false;
    }
}
