<?php

declare(strict_types=1);

/**
 * Front controller du vhost admin (back-office + API sous /api).
 *
 * Apache reecrit toute requete non-fichier vers ce fichier (RewriteRule ^ index.php).
 * Le REQUEST_URI arrive intact (pas de prefixe strippe), donc le routeur voit
 * "/", "/api/health", etc.
 */

use App\Auth\SessionManager;
use App\Controllers\AuthController;
use App\Controllers\CategoryController;
use App\Controllers\DashboardController;
use App\Controllers\HealthController;
use App\Controllers\HomeController;
use App\Controllers\MeController;
use App\Controllers\PasswordResetController;
use App\Controllers\ProductController;
use App\Controllers\ProfileController;
use App\Core\Autoloader;
use App\Core\Config;
use App\Core\Database;
use App\Core\Request;
use App\Core\Response;
use App\Core\Router;

// src/public/admin/index.php : __DIR__ = src/public/admin ; remonter de deux
// niveaux (admin -> public -> src) pour atteindre la racine src/.
require dirname(__DIR__, 2) . '/app/Core/Autoloader.php';
Autoloader::register();

// En-tetes de securite poses tot, valables sur toute reponse y compris une 500.
header('X-Content-Type-Options: nosniff');
header('X-Robots-Tag: noindex, nofollow');

$config = new Config();
date_default_timezone_set($config->timezone());

try {
    // Acces BDD paresseux : la connexion n'est ouverte qu'au premier query(),
    // donc la home back-office reste servie meme base indisponible.
    $database = new Database($config);

    // Demarre la session du vhost admin avant le dispatch (effet de bord global,
    // hors du Core stateless). Les controleurs y rattachent leur SessionManager.
    (new SessionManager($config))->start();

    $router = new Router($config, $database);
    $router->add('GET', '/', [HomeController::class, 'index']);
    $router->add('GET', '/api/health', [HealthController::class, 'index']);

    // Authentification back-office (mlt.md section 12). Le docroot du vhost admin
    // etant src/public/admin, le Router voit "/login" (pas de prefixe "/admin").
    $router->add('GET', '/login', [AuthController::class, 'showLogin']);
    $router->add('POST', '/login', [AuthController::class, 'login']);
    $router->add('POST', '/logout', [AuthController::class, 'logout']);
    $router->add('GET', '/forgot_password', [PasswordResetController::class, 'showRequest']);
    $router->add('POST', '/forgot_password', [PasswordResetController::class, 'submitRequest']);
    $router->add('GET', '/reset_password', [PasswordResetController::class, 'showConfirm']);
    $router->add('POST', '/reset_password', [PasswordResetController::class, 'submitConfirm']);

    // RBAC : identite + permissions de la session courante (gardee par SessionGuard).
    $router->add('GET', '/api/me', [MeController::class, 'show']);

    // Back-office (P3) : pages rendues serveur sous /admin, gardees par SessionGuard.
    $router->add('GET', '/admin/dashboard', [DashboardController::class, 'index']);

    // CRUD Categories (permission category.manage). Pas de suppression dure : toggle is_active.
    $router->add('GET', '/admin/categories', [CategoryController::class, 'index']);
    $router->add('GET', '/admin/categories/new', [CategoryController::class, 'create']);
    $router->add('POST', '/admin/categories', [CategoryController::class, 'store']);
    $router->add('GET', '/admin/categories/{id}/edit', [CategoryController::class, 'edit']);
    $router->add('POST', '/admin/categories/{id}', [CategoryController::class, 'update']);
    $router->add('POST', '/admin/categories/{id}/toggle', [CategoryController::class, 'toggle']);

    // Profil self-service : definition du PIN d'action sensible (RG-T13).
    $router->add('GET', '/admin/profile/pin', [ProfileController::class, 'showPin']);
    $router->add('POST', '/admin/profile/pin', [ProfileController::class, 'updatePin']);

    // CRUD Produits (product.read/create/update/delete). PIN equipier + audit sur
    // changement prix/TVA (update) et suppression (delete).
    $router->add('GET', '/admin/products', [ProductController::class, 'index']);
    $router->add('GET', '/admin/products/new', [ProductController::class, 'create']);
    $router->add('POST', '/admin/products', [ProductController::class, 'store']);
    $router->add('GET', '/admin/products/{id}/edit', [ProductController::class, 'edit']);
    $router->add('POST', '/admin/products/{id}', [ProductController::class, 'update']);
    $router->add('GET', '/admin/products/{id}/delete', [ProductController::class, 'confirmDelete']);
    $router->add('POST', '/admin/products/{id}/delete', [ProductController::class, 'destroy']);

    $response = $router->dispatch(Request::fromGlobals());
    $response->send();
} catch (Throwable $exception) {
    // En debug on remonte le message pour iterer ; en prod, reponse generique
    // pour ne rien divulguer de la pile interne (information disclosure).
    $payload = $config->isDebug()
        ? ['data' => null, 'error' => ['code' => 'INTERNAL_ERROR', 'message' => $exception->getMessage()]]
        : ['data' => null, 'error' => ['code' => 'INTERNAL_ERROR', 'message' => 'Internal server error']];

    (new Response())->json($payload, 500)->send();
}
