<?php
declare(strict_types=1);

namespace App\Core;

use RuntimeException;

/**
 * Contexte d'organisation immuable pour la requête courante.
 * Toute donnée métier doit être lue/écrite dans ce périmètre.
 */
final class TenantContext
{
    private static ?int $organisationId = null;

    public static function bootFromAuthenticatedUser(): void
    {
        $userId = Auth::id();
        if ($userId === null) {
            self::$organisationId = null;
            return;
        }

        $user = Auth::user();
        $organisationId = (int)($user['organisation_id'] ?? 0);
        $sessionOrganisationId = (int)($_SESSION['organisation_id'] ?? 0);

        if ($organisationId <= 0 || $sessionOrganisationId <= 0 || $organisationId !== $sessionOrganisationId) {
            Auth::logout();
            http_response_code(403);
            exit('Accès refusé. Contexte d’organisation invalide.');
        }

        self::$organisationId = $organisationId;
    }

    public static function id(): int
    {
        if (self::$organisationId === null) {
            self::bootFromAuthenticatedUser();
        }
        if (self::$organisationId === null || self::$organisationId <= 0) {
            throw new RuntimeException('Organisation active introuvable.');
        }
        return self::$organisationId;
    }

    public static function matches(int $organisationId): bool
    {
        return $organisationId > 0 && hash_equals((string)self::id(), (string)$organisationId);
    }

    public static function requireMatch(int $organisationId): void
    {
        if (!self::matches($organisationId)) {
            http_response_code(404);
            exit('Ressource introuvable.');
        }
    }

    public static function reset(): void
    {
        self::$organisationId = null;
    }
}
