<?php
// Front controller.

declare(strict_types=1);

define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');

$config = require BASE_PATH . '/config/config.php';

if ($config['debug']) {
    error_reporting(E_ALL);
    ini_set('display_errors', '1');
} else {
    ini_set('display_errors', '0');
}

// App config holder
class App {
    private static array $c;
    public static function boot(array $c): void { self::$c = $c; }
    public static function config(string $k, $default = null) { return self::$c[$k] ?? $default; }
}
App::boot($config);

// Core autoload (core + models + admin controller base classes).
spl_autoload_register(function (string $class): void {
    foreach ([
        APP_PATH . "/core/$class.php",
        APP_PATH . "/models/$class.php",
        APP_PATH . "/controllers/admin/$class.php",
    ] as $path) {
        if (is_file($path)) { require_once $path; return; }
    }
});

require_once APP_PATH . '/core/helpers.php';

// Cheap, early per-IP throttle — sheds bot load before any session/DB work. May exit().
RateLimiter::enforce($config['rate_limit']);

Session::start();
View::init(APP_PATH . '/views');

try {
    $routes = require BASE_PATH . '/config/routes.php';
    $router = new Router($routes);
    $uri    = $_SERVER['REQUEST_URI'] ?? '/';
    $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
    $router->dispatch($method, $uri);
} catch (Throwable $ex) {
    http_response_code(500);
    if ($config['debug']) {
        header('Content-Type: text/plain; charset=utf-8');
        echo "Error: " . $ex->getMessage() . "\n\n" . $ex->getTraceAsString();
    } else {
        echo View::render('public.500', [], 'public');
    }
}
