<?php

namespace App\Middleware;

use App\Core\Request;
use App\Core\Response;
use App\Models\User;

class PermissionMiddleware
{
    private $userModel;
    
    public function __construct()
    {
        $this->userModel = new User();
    }
    
    /**
     * Vérifier si l'utilisateur a la permission requise
     * 
     * Usage dans les routes:
     * $router->get('/deals', [DealController::class, 'index'])
     *        ->middleware(new PermissionMiddleware('deals.view'));
     */
    public function handle(Request $request, callable $next, string $permission, ?string $scopeParam = null)
    {
        $userId = $_SESSION['user_id'] ?? null;
        
        if (!$userId) {
            return $this->unauthorized('Non authentifié');
        }
        
        // Vérifier la permission
        if (!$this->userModel->hasPermission($userId, $permission)) {
            return $this->forbidden("Permission requise: {$permission}");
        }
        
        // Si un paramètre de scope est fourni, vérifier le périmètre
        if ($scopeParam) {
            $scope = $this->userModel->getPermissionScope($userId, $permission);
            $resourceOwnerId = $request->getParam($scopeParam) ?? $request->getBody()[$scopeParam] ?? null;
            
            if (!$this->checkScope($userId, $scope, $resourceOwnerId)) {
                return $this->forbidden("Vous n'avez pas accès à cette ressource");
            }
        }
        
        // Ajouter les infos de permission à la requête
        $request->setAttribute('user_permission_scope', $this->userModel->getPermissionScope($userId, $permission));
        
        return $next($request);
    }
    
    /**
     * Vérifier le scope d'accès
     */
    private function checkScope(int $userId, ?string $scope, $resourceOwnerId): bool
    {
        if ($scope === 'all') {
            return true;
        }
        
        if ($scope === 'own') {
            return $resourceOwnerId == $userId;
        }
        
        if ($scope === 'team') {
            // Implémenter la logique d'équipe selon votre structure
            // Par exemple, vérifier si l'utilisateur est dans la même équipe
            return $this->isInSameTeam($userId, $resourceOwnerId);
        }
        
        return false;
    }
    
    /**
     * Vérifier si deux utilisateurs sont dans la même équipe
     * À personnaliser selon votre structure d'équipes
     */
    private function isInSameTeam(int $userId, $otherUserId): bool
    {
        // TODO: Implémenter la logique d'équipe
        // Exemple: vérifier via une table teams ou un champ team_id
        return true;
    }
    
    private function unauthorized(string $message): Response
    {
        $response = new Response();
        
        if ($this->isApiRequest()) {
            return $response->json(['success' => false, 'error' => $message], 401);
        }
        
        header('Location: /xproject/public/login');
        exit;
    }
    
    private function forbidden(string $message): Response
    {
        $response = new Response();
        
        if ($this->isApiRequest()) {
            return $response->json(['success' => false, 'error' => $message], 403);
        }
        
        // Afficher une page 403
        return $response->html($this->render403Page($message), 403);
    }
    
    private function isApiRequest(): bool
    {
        return strpos($_SERVER['REQUEST_URI'], '/api/') !== false
            || (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false);
    }
    
    private function render403Page(string $message): string
    {
        return '<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Accès refusé</title>
    <link rel="stylesheet" href="/xproject/public/assets/css/design-system.css">
</head>
<body style="display: flex; align-items: center; justify-content: center; min-height: 100vh; background: var(--bg-secondary);">
    <div style="text-align: center; padding: 2rem;">
        <div style="font-size: 6rem; margin-bottom: 1rem;">🔒</div>
        <h1 style="margin: 0 0 0.5rem 0;">Accès refusé</h1>
        <p style="color: var(--text-secondary); margin-bottom: 2rem;">' . htmlspecialchars($message) . '</p>
        <a href="/xproject/public/" class="btn btn-primary">Retour à l\'accueil</a>
    </div>
</body>
</html>';
    }
}

/**
 * Fonction helper pour vérifier une permission
 */
function can(string $permission): bool
{
    static $userModel = null;
    if (!$userModel) {
        $userModel = new User();
    }
    
    $userId = $_SESSION['user_id'] ?? null;
    if (!$userId) {
        return false;
    }
    
    return $userModel->hasPermission($userId, $permission);
}

/**
 * Fonction helper pour récupérer le scope d'une permission
 */
function permissionScope(string $permission): ?string
{
    static $userModel = null;
    if (!$userModel) {
        $userModel = new User();
    }
    
    $userId = $_SESSION['user_id'] ?? null;
    if (!$userId) {
        return null;
    }
    
    return $userModel->getPermissionScope($userId, $permission);
}
