<?php
// auth_stub.php – user, role va permission helperlari
declare(strict_types=1);

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// Bu fayl ko‘p joyda `db.php` bilan birga chaqiriladi,
// lekin ayrim sahifalar faqat auth_stub.php ni chaqiradi.
// Shuning uchun bu yerda ham db.php ni ulab qo'yamiz.
require_once __DIR__ . '/db.php'; // $pdo global

/**
 * Bu so'rov API'mi yoki oddiy sahifami – aniqlash
 */
function is_api_request(): bool
{
    $uri = $_SERVER['REQUEST_URI'] ?? '';
    return (strpos($uri, '/api/') !== false);
}

/**
 * Foydalanuvchi login bo‘lganmi?
 */
function is_logged_in(): bool
{
    return !empty($_SESSION['user_id']);
}

/**
 * Login talab qiluvchi helper:
 *  - Agar login bo‘lmagan bo‘lsa:
 *    * API uchun: 401 JSON
 *    * Oddiy sahifa uchun: /mark2/login.php ga redirect
 */
function require_login(): void
{
    if (is_logged_in()) {
        return;
    }

    if (is_api_request()) {
        http_response_code(401);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode([
            'status'  => 'error',
            'message' => 'Avtorizatsiya talab qilinadi',
        ], JSON_UNESCAPED_UNICODE);
        exit;
    }

    // Oddiy HTML sahifa – login sahifaga yuboramiz
    $current = $_SERVER['REQUEST_URI'] ?? '';
    $loginUrl = '/mark2/login.php';

    if ($current && stripos($current, 'login.php') === false) {
        $loginUrl .= '?redirect=' . urlencode($current);
    }

    header('Location: ' . $loginUrl);
    exit;
}

/**
 * Login paytida foydalanuvchini sessiyaga yozish
 * (login.php ichida ishlatish uchun)
 */
function set_logged_in_user(int $userId): void
{
    $_SESSION['user_id'] = $userId;
    // cachelarni tozalaymiz
    unset($_SESSION['user_name'], $_SESSION['role_id'], $_SESSION['role_name'], $_SESSION['user_permissions']);
}

/**
 * Joriy foydalanuvchi ID
 */
function current_user_id(): int
{
    if (empty($_SESSION['user_id'])) {
        return 0; // ENDIIII YANGI USERGA ADMIN QILMAYDI
    }
    return (int)$_SESSION['user_id'];
}

/**
 * Joriy foydalanuvchi ismi
 */
function current_user_name(): string
{
    if (!is_logged_in()) {
        return 'Guest';
    }

    if (!empty($_SESSION['user_name'])) {
        return (string)$_SESSION['user_name'];
    }

    global $pdo;
    $uid = current_user_id();
    if ($uid <= 0) {
        return 'Guest';
    }

    try {
        $stmt = $pdo->prepare("SELECT name FROM users WHERE id = :id");
        $stmt->execute([':id' => $uid]);
        $name = $stmt->fetchColumn();
        if ($name) {
            $_SESSION['user_name'] = $name;
            return (string)$name;
        }
    } catch (Throwable $e) {
        // jim
    }

    return 'Unknown';
}

/**
 * Joriy foydalanuvchi rol ID (users.role_id)
 */
function current_user_role_id(): ?int
{
    if (!is_logged_in()) {
        return null;
    }

    if (isset($_SESSION['role_id'])) {
        return $_SESSION['role_id'] !== null ? (int)$_SESSION['role_id'] : null;
    }

    global $pdo;
    $uid = current_user_id();
    if ($uid <= 0) {
        $_SESSION['role_id'] = null;
        return null;
    }

    try {
        $stmt = $pdo->prepare("SELECT role_id FROM users WHERE id = :id");
        $stmt->execute([':id' => $uid]);
        $rid = $stmt->fetchColumn();
        if ($rid !== false && $rid !== null) {
            $_SESSION['role_id'] = (int)$rid;
            return (int)$rid;
        }
    } catch (Throwable $e) {
        // jim
    }

    $_SESSION['role_id'] = null;
    return null;
}

/**
 * Joriy foydalanuvchi rol nomi (roles.name)
 * Masalan: 'Admin', 'markirovkachi', 'sotuvchi', 'viewer'
 */
function current_user_role_name(): ?string
{
    if (!is_logged_in()) {
        return null;
    }

    if (isset($_SESSION['role_name'])) {
        return $_SESSION['role_name'] !== null ? (string)$_SESSION['role_name'] : null;
    }

    global $pdo;
    $rid = current_user_role_id();
    if (!$rid) {
        $_SESSION['role_name'] = null;
        return null;
    }

    try {
        $stmt = $pdo->prepare("SELECT name FROM roles WHERE id = :id AND is_active = 1");
        $stmt->execute([':id' => $rid]);
        $name = $stmt->fetchColumn();
        if ($name !== false && $name !== null) {
            $_SESSION['role_name'] = (string)$name;
            return (string)$name;
        }
    } catch (Throwable $e) {
        // jim
    }

    $_SESSION['role_name'] = null;
    return null;
}

/**
 * Joriy foydalanuvchi permissions ro‘yxati
 * Massiv: ['users.view' => true, 'users.edit' => true, ...]
 */
function current_user_permissions(): array
{
    if (!is_logged_in()) {
        return [];
    }

    if (isset($_SESSION['user_permissions']) && is_array($_SESSION['user_permissions'])) {
        return $_SESSION['user_permissions'];
    }

    global $pdo;

    $uid      = current_user_id();
    $roleName = strtolower(trim((string)(current_user_role_name() ?? '')));

    $perms = [];

    try {
        // Agar admin bo‘lsa – barcha permissions
        if ($roleName === 'admin') {
            $stmt = $pdo->query("SELECT code FROM permissions");
            $rows = $stmt->fetchAll(PDO::FETCH_COLUMN);
        } else {
            $stmt = $pdo->prepare("
                SELECT p.code
                FROM users u
                JOIN roles r              ON r.id = u.role_id
           LEFT JOIN role_permissions rp   ON rp.role_id = r.id
           LEFT JOIN permissions p         ON p.id = rp.permission_id
                WHERE u.id = :id
            ");
            $stmt->execute([':id' => $uid]);
            $rows = $stmt->fetchAll(PDO::FETCH_COLUMN);
        }

        if ($rows) {
            foreach ($rows as $code) {
                if ($code !== null && $code !== '') {
                    $perms[$code] = true;
                }
            }
        }
    } catch (Throwable $e) {
        $perms = [];
    }

    $_SESSION['user_permissions'] = $perms;
    return $perms;
}

/**
 * Berilgan code bo‘yicha foydalanuvchida ruxsat bormi?
 */
function user_has_permission(string $code): bool
{
    $code = trim($code);
    if ($code === '') {
        return false;
    }

    $roleName = strtolower(trim((string)(current_user_role_name() ?? '')));

    // Admin hamma narsaga ruxsat
    if ($roleName === 'admin') {
        return true;
    }

    $perms = current_user_permissions();

    // To‘g‘ridan-to‘g‘ri moslik
    if (isset($perms[$code])) {
        return true;
    }

    // Prefix + .* support: masalan 'users.edit' -> 'users.*'
    if (strpos($code, '.') !== false) {
        [$prefix] = explode('.', $code, 2);
        $wild = $prefix . '.*';
        if (isset($perms[$wild])) {
            return true;
        }
    }

    return false;
}

/**
 * Qisqa alias:
 * if (can('users.delete')) { ... }
 */
function can(string $code): bool
{
    return user_has_permission($code);
}

/**
 * Sahifaga kirishni tekshirish:
 *  - avval require_login()
 *  - keyin permission check
 */
function require_permission(string $code): void
{
    require_login(); // BIRINCHI LOGINNI TEKSHIRAMIZ

    if (user_has_permission($code)) {
        return;
    }

    http_response_code(403);

    if (is_api_request()) {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode([
            'status'  => 'error',
            'message' => 'Ruxsat yo‘q: ' . $code,
        ], JSON_UNESCAPED_UNICODE);
    } else {
        echo "<!DOCTYPE html>
<html lang=\"uz\">
<head>
  <meta charset=\"UTF-8\">
  <title>403 – Ruxsat yo‘q</title>
</head>
<body>
  <h2>403 – Ruxsat yo‘q</h2>
  <p>Bu sahifani ko‘rish uchun sizda kerakli ruxsat mavjud emas: <strong>" . htmlspecialchars($code, ENT_QUOTES, 'UTF-8') . "</strong>.</p>
</body>
</html>";
    }

    exit;
}
