<?php

declare(strict_types=1);

namespace App\Core;

final class Request
{
    private function __construct(
        private string $method,
        private string $path,
        private array $query,
        private array $input,
        private array $server
    ) {}

    public static function capture(): self
    {
        $uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
        $scriptName = str_replace('\\', '/', $_SERVER['SCRIPT_NAME'] ?? '');
        $basePath = rtrim(str_replace('/index.php', '', $scriptName), '/');

        if ($basePath !== '' && $basePath !== '/' && str_starts_with($uri, $basePath)) {
            $uri = substr($uri, strlen($basePath)) ?: '/';
        }

        $path = '/' . trim($uri, '/');
        $path = $path === '//' ? '/' : $path;

        return new self(
            strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET'),
            $path,
            $_GET,
            $_POST,
            $_SERVER
        );
    }

    public function method(): string { return $this->method; }
    public function path(): string { return $this->path; }
    public function query(?string $key = null, mixed $default = null): mixed
    {
        return $key === null ? $this->query : ($this->query[$key] ?? $default);
    }

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

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

    public function wantsJson(): bool
    {
        $accept = strtolower((string) $this->server('HTTP_ACCEPT', ''));
        return str_contains($accept, 'application/json') || str_starts_with($this->path, '/api/');
    }
}
