<?php
// ============================================================
// Permissions
// ------------------------------------------------------------
// Two layers, both fully controlled by superadmin/admin from the UI:
//
//  1. Role defaults (role_permissions table, edited on role_permissions.php)
//     - e.g. "does the manager role get Main Store visibility by default?"
//  2. Per-user overrides (user_permissions table, edited on permissions.php)
//     - Allow/Deny for one specific person, always wins over the role default.
//
// superadmin always has everything and is unaffected by either layer.
// Only the CODE + LABEL + CATEGORY of each permission is hardcoded here;
// who gets what is entirely data-driven and admin-editable.
// ============================================================

function all_permissions() {
    return [
        'main_store.view'            => ['label' => 'View Main Store Stock',            'category' => 'Main Store'],
        'main_store.adjust'          => ['label' => 'Manually Adjust Main Store Stock',  'category' => 'Main Store'],
        'store_requisitions.issue'   => ['label' => 'Issue Stock to Outlets',            'category' => 'Store Requisitions'],
        'items.manage'               => ['label' => 'Manage Item Catalogue',             'category' => 'Master Data'],
        'suppliers.manage'           => ['label' => 'Manage Suppliers',                  'category' => 'Master Data'],
        'outlets.manage'             => ['label' => 'Manage Outlets',                    'category' => 'Master Data'],
        'categories.manage'          => ['label' => 'Manage Categories & Units',         'category' => 'Master Data'],
        'purchase_orders.manage'     => ['label' => 'Create & Receive Purchase Orders',  'category' => 'Purchasing'],
        'return_to_supplier.manage'  => ['label' => 'Return Goods to Supplier',          'category' => 'Purchasing'],
        'goods_received.view'        => ['label' => 'View Goods Received Log',          'category' => 'Purchasing'],
        'reports.view'               => ['label' => 'View Reports',                     'category' => 'Reports'],
        'requisitions.view_all'      => ['label' => 'View Requisitions From All Departments (not just your own)', 'category' => 'Requisitions'],
        'waste.manage'                => ['label' => 'Record Waste / Spoilage',            'category' => 'Waste & Spoilage'],
        'accounting.coa_manage'      => ['label' => 'Manage Chart of Accounts',           'category' => 'Accounting'],
        'accounting.journal_post'    => ['label' => 'Create & Post Journal Entries',      'category' => 'Accounting'],
        'accounting.reports_view'    => ['label' => 'View GL / Trial Balance / P&L / Balance Sheet', 'category' => 'Accounting'],
        'accounting.ap_manage'       => ['label' => 'Manage Accounts Payable (bills & payments)', 'category' => 'Accounting'],
        'accounting.ar_manage'       => ['label' => 'Manage Accounts Receivable (invoices & receipts)', 'category' => 'Accounting'],
    ];
}

function assignable_roles() {
    return ['admin','hr','audit','gm','accounts','manager','staff','supervisor','opm'];
}

// Does a given ROLE have this permission by default? (superadmin/admin manage
// this list on role_permissions.php - nothing is hardcoded except superadmin.)
function role_has_permission(PDO $pdo, $role, $code) {
    if ($role === 'superadmin') return true;
    $stmt = $pdo->prepare("SELECT 1 FROM role_permissions WHERE role = ? AND permission_code = ?");
    $stmt->execute([$role, $code]);
    return (bool)$stmt->fetchColumn();
}

function get_role_permission_codes(PDO $pdo, $role) {
    $stmt = $pdo->prepare("SELECT permission_code FROM role_permissions WHERE role = ?");
    $stmt->execute([$role]);
    return $stmt->fetchAll(PDO::FETCH_COLUMN);
}

// Does this USER have the given permission? superadmin always does.
// Otherwise: an explicit per-user override (grant or deny) always wins;
// with no override, it falls back to whether their role has it by default.
function has_permission(PDO $pdo, $user, $code) {
    if (!$user) return false;
    if ($user['role'] === 'superadmin') return true;

    $stmt = $pdo->prepare("SELECT state FROM user_permissions WHERE user_id = ? AND permission_code = ?");
    $stmt->execute([$user['id'], $code]);
    $state = $stmt->fetchColumn();

    if ($state === 'grant') return true;
    if ($state === 'deny') return false;
    return role_has_permission($pdo, $user['role'], $code);
}

// Page guard - like require_role() but permission-based
function require_permission($code) {
    require_login();
    global $pdo;
    $user = current_user();
    if ($user['role'] === 'superadmin') return;
    if (!has_permission($pdo, $user, $code)) {
        http_response_code(403);
        die('<div style="font-family:sans-serif;padding:40px">
              <h2>403 - Access Denied</h2>
              <p>You do not have permission to access this page. Ask an administrator to grant you access from
                 <strong>Administration &rarr; Permissions</strong> if you believe you need it.</p>
              <a href="' . BASE_URL . 'dashboard.php">Back to dashboard</a>
             </div>');
    }
}

// Returns 'grant', 'deny', or null (no override, follows role default) for a
// given user + permission - used by the per-user Permissions admin screen.
function get_permission_override(PDO $pdo, $userId, $code) {
    $stmt = $pdo->prepare("SELECT state FROM user_permissions WHERE user_id = ? AND permission_code = ?");
    $stmt->execute([$userId, $code]);
    $state = $stmt->fetchColumn();
    return $state ?: null;
}

function get_user_permission_overrides(PDO $pdo, $userId) {
    $stmt = $pdo->prepare("SELECT permission_code, state FROM user_permissions WHERE user_id = ?");
    $stmt->execute([$userId]);
    $out = [];
    foreach ($stmt->fetchAll() as $row) { $out[$row['permission_code']] = $row['state']; }
    return $out;
}

// Department-scoped visibility for requisitions: a user can see a requisition if
// they hold 'requisitions.view_all', they created it themselves, or it belongs to
// their own department (department_id passed in, may be null for e.g. a general
// main-store PR with no outlet/department attached).
function can_view_requisition(PDO $pdo, $user, $recordDeptId, $requestedBy) {
    if (has_permission($pdo, $user, 'requisitions.view_all')) return true;
    if ((int)$requestedBy === (int)$user['id']) return true;
    if ($recordDeptId !== null && $user['department_id'] !== null && (int)$recordDeptId === (int)$user['department_id']) return true;
    return false;
}
