<?php
// auth.php

require_once 'vendor/autoload.php';
use \Firebase\JWT\JWT;
use \Firebase\JWT\Key;

class Auth {
    private static $secret_key = 'your_secret_key_here';
    private static $token_duration = 3600;

    public static function generateToken($user_data) {
        $issuedAt = time();
        $expire = $issuedAt + self::$token_duration;

        $payload = array(
            "iat" => $issuedAt,
            "exp" => $expire,
            "user" => array(
                "id" => $user_data['idUser'],
                "username" => $user_data['username'],
                "role" => $user_data['role'],
                "profile" => $user_data['profile']
            )
        );

        return JWT::encode($payload, self::$secret_key, 'HS256');
    }

    public static function validateToken() {
        $headers = getallheaders();
        if (!isset($headers['Authorization'])) {
            throw new Exception('No token provided');
        }

        $token = str_replace('Bearer ', '', $headers['Authorization']);

        try {
            $decoded = JWT::decode($token, new Key(self::$secret_key, 'HS256'));
            return $decoded;
        } catch (Exception $e) {
            throw new Exception('Invalid token: ' . $e->getMessage());
        }
    }

    public static function verifyRole($allowed_roles) {
        try {
            $decoded = self::validateToken();
            if (!in_array($decoded->user->role, $allowed_roles)) {
                throw new Exception('Insufficient permissions');
            }
            return true;
        } catch (Exception $e) {
            throw new Exception('Authorization failed: ' . $e->getMessage());
        }
    }

    public static function checkPagePermission($page, $operation) {
        try {
            $decoded = self::validateToken();

            if ($decoded->user->role === 'admin') {
                return true;
            }

            include_once 'bd/myData.php';

            // Modified query to retrieve permissions based on user profile
            $query = "
                SELECT pr.* FROM profile pr
                JOIN users u ON u.profile = pr.profile
                WHERE u.idUser = :idUser AND (pr.page = :page OR pr.page = :page_plural)
            ";
            $params = array(
                ':idUser' => $decoded->user->id,
                ':page' => $page,
                ':page_plural' => $page . 's'
            );

            $result = metodGet($query, $params);
            $permission = $result->fetch(PDO::FETCH_ASSOC);

            if (!$permission) {
                throw new Exception('No permissions found for this page');
            }

            switch ($operation) {
                case 'view':
                    return $permission['visibility'] == 1;
                case 'add':
                    return $permission['op_add'] == 1;
                case 'edit':
                    return $permission['op_edit'] == 1;
                case 'delete':
                    return $permission['op_delete'] == 1;
                default:
                    return false;
            }
        } catch (Exception $e) {
            error_log('Permission check failed: ' . $e->getMessage());
            throw new Exception('Permission check failed: ' . $e->getMessage());
        }
    }
}

function requireAuth($allowed_roles = null) {
    try {
        if ($allowed_roles) {
            Auth::verifyRole($allowed_roles);
        } else {
            Auth::validateToken();
        }
    } catch (Exception $e) {
        header('HTTP/1.1 401 Unauthorized');
        echo json_encode(['error' => $e->getMessage()]);
        exit();
    }
}

function requirePermission($page, $operation) {
    try {
        if (!Auth::checkPagePermission($page, $operation)) {
            throw new Exception('Insufficient permissions for this operation');
        }
    } catch (Exception $e) {
        header('HTTP/1.1 403 Forbidden');
        echo json_encode(['error' => $e->getMessage()]);
        exit();
    }
}
?>