<?php
// /docker/whp/web/libs/account_disable.php
// Account-level disable/enable. Cascades to per-site disable/enable via
// site_disable.php. Current suspension state is tracked in whp.accounts_disabled
// (row present iff currently suspended). History in whp.account_disable_audit.

require_once(__DIR__ . '/mysqlmgmt.php');
require_once(__DIR__ . '/site_disable.php'); // disable_site, enable_site, SITE_DISABLE_REASONS

const ACCOUNT_DISABLE_REASONS = SITE_DISABLE_REASONS;

function _adisable_db(): PDO {
    $pdo = (new mysqlmgmt())->getMySQLConnection();
    if (!$pdo) {
        throw new RuntimeException('account_disable: database connection failed');
    }
    return $pdo;
}

function account_is_disabled(string $username): ?array {
    $db = _adisable_db();
    $stmt = $db->prepare("SELECT * FROM whp.accounts_disabled WHERE username = :u LIMIT 1");
    $stmt->execute(['u' => $username]);
    $r = $stmt->fetch(PDO::FETCH_ASSOC);
    return $r ?: null;
}

function list_disabled_accounts(): array {
    $db = _adisable_db();
    return $db->query("SELECT * FROM whp.accounts_disabled ORDER BY disabled_at DESC")
              ->fetchAll(PDO::FETCH_ASSOC);
}

function _site_ids_for_username(string $username): array {
    $db = _adisable_db();
    $stmt = $db->prepare("SELECT id FROM whp.sites WHERE username = :u");
    $stmt->execute(['u' => $username]);
    return array_map('intval', array_column($stmt->fetchAll(PDO::FETCH_ASSOC), 'id'));
}

function disable_account(string $username, string $reason, string $actor, ?string $note = null): array {
    if (!in_array($reason, ACCOUNT_DISABLE_REASONS, true)) {
        return ['ok' => false, 'error' => 'invalid_reason'];
    }
    if ($username === '') return ['ok' => false, 'error' => 'empty_username'];

    $db = _adisable_db();

    // Upsert into accounts_disabled
    $stmt = $db->prepare("
        INSERT INTO whp.accounts_disabled (username, reason, disabled_by, note)
        VALUES (:u, :r, :a, :n)
        ON DUPLICATE KEY UPDATE reason=VALUES(reason), disabled_by=VALUES(disabled_by), note=VALUES(note)
    ");
    $stmt->execute(['u' => $username, 'r' => $reason, 'a' => $actor, 'n' => $note]);

    // Audit row
    $stmt = $db->prepare("
        INSERT INTO whp.account_disable_audit (username, action, reason, actor, note)
        VALUES (:u, 'disable', :r, :a, :n)
    ");
    $stmt->execute(['u' => $username, 'r' => $reason, 'a' => $actor, 'n' => $note]);

    // Cascade to each site
    $sites = _site_ids_for_username($username);
    $per_site = [];
    foreach ($sites as $sid) {
        $per_site[$sid] = disable_site($sid, $reason, $actor, $note);
    }

    return ['ok' => true, 'sites' => $per_site, 'site_count' => count($sites)];
}

function enable_account(string $username, string $actor): array {
    if ($username === '') return ['ok' => false, 'error' => 'empty_username'];

    $db = _adisable_db();

    // Idempotent: ok if not present
    $stmt = $db->prepare("DELETE FROM whp.accounts_disabled WHERE username = :u");
    $stmt->execute(['u' => $username]);

    $stmt = $db->prepare("
        INSERT INTO whp.account_disable_audit (username, action, actor)
        VALUES (:u, 'enable', :a)
    ");
    $stmt->execute(['u' => $username, 'a' => $actor]);

    $sites = _site_ids_for_username($username);
    $per_site = [];
    foreach ($sites as $sid) {
        $per_site[$sid] = enable_site($sid, $actor);
    }

    return ['ok' => true, 'sites' => $per_site, 'site_count' => count($sites)];
}

// Returns matching accounts (with site counts) for the search UI.
// Matches against username (LIKE) and against any of the user's domains via site_domains.fqdn.
function search_accounts(string $query, int $limit = 50): array {
    $db = _adisable_db();
    $like = '%' . str_replace(['%', '_'], ['\%', '\_'], $query) . '%';
    $sql = "
        SELECT s.username,
               GROUP_CONCAT(DISTINCT sd.fqdn ORDER BY sd.fqdn SEPARATOR ', ') AS domains,
               COUNT(DISTINCT s.id) AS site_count,
               ad.reason AS disabled_reason,
               ad.disabled_at,
               ad.disabled_by
          FROM whp.sites s
          LEFT JOIN whp.site_domains sd ON sd.site_id = s.id
          LEFT JOIN whp.accounts_disabled ad ON ad.username = s.username
         WHERE s.username LIKE :q1
            OR sd.fqdn LIKE :q2
         GROUP BY s.username
         ORDER BY s.username
         LIMIT " . (int)$limit;
    $stmt = $db->prepare($sql);
    $stmt->execute(['q1' => $like, 'q2' => $like]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
