<?php
/**
 * MT5 Reconciliation Upload Page
 *
 * Rebuilt 2026-08-19 alongside src/Mt5ReportParser.php and the reconcile
 * pipeline. Real changes from the old page: accepts .xlsx (the old page
 * blocked it outright, even though it's a completely valid real MT5
 * export format), requires the trader to say up front which TraderAlign
 * account the statement belongs to (the parse/reconcile endpoints both
 * require it now, matching to the right account is not optional), shows
 * the statement's own embedded MT5 account identity so a mismatch is
 * caught before anything gets reconciled, and routes to
 * /mt5-resolve?account_id=... afterward with nothing to pass by hand,
 * every unmatched item from this point on is a real, persisted row, not
 * transient JS state that disappears on reload.
 *
 * 2026-08-19 (same day, second pass): the account dropdown used to list
 * every account of every type mixed together, no different from the
 * plain flat list this same session's own audit had already found and
 * fixed everywhere else (Trading Center, Active Journeys). Rebuilt to
 * scope by Prop Firms/Live Accounts, then by challenge program for Prop
 * (1/2/3 Step, Instant Funding), the exact same filter shape Active
 * Journeys already uses, via the same apFetchAccounts() query this app
 * already treats as the one real account-fetching implementation
 * (src/AccountPicker.php), not a second copy of that logic.
 */
error_reporting(E_ALL);
ini_set('display_errors', 1);

require_once __DIR__ . '/../src/PropFirmHelpers.php';
require_once __DIR__ . '/../src/Csrf.php';
$userId = $auth->requireAuth();

$tier = 'free';
try {
    $stmt = $pdo->prepare('SELECT tier FROM user_profiles WHERE user_id = :uid LIMIT 1');
    $stmt->execute([':uid' => $userId]);
    $profileRow = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($profileRow && !empty($profileRow['tier'])) $tier = $profileRow['tier'];
} catch (\Throwable $e) {
    error_log("Failed to read user tier: " . $e->getMessage());
}
$hasAccess = in_array($tier, ['pro', 'elite', 'ultimate'], true);

$CHALLENGE_OPTIONS = ['all' => 'All Programs', 'one_step' => '1 Step', 'two_step' => '2 Step', 'three_step' => '3 Step', 'instant_funding' => 'Instant Funding'];

$requestedAccountId = trim((string)($_GET['account_id'] ?? ''));
$typeParam = $_GET['type'] ?? null;
$challengeParam = $_GET['challenge'] ?? null;

// A pre-selected account (arriving from Active Journeys' "Upload MT5
// Statement" link, which carries through whichever account was already
// open there) picks its OWN real type/program as the default tab, so the
// trader lands somewhere that actually shows it, rather than defaulting
// to Prop Firms and finding it missing. An explicit ?type=/?challenge= in
// the URL (the trader clicking a tab) always wins over this inference.
$mt5Type = 'prop';
$mt5Challenge = 'all';
if ($hasAccess && $requestedAccountId !== '' && $typeParam === null) {
    $lookup = $pdo->prepare('SELECT ta.account_type, ca.challenge_type FROM trading_accounts ta LEFT JOIN challenge_accounts ca ON ca.account_id = ta.id AND ca.deleted_at IS NULL WHERE ta.id = :id AND ta.user_id = :uid AND ta.deleted_at IS NULL LIMIT 1');
    $lookup->execute([':id' => $requestedAccountId, ':uid' => $userId]);
    $found = $lookup->fetch(PDO::FETCH_ASSOC);
    if ($found) {
        $mt5Type = $found['account_type'] === 'personal' ? 'live' : 'prop';
        if ($mt5Type === 'prop' && !empty($found['challenge_type'])) $mt5Challenge = $found['challenge_type'];
    }
}
if ($typeParam !== null) $mt5Type = $typeParam === 'live' ? 'live' : 'prop';
if ($challengeParam !== null && isset($CHALLENGE_OPTIONS[$challengeParam])) $mt5Challenge = $challengeParam;

$accounts = [];
$hasAnyAccounts = false;
if ($hasAccess) {
    $fetchOpts = $mt5Type === 'prop'
        ? ['account_type' => 'prop', 'challenge_type' => $mt5Challenge !== 'all' ? $mt5Challenge : null]
        : ['account_type' => 'personal'];
    $accounts = apFetchAccounts($userId, $db, $fetchOpts);

    // Distinct from "$accounts is empty": that can just mean the current
    // type/program tab has nothing in it, not that the trader has no
    // accounts at all. Only the latter should show the "add an account"
    // upsell instead of the filter UI.
    $countStmt = $pdo->prepare('SELECT COUNT(*) FROM trading_accounts WHERE user_id = :uid AND deleted_at IS NULL AND is_active = 1 AND workflow_context = :wfctx');
    $countStmt->execute([':uid' => $userId, ':wfctx' => ValidationService::getWorkflowState($userId, $db)]);
    $hasAnyAccounts = ((int)$countStmt->fetchColumn()) > 0;
}

// Validated against this user's own real, currently-scoped account list,
// never trusted blindly, and silently ignored (falls back to the normal
// "pick one" flow) if it doesn't match the active type/program tab.
$preselectedAccountId = '';
if ($requestedAccountId !== '') {
    foreach ($accounts as $a) {
        if ($a['id'] === $requestedAccountId) { $preselectedAccountId = $requestedAccountId; break; }
    }
}

function mt5UploadUrl(string $type, string $challenge = 'all', ?string $accountId = null): string {
    $params = ['type' => $type];
    if ($type === 'prop' && $challenge !== 'all') $params['challenge'] = $challenge;
    if ($accountId) $params['account_id'] = $accountId;
    return '/traderalign/mt5-upload?' . http_build_query($params);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MT5 Reconciliation - TraderAlign</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="/traderalign/assets/tokens.css">
    <link rel="icon" type="image/png" sizes="32x32" href="/traderalign/assets/favicon/favicon-32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/traderalign/assets/favicon/favicon-16.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/traderalign/assets/favicon/apple-touch-icon.png">
    <link rel="shortcut icon" href="/traderalign/assets/favicon/favicon.ico">
    <link rel="stylesheet" href="/traderalign/assets/css/brand.css">
    <style>
        .dash-layout{display:flex;min-height:100vh}
        .sidebar{width:4rem;background:var(--sidebar);border-right:1px solid var(--sidebar-border);display:flex;flex-direction:column;align-items:center;padding-top:1rem;gap:.25rem;position:fixed;top:0;left:0;bottom:0;z-index:40}
        .sidebar a{display:flex;align-items:center;justify-content:center;width:2.75rem;height:2.75rem;border-radius:var(--radius-md);color:var(--foreground-dim);transition:background var(--t-fast),color var(--t-fast);position:relative}
        .sidebar a:hover{background:var(--background-surface);color:var(--foreground)}
        .sidebar a.active{background:var(--background-surface);color:var(--sidebar-primary)}
        .sidebar a .tt{position:absolute;left:3.5rem;background:var(--popover);color:var(--foreground);font-size:.75rem;padding:.25rem .625rem;border-radius:var(--radius-sm);white-space:nowrap;pointer-events:none;opacity:0;transition:opacity var(--t-fast)}
        .sidebar a:hover .tt{opacity:1}
        .main{margin-left:4rem;flex:1;padding:2rem;max-width:calc(100vw - 4rem)}
        .page-header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:1.5rem;flex-wrap:wrap;gap:.75rem}
        .page-header-left{display:flex;flex-direction:column;gap:.2rem}
        .page-title{font-size:1.5rem;font-weight:700;color:var(--foreground);display:flex;align-items:center;gap:.5rem}
        .page-sub{color:var(--foreground-muted);font-size:.875rem}
        .tier-badge{display:inline-block;font-size:.63rem;font-weight:700;padding:.18rem .55rem;border-radius:var(--radius-full);text-transform:uppercase;letter-spacing:.04em}
        .tier-badge.free{background:var(--background-surface);color:var(--foreground-dim);border:1px solid var(--border)}
        .tier-badge.pro{background:color-mix(in srgb,var(--warning) 15%,transparent);color:var(--warning);border:1px solid color-mix(in srgb,var(--warning) 30%,transparent)}
        .tier-badge.elite{background:color-mix(in srgb,var(--positive) 15%,transparent);color:var(--positive);border:1px solid color-mix(in srgb,var(--positive) 30%,transparent)}
        .tier-badge.ultimate{background:linear-gradient(135deg,var(--primary),var(--positive));color:#fff;border:1px solid transparent}
        .section-card{background:var(--background-elevated);border:1px solid var(--border);border-radius:var(--radius-xl);padding:1.5rem;margin-bottom:1rem}
        .form-group{margin-bottom:1.25rem}
        .form-group label{display:block;font-size:.75rem;font-weight:600;color:var(--foreground-dim);text-transform:uppercase;letter-spacing:.03em;margin-bottom:.4rem}
        .form-group select{width:100%;max-width:420px;height:2.5rem;padding:0 .75rem;background:var(--background);border:1px solid var(--border);border-radius:var(--radius-md);color:var(--foreground);font-size:.85rem}
        .account-hint{font-size:.72rem;color:var(--foreground-dim);margin-top:.4rem}
        .upload-zone{border:2px dashed var(--border);border-radius:var(--radius-xl);padding:3rem 2rem;text-align:center;cursor:pointer;transition:all var(--t);background:var(--background)}
        .upload-zone.disabled{opacity:.45;cursor:not-allowed;pointer-events:none}
        .upload-zone:hover,.upload-zone.drag-over{border-color:var(--primary);background:color-mix(in srgb,var(--primary) 5%,transparent)}
        .upload-zone-icon{font-size:3rem;margin-bottom:1rem;display:block}
        .upload-zone-title{font-size:1.1rem;font-weight:600;color:var(--foreground);margin-bottom:.5rem}
        .upload-zone-sub{font-size:.8rem;color:var(--foreground-dim);margin-bottom:1rem}
        .upload-zone-formats{display:flex;gap:.5rem;justify-content:center;flex-wrap:wrap}
        .format-badge{display:inline-block;padding:.25rem .7rem;border-radius:var(--radius-full);font-size:.7rem;font-weight:600;background:var(--background-surface);color:var(--foreground-muted);border:1px solid var(--border);font-family:var(--font-mono)}
        .upload-info{display:flex;gap:1.5rem;justify-content:center;margin-top:1.25rem;flex-wrap:wrap}
        .upload-info-item{display:flex;align-items:center;gap:.4rem;font-size:.72rem;color:var(--foreground-dim)}
        .btn{display:inline-flex;align-items:center;gap:.4rem;padding:.65rem 1.25rem;font-size:.82rem;font-weight:600;border-radius:var(--radius-md);border:none;cursor:pointer;transition:all var(--t-fast);text-decoration:none;font-family:inherit}
        .btn-primary{background:var(--primary);color:#fff}
        .btn-primary:hover{filter:brightness(1.1)}
        .message{padding:.75rem 1rem;border-radius:var(--radius-md);font-size:.85rem;margin-bottom:1.25rem;line-height:1.5}
        .message.success{background:color-mix(in srgb,var(--positive) 10%,transparent);border:1px solid color-mix(in srgb,var(--positive) 22%,transparent);color:var(--positive)}
        .message.error{background:color-mix(in srgb,var(--negative) 10%,transparent);border:1px solid color-mix(in srgb,var(--negative) 22%,transparent);color:var(--negative)}
        .message.warning{background:color-mix(in srgb,var(--warning) 10%,transparent);border:1px solid color-mix(in srgb,var(--warning) 22%,transparent);color:var(--warning)}
        .upgrade-card{background:var(--background-elevated);border:1px solid var(--border);border-left:3px solid transparent;border-radius:var(--radius-xl);padding:2rem;margin-bottom:1rem;position:relative;overflow:hidden}
        .upgrade-card::before{content:'';position:absolute;top:0;left:0;width:3px;height:100%;z-index:1;background:var(--primary)}
        .uc-icon{font-size:2rem;margin-bottom:.75rem;display:block}
        .uc-title{font-size:1.2rem;font-weight:700;color:var(--foreground);margin-bottom:.75rem;line-height:1.3}
        .uc-body{font-size:.88rem;color:var(--foreground-muted);line-height:1.7;margin-bottom:1.5rem;max-width:640px}
        .table-wrap{overflow-x:auto;margin:1rem 0;border:1px solid var(--border);border-radius:var(--radius-lg)}
        .preview-table{width:100%;border-collapse:collapse;font-size:.78rem}
        .preview-table th{background:var(--background-surface);padding:.65rem .85rem;text-align:left;font-weight:600;color:var(--foreground-dim);font-size:.68rem;text-transform:uppercase;letter-spacing:.04em;border-bottom:1px solid var(--border);white-space:nowrap}
        .preview-table td{padding:.55rem .85rem;border-bottom:1px solid var(--border);color:var(--foreground);font-family:var(--font-mono);font-size:.75rem;white-space:nowrap}
        .preview-table tr:last-child td{border-bottom:none}
        .preview-table .pnl-positive{color:var(--positive)}
        .preview-table .pnl-negative{color:var(--negative)}
        .preview-table .direction-long{color:var(--positive)}
        .preview-table .direction-short{color:var(--negative)}
        .positive{color:var(--positive)}
        .negative{color:var(--negative)}
        .action-bar{display:flex;gap:.75rem;align-items:center;margin-top:1.5rem;flex-wrap:wrap}
        .preview-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem;gap:1rem;flex-wrap:wrap}
        .preview-title{font-size:1rem;font-weight:600;color:var(--foreground)}
        .preview-count{font-size:.75rem;color:var(--foreground-dim);background:var(--background-surface);padding:.2rem .6rem;border-radius:var(--radius-full);font-family:var(--font-mono)}
        .btn-secondary{background:var(--background-surface);color:var(--foreground);border:1px solid var(--border)}
        .btn-secondary:hover{background:var(--background-elevated)}
        .btn-primary:disabled{opacity:.5;cursor:not-allowed}
        .identity-card{display:flex;flex-wrap:wrap;gap:1.5rem;padding:1rem 1.25rem;background:var(--background-surface);border-radius:var(--radius-lg);border:1px solid var(--border);margin-bottom:1rem}
        .identity-item{display:flex;flex-direction:column;gap:.15rem}
        .identity-label{font-size:.65rem;color:var(--foreground-dim);text-transform:uppercase;letter-spacing:.03em}
        .identity-value{font-size:.85rem;font-weight:600;color:var(--foreground);font-family:var(--font-mono)}

        /* ── Step badges + account/program filtering (2026-08-19 pass) ── */
        .step-head{display:flex;align-items:center;gap:.65rem;margin-bottom:1.25rem}
        .step-badge{display:flex;align-items:center;justify-content:center;width:1.6rem;height:1.6rem;border-radius:50%;background:color-mix(in srgb,var(--primary) 18%,transparent);color:var(--primary);font-size:.78rem;font-weight:700;flex-shrink:0}
        .step-title{font-size:.95rem;font-weight:700;color:var(--foreground)}
        .mt5-type-switch{display:flex;gap:.4rem;margin-bottom:.9rem}
        .mt5-type-tab{padding:.5rem 1.1rem;border-radius:var(--radius-full);font-size:.78rem;font-weight:700;text-decoration:none;color:var(--foreground-dim);background:var(--background);border:1px solid var(--border);transition:all var(--t-fast)}
        .mt5-type-tab:hover{color:var(--foreground);border-color:var(--foreground-dim)}
        .mt5-type-tab.active{background:color-mix(in srgb,var(--primary) 16%,transparent);color:var(--primary);border-color:color-mix(in srgb,var(--primary) 45%,transparent)}
        .mt5-challenge-filter{display:flex;gap:.4rem;margin-bottom:1.1rem;flex-wrap:wrap}
        .mt5-challenge-tab{padding:.4rem .85rem;border-radius:var(--radius-full);font-size:.72rem;font-weight:600;text-decoration:none;color:var(--foreground-dim);background:var(--background);border:1px solid var(--border);transition:all var(--t-fast)}
        .mt5-challenge-tab:hover{color:var(--foreground);border-color:var(--foreground-dim)}
        .mt5-challenge-tab.active{background:color-mix(in srgb,var(--positive) 14%,transparent);color:var(--positive);border-color:color-mix(in srgb,var(--positive) 40%,transparent)}
        .mt5-empty-filter{padding:1rem 1.1rem;background:var(--background);border:1px dashed var(--border);border-radius:var(--radius-lg);font-size:.82rem;color:var(--foreground-muted);line-height:1.6}
        .mt5-empty-filter a{color:var(--primary);text-decoration:none;font-weight:600}
        .mt5-empty-filter a:hover{text-decoration:underline}
        .howto-card{margin-top:1.5rem;padding:1.1rem 1.25rem;background:var(--background-surface);border-radius:var(--radius-lg);border:1px solid var(--border)}
        .howto-title{font-size:.75rem;color:var(--foreground-dim);margin-bottom:.6rem;font-weight:600;text-transform:uppercase;letter-spacing:.03em}
        .howto-list{font-size:.78rem;color:var(--foreground-muted);line-height:1.85;padding-left:1.25rem}
        @media(max-width:768px){.main{padding:1rem}.upload-zone{padding:2rem 1rem}.upload-info{flex-direction:column;align-items:center;gap:.5rem}.action-bar{flex-direction:column}.btn{width:100%;justify-content:center}}
    </style>
</head>
<body class="dash-layout">

<?php require __DIR__ . '/sidebar.php'; ?>

<main class="main">

    <div class="page-header">
        <div class="page-header-left">
            <h1 class="page-title">MT5 Reconciliation <span class="tier-badge <?= htmlspecialchars($tier) ?>"><?= ucfirst($tier) ?></span></h1>
            <p class="page-sub">Upload your MT5 report to reconcile trades with TraderAlign</p>
        </div>
    </div>

    <?php if (!$hasAccess): ?>
    <div class="upgrade-card">
        <span class="uc-icon">📊</span>
        <h2 class="uc-title">MT5 Reconciliation requires Pro or higher</h2>
        <p class="uc-body">Upload MetaTrader 5 HTML, CSV, or Excel reports to automatically reconcile your broker trades with TraderAlign, including catching trades you journaled that your broker never confirms, and trades your broker executed that you never logged. Upgrade to Pro to unlock this.</p>
        <a href="/traderalign/pricing" class="btn btn-primary uc-btn">View Plans →</a>
    </div>

    <?php elseif (!$hasAnyAccounts): ?>
    <div class="upgrade-card">
        <span class="uc-icon">🏦</span>
        <h2 class="uc-title">Add a trading account first</h2>
        <p class="uc-body">MT5 reconciliation always runs against one specific TraderAlign account, add one before uploading a statement.</p>
        <a href="/traderalign/trading-center" class="btn btn-primary uc-btn">Go to Trading Center →</a>
    </div>

    <?php else: ?>

    <div class="section-card">
        <div class="step-head">
            <span class="step-badge">1</span>
            <span class="step-title">Choose the account this statement belongs to</span>
        </div>

        <div class="mt5-type-switch">
            <a href="<?= htmlspecialchars(mt5UploadUrl('prop', 'all', $preselectedAccountId ?: null)) ?>" class="mt5-type-tab <?= $mt5Type === 'prop' ? 'active' : '' ?>">Prop Firms</a>
            <a href="<?= htmlspecialchars(mt5UploadUrl('live', 'all', $preselectedAccountId ?: null)) ?>" class="mt5-type-tab <?= $mt5Type === 'live' ? 'active' : '' ?>">Live Accounts</a>
        </div>

        <?php if ($mt5Type === 'prop'): ?>
        <div class="mt5-challenge-filter">
            <?php foreach ($CHALLENGE_OPTIONS as $val => $label): ?>
            <a href="<?= htmlspecialchars(mt5UploadUrl('prop', $val)) ?>" class="mt5-challenge-tab <?= $mt5Challenge === $val ? 'active' : '' ?>"><?= htmlspecialchars($label) ?></a>
            <?php endforeach; ?>
        </div>
        <?php endif; ?>

        <div class="form-group">
            <?php if (empty($accounts)): ?>
            <div class="mt5-empty-filter">
                No <?= $mt5Type === 'prop' ? htmlspecialchars($CHALLENGE_OPTIONS[$mt5Challenge]) . ' prop firm' : 'live' ?> accounts match this filter.
                <?php if ($mt5Type === 'prop' && $mt5Challenge !== 'all'): ?>
                Try <a href="<?= htmlspecialchars(mt5UploadUrl('prop', 'all')) ?>">All Programs</a>, or switch to <a href="<?= htmlspecialchars(mt5UploadUrl('live')) ?>">Live Accounts</a>.
                <?php else: ?>
                Try <a href="<?= htmlspecialchars(mt5UploadUrl($mt5Type === 'prop' ? 'live' : 'prop')) ?>"><?= $mt5Type === 'prop' ? 'Live Accounts' : 'Prop Firms' ?></a> instead.
                <?php endif; ?>
            </div>
            <?php else: ?>
            <label for="accountSelect">Which <?= $mt5Type === 'prop' ? 'prop firm' : 'live' ?> account does this statement belong to?</label>
            <select id="accountSelect" onchange="onAccountChange()">
                <option value="">Select an account…</option>
                <?php foreach ($accounts as $a): ?>
                <option value="<?= htmlspecialchars($a['id']) ?>"
                        data-account-number="<?= htmlspecialchars($a['account_number'] ?? '') ?>"
                        data-currency="<?= htmlspecialchars($a['currency'] ?? '') ?>"
                        <?= $a['id'] === $preselectedAccountId ? 'selected' : '' ?>>
                    <?= htmlspecialchars($a['label']) ?><?= $mt5Type === 'prop' ? ' (' . htmlspecialchars(apChallengeTypeLabel($a['challenge_type'] ?? null)) . ')' : (!empty($a['broker_server']) ? ' (' . htmlspecialchars($a['broker_server']) . ')' : '') ?>
                </option>
                <?php endforeach; ?>
            </select>
            <div class="account-hint">Every trade this statement reconciles will be matched only against this account's own journal, never mixed across accounts.</div>
            <?php endif; ?>
        </div>
    </div>

    <?php if (!empty($accounts)): ?>
    <div class="section-card">
        <div class="step-head">
            <span class="step-badge">2</span>
            <span class="step-title">Upload the statement</span>
        </div>

        <div class="upload-zone disabled" id="uploadZone" onclick="document.getElementById('fileInput').click()">
            <span class="upload-zone-icon">📁</span>
            <div class="upload-zone-title">Drop your MT5 report here</div>
            <div class="upload-zone-sub" id="uploadZoneSub">Select an account above first</div>
            <div class="upload-zone-formats">
                <span class="format-badge">.html</span>
                <span class="format-badge">.htm</span>
                <span class="format-badge">.xlsx</span>
                <span class="format-badge">.csv</span>
            </div>
            <div class="upload-info">
                <div class="upload-info-item">📏 Max file size: <?= round(MT5_MAX_FILE_SIZE / 1024 / 1024) ?>MB</div>
                <div class="upload-info-item">📋 Max positions: <?= number_format(MT5_MAX_ROWS_PER_IMPORT) ?> per import</div>
            </div>
        </div>

        <form id="uploadForm" method="POST" enctype="multipart/form-data" action="/traderalign/api/mt5/parse" style="display:none;">
            <input type="file" id="fileInput" name="file" accept=".html,.htm,.csv,.xlsx" onchange="handleFileSelect(event)">
        </form>

        <div class="howto-card">
            <p class="howto-title">📋 How to export your MT5 report</p>
            <ol class="howto-list">
                <li>Open MetaTrader 5 and go to the <strong>Toolbox</strong> window (Ctrl+T)</li>
                <li>Navigate to the <strong>History</strong> tab</li>
                <li>Right-click anywhere in the history and select <strong>Report</strong> then <strong>HTML</strong> or <strong>Excel</strong></li>
                <li>Choose your desired date range and click <strong>Save</strong></li>
                <li>Upload the saved file here</li>
            </ol>
        </div>
    </div>
    <?php endif; ?>

    <div id="resultsArea" style="display:none;"></div>

    <?php endif; ?>

</main>

<script>
window._accountPickerUrl = '<?= htmlspecialchars(mt5UploadUrl($mt5Type, $mt5Challenge), ENT_QUOTES) ?>';
window._mt5RnType = '<?= htmlspecialchars($mt5Type, ENT_QUOTES) ?>';

function mt5AccountConfirmUrl(accountId) {
    return '/traderalign/journal?workspace=active&rn_type=' + encodeURIComponent(window._mt5RnType) + '&rn_account=' + encodeURIComponent(accountId);
}

function onAccountChange() {
    var sel = document.getElementById('accountSelect');
    var zone = document.getElementById('uploadZone');
    var sub = document.getElementById('uploadZoneSub');
    if (sel.value) {
        zone.classList.remove('disabled');
        sub.textContent = 'or click to browse files';
    } else {
        zone.classList.add('disabled');
        sub.textContent = 'Select an account above first';
    }
}

// An account already came pre-selected (e.g. arriving from Active
// Journeys' "Upload MT5 Statement" link, which carries through whichever
// account was already open there), reflect that in the upload zone
// immediately, same as if the trader had just picked it themselves.
document.addEventListener('DOMContentLoaded', function() {
    var sel = document.getElementById('accountSelect');
    if (sel && sel.value) onAccountChange();
});

(function() {
    var zone = document.getElementById('uploadZone');
    if (!zone) return;
    ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(function(eventName) {
        zone.addEventListener(eventName, preventDefaults, false);
        document.body.addEventListener(eventName, preventDefaults, false);
    });
    function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); }
    ['dragenter', 'dragover'].forEach(function(eventName) {
        zone.addEventListener(eventName, function() { if (!zone.classList.contains('disabled')) zone.classList.add('drag-over'); }, false);
    });
    ['dragleave', 'drop'].forEach(function(eventName) {
        zone.addEventListener(eventName, function() { zone.classList.remove('drag-over'); }, false);
    });
    zone.addEventListener('drop', function(e) {
        if (zone.classList.contains('disabled')) return;
        var files = e.dataTransfer.files;
        if (files.length > 0) validateAndUpload(files[0]);
    });
})();

function handleFileSelect(event) {
    var file = event.target.files[0];
    if (file) validateAndUpload(file);
}

function validateAndUpload(file) {
    var accountId = document.getElementById('accountSelect').value;
    if (!accountId) { alert('Select which account this statement belongs to first.'); return; }
    var ext = file.name.split('.').pop().toLowerCase();
    if (['html', 'htm', 'csv', 'xlsx'].indexOf(ext) === -1) {
        alert('Please upload an HTML, CSV, or Excel (.xlsx) file exported from MT5.');
        return;
    }
    if (file.size > <?= (int)MT5_MAX_FILE_SIZE ?>) {
        alert('File exceeds the maximum size.');
        return;
    }
    uploadFile(file, accountId);
}

function uploadFile(file, accountId) {
    var formData = new FormData();
    formData.append('file', file);
    formData.append('account_id', accountId);

    var resultsArea = document.getElementById('resultsArea');
    resultsArea.style.display = 'block';
    resultsArea.innerHTML = '<div class="section-card"><p style="text-align:center;color:var(--foreground-dim)">⏳ Parsing MT5 report...</p></div>';

    fetch('/traderalign/api/mt5/parse', { method: 'POST', body: formData })
        .then(function(response) { return response.json(); })
        .then(function(data) {
            if (data.success) {
                showParseResults(data);
            } else {
                resultsArea.innerHTML = '<div class="message error">' + escapeHtml(data.error || 'Failed to parse report.') + '</div>';
            }
        })
        .catch(function(error) {
            resultsArea.innerHTML = '<div class="message error">Network error: ' + escapeHtml(error.message) + '</div>';
        });
}

function showParseResults(data) {
    var html = '<div class="section-card">';

    var acc = data.statement_account || {};
    html += '<div class="identity-card">';
    html += identityItem('Broker Account #', acc.number);
    html += identityItem('Currency', acc.currency);
    html += identityItem('Server', acc.server);
    html += identityItem('Mode', acc.mode ? (acc.mode.charAt(0).toUpperCase() + acc.mode.slice(1)) : null);
    html += identityItem('Company', acc.company);
    html += '</div>';

    var m = data.account_match || {};
    // Only a real, verified account-number match is ever allowed to
    // reconcile - both "mismatch" and "we simply don't know" are treated
    // as blocked. An earlier version of this page offered a one-click
    // "save this number" button right here to clear the unverified case,
    // which was a real, live-caught flaw: it let a wrong account
    // selection get permanently written as a false "verified" match with
    // a single click, worse than staying honestly unverified. Confirming
    // an account's real broker number now only happens deliberately, in
    // Active Journeys / Trading Center, where the account's real balance,
    // phase, and broker details are visible alongside the field being
    // edited, never as a rushed side effect of an upload.
    var blocked = (m.status !== 'verified_match');
    if (m.status === 'verified_mismatch') {
        html += '<div class="message error">✕ This statement belongs to broker account #' + escapeHtml(m.statement_account_number || '?') +
            ', not <strong>' + escapeHtml(data.account_label || 'the account you selected') + '</strong> (saved as #' + escapeHtml(m.saved_account_number || '?') +
            '). This cannot be reconciled against the wrong account. Go back and pick the correct account, or upload the right statement.</div>';
    } else if (m.status === 'verified_match') {
        html += '<div class="message success">✓ This statement\'s account identity matches your selected account.</div>';
    } else if (m.status === 'unverified') {
        html += '<div class="message warning"><strong>' + escapeHtml(data.account_label || 'This account') + '</strong> has no saved broker account number yet, so this statement cannot be verified as belonging to it' +
            (m.statement_account_number ? ' (the statement itself shows account #' + escapeHtml(m.statement_account_number) + ')' : '') + '. ' +
            'Add this account\'s real broker account number first, where you can review the account\'s full details before confirming.' +
            '<div style="margin-top:.6rem"><a href="' + escapeHtml(mt5AccountConfirmUrl(data.account_id)) + '" class="btn btn-secondary btn-sm">⧉ Confirm Account Details</a></div></div>';
    }

    if (data.is_empty_statement) {
        html += '<div class="message warning">This statement shows no closed trades for this account in the exported period, nothing to reconcile.</div>';
    }

    (data.warnings || []).forEach(function(w) {
        html += '<div class="message warning">⚠ ' + escapeHtml(w) + '</div>';
    });

    html += '<div class="preview-header">';
    html += '<div class="preview-title">📄 Closed Positions <span class="preview-count">' + data.count + ' found</span></div>';
    html += '</div>';

    if (data.count > 0) {
        // 2026-08-19 fix: SL/TP/Commission/Swap were always captured by
        // the parser (verified directly against a real statement, 39-40
        // of 40 real positions carry a real value) but this preview never
        // showed them, reading as a parsing gap when it was only ever a
        // display gap.
        html += '<div class="table-wrap"><table class="preview-table"><thead><tr>';
        html += '<th>Ticket</th><th>Symbol</th><th>Type</th><th>Volume</th><th>Entry</th><th>SL</th><th>TP</th><th>Exit</th><th>Commission</th><th>Swap</th><th>Net P&L</th><th>Opened</th><th>Closed</th>';
        html += '</tr></thead><tbody>';

        var totalPnl = 0;
        data.positions.forEach(function(p) {
            var netted = (p.profit || 0) + (p.commission || 0) + (p.swap || 0);
            totalPnl += netted;
            var dirClass = p.type === 'long' ? 'direction-long' : 'direction-short';
            html += '<tr>';
            html += '<td>' + escapeHtml(p.ticket) + '</td>';
            html += '<td style="font-weight:600">' + escapeHtml(p.symbol) + '</td>';
            html += '<td class="' + dirClass + '">' + (p.type.charAt(0).toUpperCase() + p.type.slice(1)) + '</td>';
            html += '<td>' + Number(p.volume).toFixed(2) + '</td>';
            html += '<td>' + Number(p.price).toFixed(5) + '</td>';
            html += '<td>' + (p.sl !== null ? Number(p.sl).toFixed(5) : '-') + '</td>';
            html += '<td>' + (p.tp !== null ? Number(p.tp).toFixed(5) : '-') + '</td>';
            html += '<td>' + (p.close_price !== null ? Number(p.close_price).toFixed(5) : '-') + '</td>';
            html += '<td>' + (p.commission !== null ? Number(p.commission).toFixed(2) : '-') + '</td>';
            html += '<td>' + (p.swap !== null ? Number(p.swap).toFixed(2) : '-') + '</td>';
            html += '<td class="' + (netted >= 0 ? 'pnl-positive' : 'pnl-negative') + '">' + (netted >= 0 ? '+' : '') + netted.toFixed(2) + '</td>';
            html += '<td>' + escapeHtml(p.time) + '</td>';
            html += '<td>' + escapeHtml(p.close_time || '-') + '</td>';
            html += '</tr>';
        });

        html += '</tbody><tfoot><tr style="background:var(--background-surface);font-weight:600">';
        html += '<td colspan="10" style="text-align:right;padding-right:.85rem;color:var(--foreground-dim)">Net Total:</td>';
        html += '<td class="' + (totalPnl >= 0 ? 'pnl-positive' : 'pnl-negative') + '">' + (totalPnl >= 0 ? '+' : '') + totalPnl.toFixed(2) + '</td>';
        html += '<td colspan="2"></td>';
        html += '</tr></tfoot></table></div>';
    }

    html += '<div class="action-bar">';
    if (blocked) {
        html += '<a href="' + escapeHtml(window._accountPickerUrl || '/traderalign/mt5-upload') + '" class="btn btn-primary">← Choose the Correct Account</a>';
    } else if (data.count > 0) {
        html += '<button class="btn btn-primary" id="reconcileBtn" onclick="runReconciliation()">✓ Reconcile ' + data.count + ' Position(s)</button>';
    }
    html += '<button class="btn btn-secondary" onclick="location.reload()">Upload Different File</button>';
    html += '</div>';
    html += '</div>';

    window._parseResult = data;
    document.getElementById('resultsArea').innerHTML = html;
}

function identityItem(label, value) {
    return '<div class="identity-item"><span class="identity-label">' + escapeHtml(label) + '</span><span class="identity-value">' + escapeHtml(value || '—') + '</span></div>';
}

function runReconciliation() {
    var data = window._parseResult;
    if (!data || !data.positions || data.positions.length === 0) { alert('No positions to reconcile.'); return; }

    var btn = document.getElementById('reconcileBtn');
    btn.disabled = true;
    btn.textContent = '⏳ Reconciling...';

    fetch('/traderalign/api/mt5/reconcile', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ positions: data.positions, account_id: data.account_id, reconciliation_id: data.reconciliation_id })
    })
    .then(function(response) { return response.json(); })
    .then(function(result) {
        if (result.success) {
            showReconcileResults(result, data.account_id);
        } else {
            alert('Reconciliation failed: ' + (result.error || 'Unknown error'));
            btn.disabled = false;
            btn.textContent = '✓ Reconcile Trades';
        }
    })
    .catch(function(error) {
        alert('Network error: ' + error.message);
        btn.disabled = false;
        btn.textContent = '✓ Reconcile Trades';
    });
}

function showReconcileResults(data, accountId) {
    var html = '<div class="section-card" style="margin-top:1rem">';
    html += '<div class="preview-header"><div class="preview-title">🔗 Reconciliation Results</div></div>';

    if (data.summary) {
        html += '<div style="display:flex;gap:1rem;flex-wrap:wrap;margin-bottom:1rem">';
        html += '<div style="padding:.5rem 1rem;background:color-mix(in srgb,var(--positive) 10%,transparent);border-radius:var(--radius-md);font-size:.8rem">✅ Auto-Matched: <strong>' + data.summary.auto_matched + '</strong></div>';
        if (data.summary.needs_confirmation > 0) {
            html += '<div style="padding:.5rem 1rem;background:color-mix(in srgb,var(--warning) 10%,transparent);border-radius:var(--radius-md);font-size:.8rem">⚠️ Needs Review: <strong>' + data.summary.needs_confirmation + '</strong></div>';
        }
        if (data.summary.unmatched_mt5 > 0) {
            html += '<div style="padding:.5rem 1rem;background:color-mix(in srgb,var(--negative) 10%,transparent);border-radius:var(--radius-md);font-size:.8rem">❌ Broker Trades Never Journaled: <strong>' + data.summary.unmatched_mt5 + '</strong></div>';
        }
        if (data.summary.unmatched_ta > 0) {
            html += '<div style="padding:.5rem 1rem;background:color-mix(in srgb,var(--negative) 10%,transparent);border-radius:var(--radius-md);font-size:.8rem">❓ Journaled But Never Executed: <strong>' + data.summary.unmatched_ta + '</strong></div>';
        }
        html += '</div>';
    }

    var needsReview = (data.summary && (data.summary.needs_confirmation > 0 || data.summary.unmatched_mt5 > 0 || data.summary.unmatched_ta > 0));
    html += '<div class="action-bar">';
    if (needsReview) {
        html += '<a href="/traderalign/mt5-resolve?account_id=' + encodeURIComponent(accountId) + '" class="btn btn-primary">🔧 Resolve Unmatched Trades</a>';
    }
    html += '<button class="btn btn-secondary" onclick="location.reload()">Upload Another Report</button>';
    html += '<a href="/traderalign/dashboard" class="btn btn-secondary">Back to Dashboard</a>';
    html += '</div>';

    html += '</div>';

    document.getElementById('resultsArea').insertAdjacentHTML('beforeend', html);
    document.getElementById('resultsArea').scrollIntoView({ behavior: 'smooth' });
}

function escapeHtml(text) {
    var div = document.createElement('div');
    div.textContent = (text === null || text === undefined) ? '' : text;
    return div.innerHTML;
}
</script>

</body>
</html>
