<?php
/**
 * Live, end-to-end verification of api/trades/draft.php's Wave-2 fix —
 * the five drawdown-budget snapshot fields (account_status_label,
 * drawdown_at_entry_pct, breathing_room_used_pct, breathing_room_remaining,
 * trades_remaining_buffer) are now computed server-side from
 * PropFirmRuleEngine, never trusted from the client payload.
 *
 * Simulates the exact "stale URL params across a phase promotion"
 * scenario: POSTs a real draft save with deliberately WRONG values for
 * all five fields (as if the calculator's cached window._pfContextCache
 * still held pre-promotion rule percentages) and confirms the ACTUALLY
 * PERSISTED row reflects the server's own fresh PropFirmRuleEngine
 * computation instead — not the client's stale claim.
 *
 * Real account, real checklist_results/trade created then fully deleted.
 */
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../src/JourneySegmentation.php';
require_once __DIR__ . '/../src/PropFirmRuleEngine.php';

$pdo = new PDO(
    "mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=utf8mb4",
    DB_USER, DB_PASS,
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
);

$accountId = 'd207ae67-78fb-4951-8e1c-403b699d618a'; // Phase Test 5K - Attempt 1
$userId = '278d5983-d646-494f-a130-b22f7c321867';

function uuid(): string {
    $data = random_bytes(16);
    $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
    $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
    return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}

// ── 1. What the server SHOULD compute, right now, for this account ──────
$expected = PropFirmRuleEngine::compute($accountId);
$expLimit = (float)$expected['overall_drawdown']['limit_amount'];
$expCurrent = (float)$expected['overall_drawdown']['current_amount'];
$expRemaining = (float)$expected['overall_drawdown']['remaining_amount'];
$riskPerPosition = 50.0;
$expBudgetUsedPct = round(($expCurrent / $expLimit) * 100, 2);
$expStatus = $expBudgetUsedPct >= 50 ? 'Danger' : ($expBudgetUsedPct >= 25 ? 'Caution' : 'Safe');
$expTradesRemaining = round($expRemaining / $riskPerPosition, 2);

echo "Expected (fresh, server-computed):\n";
echo "  account_status_label: {$expStatus}\n";
echo "  drawdown_at_entry_pct: {$expBudgetUsedPct}\n";
echo "  breathing_room_used_pct: {$expBudgetUsedPct}\n";
echo "  breathing_room_remaining: " . round($expRemaining, 2) . "\n";
echo "  trades_remaining_buffer: {$expTradesRemaining}\n\n";

// ── 2. Find a real strategy_version_id for this user (checklist_results FK) ──
$svidStmt = $pdo->prepare("SELECT id FROM strategy_versions WHERE user_id = ? LIMIT 1");
$svidStmt->execute([$userId]);
$svid = $svidStmt->fetchColumn();

// ── 3. Create a pending checklist_results row ────────────────────────────
$tradeLifecycleId = uuid();
$pdo->prepare("
    INSERT INTO checklist_results (id, trade_lifecycle_id, user_id, strategy_version_id, items_ticked, items_required, ticked_pct, status)
    VALUES (:id, :tlid, :uid, :svid, '[]', '[]', 100, 'pending_calculator')
")->execute([':id' => uuid(), ':tlid' => $tradeLifecycleId, ':uid' => $userId, ':svid' => $svid]);

// ── 4. Real HTTP POST to /api/trades/draft, deliberately sending WRONG
// values for all five fields — simulating a stale, pre-promotion
// window._pfContextCache. If the server still trusted these, the
// persisted row would show 999/"Danger"/1/1/0.01.
$base = 'http://localhost:8080/traderalign';
$cookieJar = tempnam(sys_get_temp_dir(), 'zzcookie5');

$ch = curl_init("{$base}/public/_zz_test_autologin.php?uid=" . urlencode($userId));
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_COOKIEJAR => $cookieJar, CURLOPT_COOKIEFILE => $cookieJar]);
curl_exec($ch);
curl_close($ch);

$payload = json_encode([
    'trade_lifecycle_id' => $tradeLifecycleId,
    'account_id' => $accountId,
    'strategy_version_id' => $svid,
    'instrument' => 'eurusd',
    'instrument_display' => 'EUR/USD',
    'direction' => 'long',
    'session' => 'London',
    'session_utc_time' => '08:00:00 UTC',
    'entry_price' => 1.1000,
    'sl_price' => 1.0950,
    'tp1_price' => 1.1100,
    'risk_mode' => 'auto',
    'risk_per_position' => $riskPerPosition,
    'risk_pct' => 1.0,
    'lots_per_position' => 0.1,
    'risk_reward_tp1' => 2.0,
    'max_potential_profit' => 100,
    'max_potential_loss' => 50,
    // Deliberately WRONG — simulating stale URL-param-derived client math:
    'account_status_label' => 'Danger',
    'drawdown_at_entry_pct' => 999,
    'breathing_room_used_pct' => 999,
    'breathing_room_remaining' => 1,
    'trades_remaining_buffer' => 0.01,
]);

$ch = curl_init("{$base}/api/trades/draft");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEJAR => $cookieJar,
    CURLOPT_COOKIEFILE => $cookieJar,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
@unlink($cookieJar);

echo "POST /api/trades/draft (sending intentionally WRONG values) => HTTP {$code}\n";
echo "Response: {$resp}\n\n";

$decoded = json_decode($resp, true);
$tradeId = $decoded['trade_id'] ?? null;

if (!$tradeId) {
    echo "!!! No trade_id returned — cannot verify persisted row.\n";
    // Still attempt cleanup of the checklist row.
    $pdo->prepare("DELETE FROM checklist_results WHERE trade_lifecycle_id = ?")->execute([$tradeLifecycleId]);
    exit(1);
}

// ── 5. Read back the ACTUALLY PERSISTED row ─────────────────────────────
$persisted = $pdo->prepare("SELECT account_status_label, drawdown_at_entry_pct, breathing_room_used_pct, breathing_room_remaining, trades_remaining_buffer FROM trades WHERE id = ?");
$persisted->execute([$tradeId]);
$row = $persisted->fetch();

echo "ACTUALLY PERSISTED:\n";
echo "  account_status_label: {$row['account_status_label']}\n";
echo "  drawdown_at_entry_pct: {$row['drawdown_at_entry_pct']}\n";
echo "  breathing_room_used_pct: {$row['breathing_room_used_pct']}\n";
echo "  breathing_room_remaining: {$row['breathing_room_remaining']}\n";
echo "  trades_remaining_buffer: {$row['trades_remaining_buffer']}\n\n";

$pass = true;
if ((string)$row['account_status_label'] !== $expStatus) { $pass = false; echo "MISMATCH: account_status_label\n"; }
if (abs((float)$row['drawdown_at_entry_pct'] - $expBudgetUsedPct) > 0.01) { $pass = false; echo "MISMATCH: drawdown_at_entry_pct\n"; }
if (abs((float)$row['breathing_room_used_pct'] - $expBudgetUsedPct) > 0.01) { $pass = false; echo "MISMATCH: breathing_room_used_pct\n"; }
if (abs((float)$row['breathing_room_remaining'] - round($expRemaining, 2)) > 0.01) { $pass = false; echo "MISMATCH: breathing_room_remaining\n"; }
if (abs((float)$row['trades_remaining_buffer'] - $expTradesRemaining) > 0.01) { $pass = false; echo "MISMATCH: trades_remaining_buffer\n"; }

echo $pass
    ? "PASS — persisted values match the server's fresh PropFirmRuleEngine computation, completely ignoring the client's intentionally-wrong payload values.\n\n"
    : "!!! FAIL — see mismatches above.\n\n";

// ── 6. Revert ─────────────────────────────────────────────────────────
$pdo->prepare("DELETE FROM trades WHERE id = ?")->execute([$tradeId]);
$pdo->prepare("DELETE FROM checklist_results WHERE trade_lifecycle_id = ?")->execute([$tradeLifecycleId]);

$checkTrade = $pdo->prepare("SELECT COUNT(*) FROM trades WHERE id = ?");
$checkTrade->execute([$tradeId]);
$checkChecklist = $pdo->prepare("SELECT COUNT(*) FROM checklist_results WHERE trade_lifecycle_id = ?");
$checkChecklist->execute([$tradeLifecycleId]);

echo "REVERTED: trade deleted: " . ((int)$checkTrade->fetchColumn() === 0 ? 'YES' : 'NO — STILL EXISTS') . "\n";
echo "REVERTED: checklist_results deleted: " . ((int)$checkChecklist->fetchColumn() === 0 ? 'YES' : 'NO — STILL EXISTS') . "\n";
