<?php
/**
 * Contrôleur de base — fournit les utilitaires communs à tous les
 * contrôleurs de l'application.
 *
 * Chaque contrôleur de page étend cette classe et implémente ses
 * propres méthodes d'action (GET, POST, AJAX).
 */
class Controller
{
    protected Database $db;
    protected Auth $auth;
    protected ?array $currentUser;
    protected Module $moduleRegistry;
    protected Settings $settings;
    protected I18n $i18n;
    protected Logger $logger;
    protected string $activeTheme;

    public function __construct()
    {
        $this->db             = Database::getInstance();
        $this->settings       = Settings::getInstance();
        $this->logger         = Logger::getInstance();
        $this->moduleRegistry = Module::getInstance();
        $this->i18n           = I18n::getInstance();
        $this->auth           = new Auth();
        $this->currentUser    = $this->auth->getCurrentUser();

        $appDefault = $this->settings->get('default_theme', DEFAULT_THEME);
        $this->activeTheme = $this->currentUser
            ? ($this->currentUser['theme'] ?: $appDefault)
            : $appDefault;
        if (Session::has('theme') && in_array(Session::get('theme'), THEMES)) {
            $this->activeTheme = Session::get('theme');
        }
    }

    protected function requireLogin(): void
    {
        if (!$this->auth->isLoggedIn()) {
            $this->redirect('/login?redirect=' . urlencode($_SERVER['REQUEST_URI'] ?? '/'));
        }
    }

    protected function requireRole(string ...$roles): void
    {
        $this->auth->requireRole(...$roles);
    }

    protected function ensureCsrf(): void
    {
        if (!Session::has('csrf_token')) {
            Session::set('csrf_token', bin2hex(random_bytes(32)));
        }
    }

    protected function verifyCsrf(): bool
    {
        return hash_equals(
            Session::get('csrf_token', ''),
            $_POST['csrf_token'] ?? ''
        );
    }

    protected function redirect(string $url): never
    {
        header('Location: ' . $url);
        exit;
    }

    protected function json(array $data, int $status = 200): never
    {
        http_response_code($status);
        header('Content-Type: application/json; charset=UTF-8');
        echo json_encode($data);
        exit;
    }

    /**
     * Rend un template avec les variables communes injectées.
     *
     * @param string $template Chemin absolu vers le template PHP
     * @param array  $data     Variables spécifiques à la page
     */
    protected function view(string $template, array $data = []): void
    {
        $data += [
            'currentUser'    => $this->currentUser,
            'auth'           => $this->auth,
            'activeTheme'    => $this->activeTheme,
            'settings'       => $this->settings,
            'i18n'           => $this->i18n,
            'moduleRegistry' => $this->moduleRegistry,
            'db'             => $this->db,
        ];
        View::display($template, $data);
    }

    protected function isPost(): bool
    {
        return $_SERVER['REQUEST_METHOD'] === 'POST';
    }

    protected function input(string $key, string $default = ''): string
    {
        return trim((string)($_POST[$key] ?? $_GET[$key] ?? $default));
    }
}
