<?php

namespace App\Core;

/**
 * ITSWEBER CMS – Request Abstraction
 */
class Request
{
    private string $method;
    private string $uri;
    private array $query;
    private array $post;
    private array $server;
    private array $files;

    public function __construct(string $method, string $uri, array $query, array $post, array $server, array $files)
    {
        $this->method = strtoupper($method);
        $this->uri = $uri;
        $this->query = $query;
        $this->post = $post;
        $this->server = $server;
        $this->files = $files;
    }

    /**
     * Capture the current HTTP request.
     */
    public static function capture(): self
    {
        $uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
        $uri = '/' . trim($uri, '/');
        if ($uri !== '/') {
            $uri = rtrim($uri, '/');
        }

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

    public function method(): string
    {
        return $this->method;
    }

    public function uri(): string
    {
        return $this->uri;
    }

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

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

    /**
     * Get a query parameter (?key=value).
     */
    public function query(string $key, mixed $default = null): mixed
    {
        return $this->query[$key] ?? $default;
    }

    /**
     * Get a POST parameter.
     */
    public function input(string $key, mixed $default = null): mixed
    {
        return $this->post[$key] ?? $default;
    }

    /**
     * Get all POST data.
     */
    public function all(): array
    {
        return $this->post;
    }

    /**
     * Get an uploaded file.
     */
    public function file(string $key): ?array
    {
        return $this->files[$key] ?? null;
    }

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