<?php
/*
|--------------------------------------------------------------------------
| config/module_access.php
| Per-staff, per-module access for company modules.
| access_level (per company_id + user_id + module_key):
|   - none    : no row  -> module hidden / no access
|   - view    : open & read only
|   - edit    : can add/edit/delete own items (for jobs: edit/close/upload own,
|               but NO admin functions)
|   - manage  : full admin (for jobs: admin dashboard, all jobs)
| Company admins always have 'manage'.
| (Legacy can_edit column kept in sync: 1 for edit/manage, 0 for view.)
|--------------------------------------------------------------------------
*/

function ma_ensure_table(PDO $pdo): void
{
    static $done = false;
    if ($done) return;
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS company_module_staff (
            id         INT AUTO_INCREMENT PRIMARY KEY,
            company_id INT NOT NULL,
            user_id    INT NOT NULL,
            module_key VARCHAR(50) NOT NULL,
            can_edit   TINYINT(1) NOT NULL DEFAULT 0,
            access_level VARCHAR(20) NOT NULL DEFAULT 'view',
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            UNIQUE KEY uniq_cms (company_id, user_id, module_key)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    ");
    // add access_level on older installs + backfill from can_edit
    if (!$pdo->query("SHOW COLUMNS FROM company_module_staff LIKE 'access_level'")->fetch()) {
        $pdo->exec("ALTER TABLE company_module_staff ADD COLUMN access_level VARCHAR(20) NOT NULL DEFAULT 'view'");
        $pdo->exec("UPDATE company_module_staff SET access_level = IF(can_edit=1,'manage','view')");
    }
    $done = true;
}

/* Raw level: 'none' | 'view' | 'edit' | 'manage'. Admins are always 'manage'. */
function mod_access_level(PDO $pdo, int $companyId, int $userId, ?string $role, string $moduleKey): string
{
    if (($role ?? '') === 'company_admin') return 'manage';
    try {
        ma_ensure_table($pdo);
        $st = $pdo->prepare("SELECT access_level, can_edit FROM company_module_staff
                             WHERE company_id=? AND user_id=? AND module_key=? LIMIT 1");
        $st->execute([$companyId, $userId, $moduleKey]);
        $r = $st->fetch(PDO::FETCH_ASSOC);
        if (!$r) return 'none';
        $lvl = $r['access_level'] ?? '';
        if (in_array($lvl, ['view','edit','manage'], true)) return $lvl;
        return ((int)$r['can_edit'] === 1) ? 'manage' : 'view';
    } catch (Throwable $e) {
        return 'none';
    }
}

/* Can OPEN the module (view or higher). */
function mod_can_view(PDO $pdo, int $companyId, int $userId, ?string $role, string $moduleKey): bool
{
    return mod_access_level($pdo, $companyId, $userId, $role, $moduleKey) !== 'none';
}

/* Can make changes (edit own or manage). For jobs: edit/close/upload. */
function mod_can_edit(PDO $pdo, int $companyId, int $userId, ?string $role, string $moduleKey): bool
{
    return in_array(mod_access_level($pdo, $companyId, $userId, $role, $moduleKey), ['edit','manage'], true);
}

/* Full admin of the module (manage). For jobs: admin dashboard & all jobs. */
function mod_can_admin(PDO $pdo, int $companyId, int $userId, ?string $role, string $moduleKey): bool
{
    return mod_access_level($pdo, $companyId, $userId, $role, $moduleKey) === 'manage';
}

/* Map of user_id => level for a module (only assigned staff appear). */
function mod_access_map(PDO $pdo, int $companyId, string $moduleKey): array
{
    try {
        ma_ensure_table($pdo);
        $st = $pdo->prepare("SELECT user_id, access_level, can_edit FROM company_module_staff
                             WHERE company_id=? AND module_key=?");
        $st->execute([$companyId, $moduleKey]);
        $out = [];
        foreach ($st->fetchAll(PDO::FETCH_ASSOC) as $r) {
            $lvl = $r['access_level'] ?? '';
            if (!in_array($lvl, ['view','edit','manage'], true)) { $lvl = ((int)$r['can_edit'] === 1) ? 'manage' : 'view'; }
            $out[(int)$r['user_id']] = $lvl;
        }
        return $out;
    } catch (Throwable $e) {
        return [];
    }
}

/* Set access level for a user+module. $level = 'none' | 'view' | 'edit' | 'manage'. */
function mod_set_access(PDO $pdo, int $companyId, int $userId, string $moduleKey, string $level): void
{
    ma_ensure_table($pdo);
    if (!in_array($level, ['view','edit','manage'], true)) {
        $pdo->prepare("DELETE FROM company_module_staff WHERE company_id=? AND user_id=? AND module_key=?")
            ->execute([$companyId, $userId, $moduleKey]);
        return;
    }
    $canEdit = in_array($level, ['edit','manage'], true) ? 1 : 0;
    $pdo->prepare("
        INSERT INTO company_module_staff (company_id, user_id, module_key, can_edit, access_level)
        VALUES (?, ?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE can_edit = VALUES(can_edit), access_level = VALUES(access_level)
    ")->execute([$companyId, $userId, $moduleKey, $canEdit, $level]);
}