<?php
class Request
{
    private array $getParams;
    private array $postParams;
    private array $serverParams;
    private array $files;
    private array $routeParams = [];

    public function __construct()
    {
        $this->getParams = $_GET;
        $this->postParams = $_POST;
        $this->serverParams = $_SERVER;
        $this->files = $_FILES;
    }

    public function get(string $key, $default = null)
    {
        return $this->getParams[$key] ?? $default;
    }

    public function post(string $key, $default = null)
    {
        return $this->postParams[$key] ?? $default;
    }

    public function input(string $key, $default = null)
    {
        return $this->postParams[$key] ?? $this->getParams[$key] ?? $default;
    }

    public function all(): array
    {
        return array_merge($this->getParams, $this->postParams);
    }

    public function only(array $keys): array
    {
        $all = $this->all();
        return array_intersect_key($all, array_flip($keys));
    }

    public function has(string $key): bool
    {
        return isset($this->postParams[$key]) || isset($this->getParams[$key]);
    }

    public function file(string $name): ?array
    {
        return $this->files[$name] ?? null;
    }

    public function method(): string
    {
        return strtoupper($this->serverParams['REQUEST_METHOD'] ?? 'GET');
    }

    public function uri(): string
    {
        $uri = $this->getParams['_url'] ?? '';
        $uri = '/' . ltrim($uri, '/');
        $uri = strtok($uri, '?');
        return $uri ?: '/';
    }

    public function isAjax(): bool
    {
        return strtolower($this->serverParams['HTTP_X_REQUESTED_WITH'] ?? '') === 'xmlhttprequest';
    }

    public function ip(): string
    {
        if (!empty($this->serverParams['HTTP_X_FORWARDED_FOR'])) {
            $ips = explode(',', $this->serverParams['HTTP_X_FORWARDED_FOR']);
            return trim($ips[0]);
        }
        return $this->serverParams['REMOTE_ADDR'] ?? '0.0.0.0';
    }

    public function userAgent(): string
    {
        return $this->serverParams['HTTP_USER_AGENT'] ?? '';
    }

    public function setRouteParams(array $params): void
    {
        $this->routeParams = $params;
    }

    public function routeParam(string $name, $default = null)
    {
        return $this->routeParams[$name] ?? $default;
    }

    public function header(string $name, $default = null): ?string
    {
        $key = 'HTTP_' . strtoupper(str_replace('-', '_', $name));
        return $this->serverParams[$key] ?? $default;
    }

    public function bearerToken(): ?string
    {
        $auth = $this->serverParams['HTTP_AUTHORIZATION'] ?? '';
        if (str_starts_with($auth, 'Bearer ')) {
            return substr($auth, 7);
        }
        return null;
    }

    public function csrfToken(): ?string
    {
        return $this->post('_token') ?? $this->header('X-CSRF-TOKEN');
    }
}