<?php
declare(strict_types=1);

/**
 * SCLS Audit List — GET /api/audit/list.php
 *
 * Dashboard-facing API: lists audit entries with filtering, pagination,
 * and summary statistics. NEVER returns encrypted_statement.
 * Auth: dashboard session (AuthChain).
 */

define('DASHBOARD_ROOT', realpath(__DIR__ . '/../..'));
require_once DASHBOARD_ROOT . '/core/bootstrap.php';

// ── Auth gate ─────────────────────────────────────────────────────────────
if (!AuthChain::isAuthenticated()) {
    http_response_code(401);
    header('Content-Type: application/json');
    exit(json_encode(['status' => 'error', 'error' => 'Unauthorized']));
}

RBAC::enforce('view.security');
header('Content-Type: application/json');

// ── Engine DB connection ──────────────────────────────────────────────────
require_once DASHBOARD_ROOT . '/modules/mesh/engine_db_bridge.php';

function getEngineDb(): PDO
{
    static $pdo = null;
    if ($pdo !== null) return $pdo;

    $host   = '172.28.41.2';
    $port   = 3306;
    $dbname = 'engine';
    $user   = 'dashboard';
    $pass   = '';

    if (class_exists('CredentialStore')) {
        try {
            $creds = CredentialStore::get('engine_db');
            if ($creds) {
                $host = $creds['host'] ?? $host;
                $port = (int)($creds['port'] ?? $port);
                $user = $creds['user'] ?? $user;
                $pass = $creds['pass'] ?? $pass;
            }
        } catch (\Throwable $e) {}
    }

    $envFile = '/var/www/private/engine_db.env';
    if ($pass === '' && file_exists($envFile)) {
        $lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        foreach ($lines as $line) {
            if (str_starts_with(trim($line), '#')) continue;
            [$k, $v] = explode('=', $line, 2) + ['', ''];
            $k = trim($k);
            $v = trim($v, " \t\n\r\"'");
            match ($k) {
                'ENGINE_DB_HOST' => $host = $v,
                'ENGINE_DB_PORT' => $port = (int)$v,
                'ENGINE_DB_USER' => $user = $v,
                'ENGINE_DB_PASS' => $pass = $v,
                'ENGINE_DB_NAME' => $dbname = $v,
                default          => null,
            };
        }
    }

    $dsn = "mysql:host={$host};port={$port};dbname={$dbname};charset=utf8mb4";
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
        PDO::ATTR_TIMEOUT            => 10,
    ]);
    return $pdo;
}

try {
    $pdo = getEngineDb();
} catch (\Throwable $e) {
    http_response_code(500);
    exit(json_encode(['status' => 'error', 'error' => 'Engine DB unavailable']));
}

// ── Parse query params ────────────────────────────────────────────────────
$nodeId    = $_GET['node_id']    ?? '';
$toolId    = $_GET['tool_id']    ?? '';
$sessionId = $_GET['session_id'] ?? '';
$status    = $_GET['status']     ?? '';
$severity  = $_GET['severity']   ?? '';
$from      = $_GET['from']       ?? '';
$to        = $_GET['to']         ?? '';
$trustMin  = $_GET['trust_min']  ?? '';
$trustMax  = $_GET['trust_max']  ?? '';
$page      = max(1, (int)($_GET['page'] ?? 1));
$perPage   = max(1, min(500, (int)($_GET['per_page'] ?? 50)));
$sort      = $_GET['sort']       ?? 'started_at';
$order     = strtoupper($_GET['order'] ?? 'DESC');

// ── Whitelist sort columns ────────────────────────────────────────────────
$allowedSorts = ['started_at', 'created_at', 'completed_at', 'duration_ms',
                 'trust_score', 'node_id', 'tool_id', 'severity', 'status'];
if (!in_array($sort, $allowedSorts, true)) {
    $sort = 'started_at';
}
if ($order !== 'ASC' && $order !== 'DESC') {
    $order = 'DESC';
}

// ── Build WHERE clauses ───────────────────────────────────────────────────
$where  = [];
$params = [];

// Validate enums
$validStatuses   = ['pending', 'success', 'failed', 'timeout', 'killed'];
$validSeverities = ['info', 'low', 'medium', 'high', 'critical'];

if ($nodeId !== '' && preg_match('/^\d{6}$/', $nodeId)) {
    $where[]  = 'a.node_id = ?';
    $params[] = $nodeId;
}

if ($toolId !== '' && preg_match('/^[a-f0-9]{4}$/', $toolId)) {
    $where[]  = 'a.tool_id = ?';
    $params[] = $toolId;
}

if ($sessionId !== '' && strlen($sessionId) <= 50) {
    $where[]  = 'a.session_id = ?';
    $params[] = $sessionId;
}

if ($status !== '' && in_array($status, $validStatuses, true)) {
    $where[]  = 'a.status = ?';
    $params[] = $status;
}

if ($severity !== '' && in_array($severity, $validSeverities, true)) {
    $where[]  = 'a.severity = ?';
    $params[] = $severity;
}

if ($from !== '' && preg_match('/^\d{4}-\d{2}-\d{2}/', $from)) {
    $where[]  = 'a.started_at >= ?';
    $params[] = $from;
}

if ($to !== '' && preg_match('/^\d{4}-\d{2}-\d{2}/', $to)) {
    $where[]  = 'a.started_at <= ?';
    $params[] = $to;
}

if ($trustMin !== '' && is_numeric($trustMin)) {
    $where[]  = 'a.trust_score >= ?';
    $params[] = round((float)$trustMin, 2);
}

if ($trustMax !== '' && is_numeric($trustMax)) {
    $where[]  = 'a.trust_score <= ?';
    $params[] = round((float)$trustMax, 2);
}

$whereClause = $where ? 'WHERE ' . implode(' AND ', $where) : '';

// ── Count total ───────────────────────────────────────────────────────────
$countSql = "SELECT COUNT(*) FROM sec_audit_log a {$whereClause}";
$stmt = $pdo->prepare($countSql);
$stmt->execute($params);
$total = (int)$stmt->fetchColumn();

$totalPages = max(1, (int)ceil($total / $perPage));
$page       = min($page, $totalPages);
$offset     = ($page - 1) * $perPage;

// ── Fetch entries (NEVER return encrypted_statement) ──────────────────────
$dataSql = "SELECT
        a.id, a.event_uuid, a.node_id, a.tool_id, a.tool_name, a.tool_category,
        a.encryption_version, a.session_id, a.admin_id, a.trust_score,
        a.exit_code, a.duration_ms, a.cpu_percent, a.memory_mb,
        a.network_zone, a.status, a.severity, a.flags,
        a.started_at, a.completed_at, a.created_at
    FROM sec_audit_log a
    {$whereClause}
    ORDER BY a.{$sort} {$order}
    LIMIT ? OFFSET ?";

$dataParams   = $params;
$dataParams[] = $perPage;
$dataParams[] = $offset;

$stmt = $pdo->prepare($dataSql);
$stmt->execute($dataParams);
$entries = $stmt->fetchAll();

// ── Format source_ip for display (not included in query for safety) ───────
// source_ip is VARBINARY — we deliberately exclude it from the response.

// ── Summary stats ─────────────────────────────────────────────────────────
try {
    // Active nodes (last 24h)
    $s1 = $pdo->query(
        "SELECT COUNT(DISTINCT node_id) FROM sec_audit_log
         WHERE started_at >= NOW() - INTERVAL 24 HOUR"
    );
    $nodesActive = (int)$s1->fetchColumn();

    // Distinct tools (last 24h)
    $s2 = $pdo->query(
        "SELECT COUNT(DISTINCT tool_id) FROM sec_audit_log
         WHERE started_at >= NOW() - INTERVAL 24 HOUR"
    );
    $tools24h = (int)$s2->fetchColumn();

    // Avg duration (last 24h, completed only)
    $s3 = $pdo->query(
        "SELECT COALESCE(AVG(duration_ms), 0) FROM sec_audit_log
         WHERE started_at >= NOW() - INTERVAL 24 HOUR
         AND status = 'success' AND duration_ms IS NOT NULL"
    );
    $avgDuration = round((float)$s3->fetchColumn(), 1);

    // Success rate (last 24h)
    $s4 = $pdo->query(
        "SELECT
            COUNT(*) AS total,
            SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS ok
         FROM sec_audit_log
         WHERE started_at >= NOW() - INTERVAL 24 HOUR"
    );
    $sr = $s4->fetch();
    $successRate = ($sr['total'] > 0)
        ? round(((int)$sr['ok'] / (int)$sr['total']) * 100, 1)
        : 100.0;
} catch (\Throwable $e) {
    $nodesActive = 0;
    $tools24h    = 0;
    $avgDuration = 0;
    $successRate = 0;
}

// ── Response ──────────────────────────────────────────────────────────────
echo json_encode([
    'status' => 'ok',
    'data'   => [
        'entries'    => $entries,
        'pagination' => [
            'page'        => $page,
            'per_page'    => $perPage,
            'total'       => $total,
            'total_pages' => $totalPages,
            'has_next'    => $page < $totalPages,
            'has_prev'    => $page > 1,
        ],
        'summary'    => [
            'nodes_active'    => $nodesActive,
            'tools_24h'       => $tools24h,
            'avg_duration_ms' => $avgDuration,
            'success_rate'    => $successRate,
        ],
    ],
    'ts' => date('c'),
], JSON_PRETTY_PRINT);
