<?php
declare(strict_types=1);

// -----------------------------------------------------------------------------
// bootstrap.php
// Initialise l'environnement PHP : timezone UTC, exception applicative,
// chargement .env (dev local), autoload PSR-4 pour le namespace Infolab\,
// et conversion des warnings PHP en exceptions.
// -----------------------------------------------------------------------------

// Tout en UTC en interne, les clients gèrent leur fuseau côté front.
date_default_timezone_set('UTC');

/**
 * Exception applicative : porte un code HTTP et le payload JSON à renvoyer.
 * Levée par les contrôleurs et helpers, attrapée par le handler global de index.php.
 * Définie dans le namespace racine pour être accessible depuis tout le code.
 */
final class ApiException extends \RuntimeException
{
    /** @param array<string,mixed> $payload */
    public function __construct(public readonly int $statusCode, public readonly array $payload)
    {
        parent::__construct($payload['error'] ?? 'error');
    }
}

/**
 * Raccourci pour interrompre rapidement le traitement avec une erreur typée.
 *
 * @param array<string,mixed> $extra champs additionnels à inclure dans le payload JSON
 */
function api_abort(int $status, string $error, ?string $message = null, array $extra = []): never
{
    $payload = ['error' => $error];
    if ($message !== null) {
        $payload['message'] = $message;
    }
    if ($extra !== []) {
        $payload += $extra;
    }
    throw new ApiException($status, $payload);
}

// -----------------------------------------------------------------------------
// Chargement minimal d'un fichier .env (pour le dev local sous Laragon).
// En prod docker, c'est `env_file:` qui pousse les variables — on ne fait rien.
// -----------------------------------------------------------------------------
$envFile = dirname(__DIR__) . '/.env';
if (is_file($envFile)) {
    foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
        $line = trim($line);
        if ($line === '' || $line[0] === '#' || !str_contains($line, '=')) {
            continue;
        }
        [$k, $v] = explode('=', $line, 2);
        $k = trim($k);
        $v = trim($v);
        // Strip guillemets simples ou doubles s'ils encadrent la valeur.
        if (strlen($v) >= 2 && (
            ($v[0] === '"' && substr($v, -1) === '"') ||
            ($v[0] === "'" && substr($v, -1) === "'")
        )) {
            $v = substr($v, 1, -1);
        }
        // Ne pas écraser un env déjà défini (ex: par docker, par le shell de CI...)
        if (getenv($k) === false) {
            putenv("$k=$v");
            $_ENV[$k] = $v;
        }
    }
}

// -----------------------------------------------------------------------------
// Autoload PSR-4 pour le namespace Infolab\ -> src/
// On évite Composer : pas de dépendance externe, pas de `composer install`.
// -----------------------------------------------------------------------------
spl_autoload_register(static function (string $class): void {
    $prefix = 'Infolab\\';
    if (!str_starts_with($class, $prefix)) {
        return;
    }
    $relative = substr($class, strlen($prefix));
    $path = __DIR__ . '/' . str_replace('\\', '/', $relative) . '.php';
    if (is_file($path)) {
        require $path;
    }
});

// -----------------------------------------------------------------------------
// Convertit les warnings/notices PHP en exceptions (sauf ceux supprimés par @).
// Centralise tout le tracking d'erreurs dans le handler de index.php.
// -----------------------------------------------------------------------------
set_error_handler(static function (int $severity, string $message, string $file, int $line): bool {
    if (!(error_reporting() & $severity)) {
        return false;
    }
    throw new \ErrorException($message, 0, $severity, $file, $line);
});
