<?php
namespace PpPhp\Plugins;

use PpPhp\Core\ValidationPlugin;

class UrlRule implements ValidationPlugin
{
    public static function id(): string { return 'url'; }
    public static function label(): string { return 'Web address (URL)'; }
    public static function group(): string { return 'Format'; }

    public static function paramsSchema(): array
    {
        return [
            ['key' => 'requireScheme', 'type' => 'bool', 'label' => 'Require http(s):// prefix', 'default' => false],
            ['key' => 'https', 'type' => 'bool', 'label' => 'Require HTTPS', 'default' => false],
        ];
    }

    public static function appliesTo(): array { return ['url', 'text']; }
    public static function defaultMessage(): string { return 'Enter a valid web address.'; }

    private static function flag(mixed $v): bool { return in_array(strtolower((string) $v), ['1', 'yes', 'true', 'on'], true); }

    public static function serverCheck(mixed $value, array $params, array $record = []): bool
    {
        $u = trim((string) $value);
        $hasScheme = (bool) preg_match('~^[a-z][a-z0-9+.\-]*://~i', $u);
        if (self::flag($params['requireScheme'] ?? false) && !$hasScheme) return false;
        if (!$hasScheme) { $u = 'http://' . $u; }

        // Only http/https — blocks javascript:, data:, file:, ftp:, mailto:, etc.
        $scheme = strtolower((string) parse_url($u, PHP_URL_SCHEME));
        if (!in_array($scheme, ['http', 'https'], true)) return false;
        if (self::flag($params['https'] ?? false) && $scheme !== 'https') return false;

        // Require a real dotted host (rejects "hello" / bare "localhost").
        $host = (string) parse_url($u, PHP_URL_HOST);
        if ($host === '' || strpos($host, '.') === false) return false;

        return filter_var($u, FILTER_VALIDATE_URL) !== false;
    }

    public static function clientRule(array $params): array
    {
        $scheme = self::flag($params['https'] ?? false)
            ? 'https:\\/\\/'
            : (self::flag($params['requireScheme'] ?? false) ? 'https?:\\/\\/' : '(https?:\\/\\/)?');
        return ['pattern' => '^' . $scheme . '[\\w.\\-]+\\.[a-z]{2,}([\\/?#][^\\s]*)?$', 'flags' => 'i'];
    }
}
