<?php
/**
 * Antara — sanitization & validation helpers.
 */

final class AntaraSanitize
{
    public static function str($v, int $maxLen = 255): string
    {
        if (!is_string($v)) $v = (string)$v;
        $v = trim($v);
        if (strlen($v) > $maxLen) $v = substr($v, 0, $maxLen);
        return $v;
    }

    public static function email($v): ?string
    {
        $v = self::str($v, 254);
        if ($v === '') return null;
        $v = strtolower($v);
        return filter_var($v, FILTER_VALIDATE_EMAIL) ? $v : null;
    }

    public static function username($v): ?string
    {
        $v = self::str($v, 64);
        if ($v === '') return null;
        // letters, numbers, dot, dash, underscore, accents
        return preg_match('/^[\p{L}\p{N}._\-@+ ]{2,64}$/u', $v) ? $v : null;
    }

    public static function phone($v): ?string
    {
        $v = self::str($v, 32);
        if ($v === '') return null;
        $v = preg_replace('/\s+/', '', $v);
        // optional leading +, then 6-20 digits
        return preg_match('/^\+?\d{6,20}$/', $v) ? $v : null;
    }

    /** Digits-only form for comparing phone numbers on login. */
    public static function phoneDigits($v): string
    {
        if (!is_string($v)) $v = (string)$v;
        return preg_replace('/\D/', '', trim($v));
    }

    public static function role($v): ?string
    {
        $v = self::str($v, 32);
        return in_array($v, ['super_admin', 'admin', 'usuario'], true) ? $v : null;
    }

    public static function bool($v): bool
    {
        return filter_var($v, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) === true;
    }

    public static function intRange($v, int $min, int $max, int $default): int
    {
        $i = filter_var($v, FILTER_VALIDATE_INT);
        if ($i === false) return $default;
        return max($min, min($max, $i));
    }

    public static function password($v): ?string
    {
        if (!is_string($v)) return null;
        $len = strlen($v);
        if ($len < 8 || $len > 200) return null;
        return $v;
    }

    /**
     * WebAuthn rpId: registrable domain string, or null to use HTTP_HOST autodetection.
     * Empty string / "auto" / JSON null from client → null.
     */
    public static function rpId($v): ?string
    {
        if ($v === null) return null;
        if (!is_string($v)) return null;
        $v = strtolower(trim($v));
        if ($v === '' || $v === 'auto') return null;
        if (strlen($v) > 253) return null;
        if (filter_var($v, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) return $v;
        $host = filter_var($v, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME);
        if ($host !== false) return $host;
        // Dev / LAN: single-label hosts (e.g. localhost) are valid rpId but often rejected by FILTER_VALIDATE_DOMAIN.
        if (preg_match('/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/', $v)) return $v;
        return null;
    }

    /** Read JSON body of a fetch request safely. Returns [] on failure. */
    public static function readJsonBody(): array
    {
        $raw = @file_get_contents('php://input');
        if (!is_string($raw) || $raw === '') return [];
        $data = json_decode($raw, true);
        return is_array($data) ? $data : [];
    }
}
