<?php
namespace Core;

class Request {
    public string $method;
    public string $uri;

    public function __construct() {
        $this->method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
        $raw  = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
        $base = '/cbe/sms/public';
        // Strip base path prefix
        if (str_starts_with($raw, $base)) {
            $uri = substr($raw, strlen($base));
        } else {
            $uri = $raw;
        }
        $this->uri = $uri === '' ? '/' : $uri;
    }

    public function get(string $key, mixed $default = null): mixed {
        return $_GET[$key] ?? $default;
    }

    public function post(string $key, mixed $default = null): mixed {
        return $_POST[$key] ?? $default;
    }

    public function all(): array { return array_merge($_GET, $_POST); }

    public function input(string $key, mixed $default = null): mixed {
        return $_POST[$key] ?? $_GET[$key] ?? $default;
    }

    public function file(string $key): ?array {
        return isset($_FILES[$key]) && $_FILES[$key]['error'] === UPLOAD_ERR_OK ? $_FILES[$key] : null;
    }

    public function isPost(): bool { return $this->method === 'POST'; }

    public function sanitize(string $key, mixed $default = ''): string {
        $val = $this->input($key, $default);
        return htmlspecialchars(strip_tags(trim((string)$val)), ENT_QUOTES, 'UTF-8');
    }

    public function validate(array $rules): array {
        $errors = [];
        foreach ($rules as $field => $rule) {
            $val = $this->input($field, '');
            foreach (explode('|', $rule) as $r) {
                [$rName, $rParam] = array_pad(explode(':', $r, 2), 2, null);
                match($rName) {
                    'required' => (!$val && $val !== '0') ? $errors[$field][] = "$field is required" : null,
                    'email'    => (!filter_var($val, FILTER_VALIDATE_EMAIL)) ? $errors[$field][] = "Invalid email" : null,
                    'min'      => (strlen((string)$val) < (int)$rParam) ? $errors[$field][] = "$field min $rParam chars" : null,
                    'max'      => (strlen((string)$val) > (int)$rParam) ? $errors[$field][] = "$field max $rParam chars" : null,
                    'numeric'  => (!is_numeric($val) && $val !== '') ? $errors[$field][] = "$field must be numeric" : null,
                    'in'       => ($val && !in_array($val, explode(',', $rParam))) ? $errors[$field][] = "Invalid $field" : null,
                    default    => null,
                };
            }
        }
        return $errors;
    }
}
