<?php
function gp_auth_user_full(PDO $pdo): ?array
{
    $sessionUser = auth_user();
    if (!$sessionUser || empty($sessionUser['id'])) return null;

    $stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id LIMIT 1");
    $stmt->execute([':id' => (int)$sessionUser['id']]);
    $u = $stmt->fetch();
    if (!$u || (int)($u['is_active'] ?? 0) !== 1) return null;
    return $u;
}

function gp_user_role(PDO $pdo): string
{
    $u = gp_auth_user_full($pdo);
    return $u ? strtolower(trim((string)($u['role'] ?? ''))) : '';
}

function gp_current_user_id(): int
{
    $sessionUser = auth_user();
    return (int)($sessionUser['id'] ?? 0);
}

function gp_is_full_project_access_role(string $role): bool
{
    return in_array($role, ['admin', 'administrator', 'super_admin', 'owner', 'manager'], true);
}

function gp_is_secretary_like_role(string $role): bool
{
    return in_array($role, ['secretary', 'secretariat', 'office'], true);
}

function gp_is_admin_like(): bool
{
    $user = auth_user();
    if (!$user) return false;
    return gp_is_full_project_access_role(strtolower(trim((string)($user['role'] ?? ''))));
}

/**
 * Check a single perm_* permission for the current user.
 * Admin & manager always return true regardless of DB value.
 *
 * @param PDO    $pdo
 * @param string $key  e.g. 'perm_costings', 'perm_assign', 'perm_expenses'
 * @return bool
 */
function gp_user_perm(PDO $pdo, string $key): bool
{
    $u = gp_auth_user_full($pdo);
    if (!$u) return false;

    $role = strtolower(trim((string)($u['role'] ?? '')));

    // Admins & managers always have everything
    if (gp_is_full_project_access_role($role)) return true;

    return (int)($u[$key] ?? 0) === 1;
}

/**
 * Require a specific permission or abort with 403.
 */
function gp_require_perm(PDO $pdo, string $key): void
{
    if (!gp_user_perm($pdo, $key)) {
        http_response_code(403);
        exit('Access denied. You do not have the required permission: ' . htmlspecialchars($key));
    }
}

function gp_can_create_project(PDO $pdo): bool
{
    $role = gp_user_role($pdo);
    return gp_is_full_project_access_role($role) || gp_is_secretary_like_role($role);
}

function gp_can_manage_project_access(PDO $pdo): bool
{
    return gp_is_full_project_access_role(gp_user_role($pdo));
}

function gp_can_edit_project(PDO $pdo, int $projectId): bool
{
    $u = gp_auth_user_full($pdo);
    if (!$u || $projectId <= 0) return false;

    $role = strtolower(trim((string)($u['role'] ?? '')));

    if (gp_is_full_project_access_role($role)) {
        return true;
    }

    if (gp_is_secretary_like_role($role)) {
        $stmt = $pdo->prepare("SELECT can_edit FROM project_edit_permissions WHERE user_id = :uid AND project_id = :pid LIMIT 1");
        $stmt->execute([
            ':uid' => (int)$u['id'],
            ':pid' => $projectId,
        ]);
        return (int)($stmt->fetchColumn() ?: 0) === 1;
    }

    return false;
}

function gp_require_project_edit(PDO $pdo, int $projectId): void
{
    if (!gp_can_edit_project($pdo, $projectId)) {
        http_response_code(403);
        exit('Project edit access denied.');
    }
}

function gp_require_project_create(PDO $pdo): void
{
    if (!gp_can_create_project($pdo)) {
        http_response_code(403);
        exit('Project create access denied.');
    }
}
