<?php
/**
 * SUDANNA AI OS — RUNTIME PROOF SCRIPT
 * Run: https://sudanna.ai/runtime_proof.php?token=proof2026
 * DELETE IMMEDIATELY AFTER
 */
if (($_GET['token'] ?? '') !== 'proof2026') { http_response_code(403); die('forbidden'); }

require_once __DIR__ . '/config.php';
require_once __DIR__ . '/engine/Gateway.php';
require_once __DIR__ . '/engine/InvoiceEngine.php';
require_once __DIR__ . '/engine/FinancialAgent.php';
require_once __DIR__ . '/engine/EventBus.php';
require_once __DIR__ . '/engine/QueueEngine.php';

header('Content-Type: application/json; charset=utf-8');
$proof = ['timestamp' => date('Y-m-d H:i:s'), 'steps' => []];

$log = function(string $step, bool $ok, $data = null) use (&$proof) {
    $proof['steps'][$step] = ['ok' => $ok, 'data' => $data, 'time' => date('H:i:s')];
};

// ══ STEP 1: DB Tables Exist ════════════════════════════════════════
try {
    $tables = db()->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
    $required = ['users','invoices','payment_proofs','ledger','accounts',
                 'tasks','flow_sessions','notifications','wallet','wallet_transactions'];
    $missing = array_diff($required, $tables);
    $log('1_db_tables', empty($missing), [
        'total_tables'   => count($tables),
        'required_found' => count($required) - count($missing),
        'missing'        => array_values($missing),
    ]);
} catch (Throwable $e) { $log('1_db_tables', false, ['error' => $e->getMessage()]); }

// ══ STEP 2: Create Invoice ══════════════════════════════════════════
$invoiceId = null; $refCode = null;
try {
    require_once __DIR__ . '/engine/InvoiceEngine.php';
    $r = InvoiceEngine::create(1, 'legal', 500.00, ['test' => 'runtime_proof']);
    $invoiceId = $r['invoice_id'] ?? null;
    $refCode   = $r['reference_code'] ?? null;
    $log('2_invoice_create', $r['success'] ?? false, $r);

    // Fetch from DB
    if ($invoiceId) {
        $row = db()->prepare("SELECT * FROM invoices WHERE id=?")->execute([$invoiceId])
            ? (function($id){ $s=db()->prepare("SELECT * FROM invoices WHERE id=? LIMIT 1"); $s->execute([$id]); return $s->fetch(PDO::FETCH_ASSOC); })($invoiceId)
            : null;
        $log('2a_invoice_db', (bool)$row, $row);
    }
} catch (Throwable $e) { $log('2_invoice_create', false, ['error' => $e->getMessage()]); }

// ══ STEP 3: Upload Payment Proof ═══════════════════════════════════
try {
    if ($invoiceId) {
        $fakePath = 'uploads/proofs/test_' . time() . '.jpg';
        $fakeHash = hash('sha256', 'test_image_' . $invoiceId . time());
        $r2 = InvoiceEngine::uploadProof($invoiceId, $fakePath, $fakeHash);
        $log('3_upload_proof', $r2['success'] ?? false, $r2);

        // DB check
        $proof_row = db()->query(
            "SELECT * FROM payment_proofs WHERE invoice_id=$invoiceId"
        )->fetch(PDO::FETCH_ASSOC);
        $log('3a_proof_db', (bool)$proof_row, $proof_row);
    }
} catch (Throwable $e) { $log('3_upload_proof', false, ['error' => $e->getMessage()]); }

// ══ STEP 4: Idempotency — Duplicate Proof Attempt ══════════════════
try {
    if ($invoiceId) {
        $sameHash = hash('sha256', 'test_image_' . $invoiceId . time()); // new hash
        // Same invoiceId → must fail (UNIQUE constraint)
        $r3 = InvoiceEngine::uploadProof($invoiceId, 'uploads/proofs/dup_' . time() . '.jpg', $sameHash);
        $log('4_idempotency_proof', !($r3['success'] ?? true), [
            'attempted_second_upload' => true,
            'was_rejected'            => !($r3['success'] ?? true),
            'error_returned'          => $r3['error'] ?? null,
        ]);
    }
} catch (Throwable $e) { $log('4_idempotency_proof', true, ['rejected_with' => $e->getMessage()]); }

// ══ STEP 5: Approve — FinancialAgent::confirmPayment ═══════════════
$ledgerBefore = 0;
try {
    $ledgerBefore = (int)db()->query("SELECT COUNT(*) FROM ledger")->fetchColumn();
    if ($invoiceId) {
        // Must set proof to uploaded first
        db()->query("UPDATE invoices SET status='proof_uploaded' WHERE id=$invoiceId");
        $r4 = FinancialAgent::confirmPayment($invoiceId, 1);
        $log('5_payment_approval', $r4['success'] ?? false, $r4);
    }
} catch (Throwable $e) { $log('5_payment_approval', false, ['error' => $e->getMessage()]); }

// ══ STEP 6: Ledger Entries Created ═════════════════════════════════
try {
    $ledgerAfter = (int)db()->query("SELECT COUNT(*) FROM ledger")->fetchColumn();
    $newEntries = db()->query(
        "SELECT l.*, a.code, a.name FROM ledger l JOIN accounts a ON a.id=l.account_id
         WHERE l.reference_type='invoice' AND l.reference_id=$invoiceId ORDER BY l.id"
    )->fetchAll(PDO::FETCH_ASSOC);

    $totalDebit  = array_sum(array_column($newEntries, 'debit'));
    $totalCredit = array_sum(array_column($newEntries, 'credit'));
    $log('6_ledger_entries', count($newEntries) >= 4, [
        'entries_created' => count($newEntries),
        'total_debit'     => $totalDebit,
        'total_credit'    => $totalCredit,
        'balanced'        => abs($totalDebit - $totalCredit) < 0.01,
        'entries'         => $newEntries,
    ]);
} catch (Throwable $e) { $log('6_ledger_entries', false, ['error' => $e->getMessage()]); }

// ══ STEP 7: Duplicate Payment Attempt ══════════════════════════════
try {
    if ($invoiceId) {
        $r5 = FinancialAgent::confirmPayment($invoiceId, 1);
        $log('7_dup_payment_rejected', !($r5['success'] ?? true), [
            'second_payment_attempted' => true,
            'was_rejected'             => !($r5['success'] ?? true),
            'error'                    => $r5['error'] ?? null,
        ]);
    }
} catch (Throwable $e) { $log('7_dup_payment_rejected', true, ['error' => $e->getMessage()]); }

// ══ STEP 8: EventBus → Task Created ════════════════════════════════
try {
    $tasksBefore = (int)db()->query("SELECT COUNT(*) FROM tasks WHERE status='pending'")->fetchColumn();
    EventBus::emit('payment.confirmed', [
        'user_id'    => 1,
        'invoice_id' => $invoiceId,
        'amount'     => 500.00,
    ]);
    $tasksAfter = (int)db()->query("SELECT COUNT(*) FROM tasks WHERE status='pending'")->fetchColumn();
    $latestTask = db()->query(
        "SELECT * FROM tasks ORDER BY id DESC LIMIT 1"
    )->fetch(PDO::FETCH_ASSOC);
    $log('8_eventbus_task', $tasksAfter > $tasksBefore, [
        'tasks_before' => $tasksBefore,
        'tasks_after'  => $tasksAfter,
        'task_created' => $tasksAfter > $tasksBefore,
        'latest_task'  => $latestTask,
    ]);
} catch (Throwable $e) { $log('8_eventbus_task', false, ['error' => $e->getMessage()]); }

// ══ STEP 9: Tasks Table State ═══════════════════════════════════════
try {
    $taskStats = db()->query(
        "SELECT status, COUNT(*) as cnt FROM tasks GROUP BY status"
    )->fetchAll(PDO::FETCH_ASSOC);
    $recent = db()->query(
        "SELECT id,type,status,attempts,created_at,updated_at FROM tasks ORDER BY id DESC LIMIT 5"
    )->fetchAll(PDO::FETCH_ASSOC);
    $log('9_tasks_state', true, ['stats' => $taskStats, 'recent' => $recent]);
} catch (Throwable $e) { $log('9_tasks_state', false, ['error' => $e->getMessage()]); }

// ══ STEP 10: Run Worker Inline (sync test) ══════════════════════════
try {
    require_once __DIR__ . '/engine/QueueEngine.php';
    require_once __DIR__ . '/engine/AIOrchestrator.php';
    require_once __DIR__ . '/engine/DecisionEngine.php';
    require_once __DIR__ . '/engine/PolicyEngine.php';
    require_once __DIR__ . '/engine/ControlEngine.php';
    require_once __DIR__ . '/engine/TaskEngine.php';
    require_once __DIR__ . '/engine/GrowthBrain.php';
    require_once __DIR__ . '/engine/SupportEngines.php';
    require_once __DIR__ . '/engine/BehaviorEngine.php';

    $tasks = QueueEngine::fetch(3);
    $processed = 0;
    foreach ($tasks as $task) {
        try {
            $payload = json_decode($task['payload'], true) ?? [];
            if ($task['type'] === 'event') {
                $event = $payload['event'] ?? '';
                unset($payload['event']);
                if ($event) { AIOrchestrator::run($event, $payload); $processed++; }
            }
            QueueEngine::done((int)$task['id']);
        } catch (Throwable $e) {
            QueueEngine::fail((int)$task['id'], $e->getMessage());
        }
    }

    $tasksDone = (int)db()->query(
        "SELECT COUNT(*) FROM tasks WHERE status='done'"
    )->fetchColumn();
    $log('10_worker_inline', $processed >= 0, [
        'tasks_fetched'    => count($tasks),
        'tasks_processed'  => $processed,
        'total_done_in_db' => $tasksDone,
    ]);
} catch (Throwable $e) { $log('10_worker_inline', false, ['error' => $e->getMessage()]); }

// ══ STEP 11: Ledger Balance Verification ═══════════════════════════
try {
    $balance = FinancialAgent::verifyLedger();
    $log('11_ledger_balance', $balance['balanced'] ?? false, $balance);
} catch (Throwable $e) { $log('11_ledger_balance', false, ['error' => $e->getMessage()]); }

// ══ STEP 12: Wallet Updated ════════════════════════════════════════
try {
    $wallet = db()->query("SELECT * FROM wallet WHERE user_id=1")->fetch(PDO::FETCH_ASSOC);
    $txns   = db()->query(
        "SELECT * FROM wallet_transactions WHERE user_id=1 ORDER BY id DESC LIMIT 3"
    )->fetchAll(PDO::FETCH_ASSOC);
    $log('12_wallet', (bool)$wallet, ['wallet' => $wallet, 'transactions' => $txns]);
} catch (Throwable $e) { $log('12_wallet', false, ['error' => $e->getMessage()]); }

// ══ SUMMARY ════════════════════════════════════════════════════════
$passed = count(array_filter($proof['steps'], fn($s) => $s['ok']));
$total  = count($proof['steps']);
$proof['summary'] = [
    'passed'       => $passed,
    'total'        => $total,
    'score'        => round($passed / $total * 100) . '%',
    'status'       => $passed === $total ? 'ALL_PASS ✅' : "PARTIAL ({$passed}/{$total})",
    'system_ready' => $passed >= 10,
];

echo json_encode($proof, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
