<?php
declare(strict_types=1);

namespace App\Core;

use App\Models\User;

final class SpaceAccess
{
    private const ORDER = ['famille', 'professeur', 'direction', 'facturation', 'axiom'];
    private const SPACE_PERMISSIONS = [
        'famille' => ['clients.view', 'familles.view', 'demandes_inscription.view'],
        'direction' => ['professeurs.view', 'ateliers.view', 'planning.view', 'presences.view', 'communications.view'],
        'facturation' => ['facturation.view', 'paiements.view', 'comptabilite.view', 'tresorerie.view'],
        'axiom' => ['utilisateurs.view', 'administration.permissions.view', 'axiom.studio.view', 'updates.view', 'backups.view'],
    ];

    public static function available(): array
    {
        if (!Auth::check()) {
            return [];
        }

        $user = Auth::user();
        $userId = (int)(Auth::id() ?? 0);
        $organisationId = (int)($user['organisation_id'] ?? 1);
        $spaces = [];

        if (self::isSuperAdmin($userId)) {
            return self::ORDER;
        }

        if (self::hasFamilyLink($userId, $organisationId) || self::hasAnyRaw($userId, self::SPACE_PERMISSIONS['famille'])) {
            $spaces[] = 'famille';
        }
        if (self::hasProfessorLink($userId, $organisationId)) {
            $spaces[] = 'professeur';
        }
        if (self::hasAnyRaw($userId, self::SPACE_PERMISSIONS['direction'])) {
            $spaces[] = 'direction';
        }
        if (self::hasAnyRaw($userId, self::SPACE_PERMISSIONS['facturation'])) {
            $spaces[] = 'facturation';
        }
        if (self::hasAnyRaw($userId, self::SPACE_PERMISSIONS['axiom'])) {
            $spaces[] = 'axiom';
        }

        return array_values(array_intersect(self::ORDER, array_unique($spaces)));
    }

    public static function active(): string
    {
        $available = self::available();
        $active = (string)($_SESSION['axiom_space'] ?? '');
        if (!in_array($active, $available, true)) {
            $active = in_array('axiom', $available, true) && Permission::isSuperAdmin()
                ? 'axiom'
                : ($available[0] ?? '');
            $_SESSION['axiom_space'] = $active;
        }
        return $active;
    }

    public static function hasProfessorLink(int $userId, int $organisationId): bool
    {
        if ($userId <= 0) {
            return false;
        }
        try {
            $stmt = Database::connection()->prepare(
                'SELECT 1 FROM professeurs
                 WHERE utilisateur_id=? AND organisation_id=? AND deleted_at IS NULL
                 LIMIT 1'
            );
            $stmt->execute([$userId, $organisationId]);
            return (bool)$stmt->fetchColumn();
        } catch (\Throwable) {
            return false;
        }
    }

    public static function hasFamilyLink(int $userId, int $organisationId): bool
    {
        if ($userId <= 0) {
            return false;
        }
        try {
            $stmt = Database::connection()->prepare(
                'SELECT 1
                 FROM cda_family_accounts fa
                 INNER JOIN clients c ON c.id=fa.client_id
                 WHERE fa.utilisateur_id=? AND c.organisation_id=? AND c.deleted_at IS NULL
                 LIMIT 1'
            );
            $stmt->execute([$userId, $organisationId]);
            return (bool)$stmt->fetchColumn();
        } catch (\Throwable) {
            return false;
        }
    }

    public static function allowsPath(string $path): bool
    {
        // L’espace organise l’interface. Les contrôleurs et Permission::require()
        // restent l’unique autorité d’accès aux routes et aux actions.
        return true;
    }

    private static function hasAnyRaw(int $userId, array $permissions): bool
    {
        foreach ($permissions as $permission) {
            if (User::hasPermission($userId, $permission)) {
                return true;
            }
        }
        return false;
    }

    private static function isSuperAdmin(int $userId): bool
    {
        return $userId > 0 && User::hasAnyRole($userId, 'super_admin', 'superadmin');
    }
}
