<?php
namespace Core;

class Request
{
    private static $input = null;
    private static $headers = null;

    public static function method(): string
    {
        return $_SERVER['REQUEST_METHOD'] ?? 'GET';
    }

    public static function body(): array
    {
        if (self::$input === null) {
            self::$input = json_decode(file_get_contents('php://input'), true) ?? [];
        }
        return self::$input;
    }

    public static function input(string $key, $default = null)
    {
        $body = self::body();
        return $body[$key] ?? $default;
    }

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

    public static function getInt(string $key, int $default = 0): int
    {
        return (int)($_GET[$key] ?? $default);
    }

    public static function inputInt(string $key, int $default = 0): int
    {
        $body = self::body();
        return (int)($body[$key] ?? $default);
    }

    public static function getJson(string $key = null, $default = null)
    {
        // Se nenhuma chave for passada, retorna todo o body como array
        if ($key === null) {
            return self::body();
        }
        
        $value = $_GET[$key] ?? null;
        if ($value === null) {
            return $default;
        }
        $decoded = json_decode($value, true);
        return $decoded !== null ? $decoded : $default;
    }

    public static function inputJson(string $key = null, $default = null)
    {
        // Se nenhuma chave for passada, retorna todo o body
        if ($key === null) {
            return self::body();
        }
        $body = self::body();
        return $body[$key] ?? $default;
    }

    public static function query(): array
    {
        return $_GET;
    }

    public static function headers(): array
    {
        if (self::$headers === null) {
            self::$headers = getallheaders() ?: [];
        }
        return self::$headers;
    }

    public static function header(string $key, $default = null)
    {
        $headers = self::headers();
        foreach ($headers as $k => $v) {
            if (strtolower($k) === strtolower($key)) {
                return $v;
            }
        }
        return $default;
    }

    public static function bearerToken()
    {
        $auth = self::header('Authorization', '');
        if (preg_match('/Bearer\s+(.+)/', $auth, $matches)) {
            return $matches[1];
        }
        return null;
    }

    public static function apiKey()
    {
        return self::header('X-API-Key') ?? self::header('x-api-key');
    }

    public static function isOptions(): bool
    {
        return self::method() === 'OPTIONS';
    }

    public static function isGet(): bool
    {
        return self::method() === 'GET';
    }

    public static function isPost(): bool
    {
        return self::method() === 'POST';
    }

    public static function isPut(): bool
    {
        return self::method() === 'PUT';
    }

    public static function isDelete(): bool
    {
        return self::method() === 'DELETE';
    }

    public static function ip(): string
    {
        return $_SERVER['HTTP_X_FORWARDED_FOR'] 
            ?? $_SERVER['HTTP_X_REAL_IP'] 
            ?? $_SERVER['REMOTE_ADDR'] 
            ?? '';
    }

    public static function userAgent(): string
    {
        return $_SERVER['HTTP_USER_AGENT'] ?? '';
    }

    public static function validate(array $required): array
    {
        $errors = [];
        $body = self::body();
        
        foreach ($required as $field) {
            if (!isset($body[$field]) || (is_string($body[$field]) && trim($body[$field]) === '')) {
                $errors[] = "{$field} is required";
            }
        }
        
        return $errors;
    }

    public static function pagination(int $defaultLimit = 50, int $maxLimit = 100): array
    {
        $page = max(1, (int)self::get('page', 1));
        $limit = min($maxLimit, max(1, (int)self::get('limit', $defaultLimit)));
        $offset = ($page - 1) * $limit;
        
        return [
            'page' => $page,
            'limit' => $limit,
            'offset' => $offset
        ];
    }
}
