<?php
/**
 * Auth Middleware
 * Gerencia autenticação e autorização
 * Compatível com PHP 7.x
 */

namespace Middleware;

use Core\Response;

class Auth
{
    /** @var array|null */
    private static $currentUser = null;

    /**
     * Obter usuário autenticado (via sessão ou token)
     * @return array|null
     */
    public static function getUser()
    {
        if (self::$currentUser !== null) {
            return self::$currentUser;
        }

        // Verificar sessão primeiro
        if (isset($_SESSION['admin_user'])) {
            $pdo = getDBConnection();
            $stmt = $pdo->prepare("SELECT * FROM admin_users WHERE id = ? AND is_active = 1");
            $stmt->execute([$_SESSION['admin_user']['id']]);
            $user = $stmt->fetch();
            
            if ($user) {
                self::$currentUser = $user;
                return $user;
            }
        }

        // Verificar Bearer token
        $headers = getallheaders();
        $auth = $headers['Authorization'] ?? '';

        if (preg_match('/Bearer\s+(.+)/', $auth, $matches)) {
            $token = $matches[1];
            $pdo = getDBConnection();

            $stmt = $pdo->prepare("
                SELECT u.* FROM admin_users u
                JOIN admin_sessions s ON s.user_id = u.id
                WHERE s.id = ? AND s.expires_at > NOW() AND u.is_active = 1
            ");
            $stmt->execute([$token]);
            $user = $stmt->fetch();

            if ($user) {
                self::$currentUser = $user;
                return $user;
            }
        }

        return null;
    }

    /**
     * Requer autenticação (retorna usuário ou erro 401)
     */
    public static function require(): array
    {
        $user = self::getUser();
        
        if (!$user) {
            Response::unauthorized('Authentication required');
        }
        
        return $user;
    }

    /**
     * Verificar se é super admin
     * Super admin = role super_admin OU (role admin sem site_id)
     */
    public static function isSuperAdmin(?array $user = null): bool
    {
        $user = $user ?? self::getUser();

        if (!$user) {
            return false;
        }

        // Role super_admin sempre e super admin
        if ($user['role'] === 'super_admin') {
            return true;
        }

        // Role admin sem site_id tambem e super admin (compatibilidade)
        if ($user['role'] === 'admin' && empty($user['site_id'])) {
            return true;
        }

        return false;
    }

    /**
     * Requer acesso de super admin
     */
    public static function requireSuperAdmin(): array
    {
        $user = self::require();
        
        if (!self::isSuperAdmin($user)) {
            Response::forbidden('Super admin access required');
        }
        
        return $user;
    }

    /**
     * Verificar se usuário tem acesso a um site específico
     */
    public static function hasAccessToSite(int $siteId, ?array $user = null): bool
    {
        $user = $user ?? self::getUser();
        
        if (!$user) {
            return false;
        }
        
        if (self::isSuperAdmin($user)) {
            return true;
        }
        
        return (int)($user['site_id'] ?? 0) === $siteId;
    }

    /**
     * Requer acesso a um site específico
     */
    public static function requireSiteAccess(int $siteId): array
    {
        $user = self::require();
        
        if (!self::hasAccessToSite($siteId, $user)) {
            Response::forbidden('Acesso negado a este site');
        }
        
        return $user;
    }

    /**
     * Verificar se usuário tem permissão específica
     * OTIMIZADO: Removido SHOW TABLES check desnecessário
     */
    public static function hasPermission(string $permission, ?array $user = null): bool
    {
        $user = $user ?? self::getUser();

        if (!$user) {
            return false;
        }

        // Super admin tem todas as permissoes
        if (self::isSuperAdmin($user)) {
            return true;
        }

        // Verificar permissão na tabela
        $pdo = getDBConnection();
        try {
            $stmt = $pdo->prepare("SELECT 1 FROM site_user_permissions WHERE user_id = ? AND permission = ? LIMIT 1");
            $stmt->execute([$user['id'], $permission]);
            return $stmt->fetchColumn() !== false;
        } catch (\Exception $e) {
            // Em caso de erro (tabela não existe), permitir para admins
            return $user['role'] === 'admin';
        }
    }

    /**
     * Requer permissão específica
     */
    public static function requirePermission(string $permission): array
    {
        $user = self::require();
        
        if (!self::hasPermission($permission, $user)) {
            Response::forbidden("Permissão negada: {$permission}");
        }
        
        return $user;
    }

    /**
     * Obter site_id do usuário (força filtro para usuários de site)
     * @param array|null $user
     * @return int|null
     */
    public static function getUserSiteId($user = null)
    {
        $user = $user ?? self::getUser();
        
        if (!$user || self::isSuperAdmin($user)) {
            return null;
        }
        
        return (int)($user['site_id'] ?? 0) ?: null;
    }

    /**
     * Criar sessão PHP para o usuário
     */
    public static function createSession(array $user): void
    {
        $_SESSION['admin_user'] = [
            'id' => $user['id'],
            'username' => $user['username'],
            'role' => $user['role']
        ];
        self::$currentUser = $user;
    }

    /**
     * Destruir sessão
     */
    public static function destroySession(): void
    {
        session_destroy();
        self::$currentUser = null;
    }

    /**
     * Limpar cache do usuário atual
     */
    public static function clearUserCache(): void
    {
        self::$currentUser = null;
    }
}
