<?php

require_once __DIR__ . '/../vendor/autoload.php';

use Dotenv\Dotenv;
use App\Helpers\Response;

date_default_timezone_set('America/Costa_Rica');
header('Content-Type: application/json');

// ==================
// Global error handling
// ==================
set_exception_handler(function (Throwable $e) {
    Response::error(
        $_ENV['APP_DEBUG'] ?? false
            ? $e->getMessage()
            : 'Internal server error',
        500
    );
});

// ==================
// Load ENV
// ==================
$dotenv = Dotenv::createImmutable(dirname(__DIR__));
$dotenv->load();

// ==================
// Request context
// ==================
$httpMethod = $_SERVER['REQUEST_METHOD'];
$requestUri = $_SERVER['REQUEST_URI'];
$path = parse_url($requestUri, PHP_URL_PATH);

// ==================
// Normalize base path
// ==================
$basePath = rtrim($_ENV['BASE_PATH'] ?? '', '/');
if ($basePath && str_starts_with($path, $basePath)) {
    $path = substr($path, strlen($basePath));
}

$path = $path ?: '/';

// ==================
// Request body (JSON)
// ==================
$requestBody = [];
if (in_array($httpMethod, ['POST', 'PUT', 'PATCH'], true)) {
    $raw = file_get_contents('php://input');
    $requestBody = json_decode($raw, true) ?? [];
}

$GLOBALS['request_body'] = $requestBody;

// ==================
// Load routes
// ==================
$routes = require __DIR__ . '/../routes/api.php';

// ==================
// Router
// ==================
$routeFound = false;

foreach ($routes as $routeKey => $routeConfig) {

    [$routeMethod, $routePath] = explode(' ', $routeKey, 2);

    if ($httpMethod !== $routeMethod) {
        continue;
    }

    $pattern = preg_replace('#\{[a-zA-Z_]+\}#', '([^/]+)', $routePath);
    $pattern = '#^' . $pattern . '$#';

    if (!preg_match($pattern, $path, $matches)) {
        continue;
    }

    array_shift($matches);

    // ==================
    // Middleware
    // ==================
    foreach ($routeConfig['middleware'] ?? [] as $middleware) {
        $middleware::handle();
    }

    // ==================
    // Controller
    // ==================
    [$controller, $action] = $routeConfig['controller'];
    (new $controller)->$action(...$matches);

    $routeFound = true;
    break;
}

// ==================
// 404
// ==================
if (!$routeFound) {
    Response::error('Route not found', 404);
}
