<?php
declare(strict_types=1);

namespace App\Http;

class Request
{
    private string $method;
    private string $path;
    private array $headers;
    private ?string $rawBody;

    // 🔹 Datos del cliente (se llenan en ApiAuth)
    private ?int $clientId = null;
    private ?string $clientAmbiente = null;

    public function __construct()
    {
        $this->method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');

        // Ruta desde ?r=...
        $route = $_GET['r'] ?? '/';
        $route = '/' . ltrim($route, '/');
        $this->path = rtrim($route, '/') ?: '/';

        // Headers normales (HTTP_*)
        $this->headers = [];
        foreach ($_SERVER as $key => $value) {
            if (str_starts_with($key, 'HTTP_')) {
                $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
                $this->headers[$name] = $value;
            }
        }

        // Manejo especial de Content-Type y Content-Length
        if (isset($_SERVER['CONTENT_TYPE'])) {
            $this->headers['Content-Type'] = $_SERVER['CONTENT_TYPE'];
        }
        if (isset($_SERVER['CONTENT_LENGTH'])) {
            $this->headers['Content-Length'] = (string)$_SERVER['CONTENT_LENGTH'];
        }

        $this->rawBody = file_get_contents('php://input') ?: null;
    }

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

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

    public function header(string $name, ?string $default = null): ?string
    {
        $name = str_replace(' ', '-', ucwords(strtolower(str_replace('-', ' ', $name))));
        return $this->headers[$name] ?? $default;
    }

    public function getRawBody(): ?string
    {
        return $this->rawBody;
    }

    /**
     * @return array<string,mixed>|null
     */
    public function json(): ?array
    {
        if ($this->rawBody === null || $this->rawBody === '') {
            return null;
        }

        $data = json_decode($this->rawBody, true);
        if (!is_array($data)) {
            return null;
        }

        return $data;
    }

    // 🔹 Métodos para info del cliente

    public function setClientInfo(int $clientId, string $ambiente): void
    {
        $this->clientId       = $clientId;
        $this->clientAmbiente = $ambiente;
    }

    public function getClientId(): ?int
    {
        return $this->clientId;
    }

    public function getClientAmbiente(): ?string
    {
        return $this->clientAmbiente;
    }
}
