<?php

/**
 * Developer Console — Synchronization Dashboard (DX002B)
 *
 * Main synchronization page. Provides:
 *   - Mirror status badge
 *   - Compare Schema (AJAX)
 *   - Dry Run (AJAX)
 *   - Generate Schema / SQL Preview (AJAX)
 *   - Push to Supabase (AJAX + confirmation modal)
 *   - Verify Mirror (AJAX)
 *   - Pull from Supabase (disabled — disaster recovery only)
 *   - Recent sync history
 *
 * Variables:
 *   $sync_status   — from SynchronizationService::getStatus()
 *   $recent_logs   — from SynchronizationService::getLogs(5)
 *   $supabase_info — from SupabaseService::getProjectInfo()
 *
 * @package Inveetaire
 * @ref     DX002B
 */

/** @var array $sync_status */
/** @var array $recent_logs */
/** @var array $supabase_info */
$sync_status   = $sync_status   ?? [];
$recent_logs   = $recent_logs   ?? [];
$supabase_info = $supabase_info ?? [];

$hasPat        = (bool)($sync_status['has_pat']             ?? false);
$sbConfigured  = (bool)($sync_status['supabase_configured'] ?? false);
$execMode      = $sync_status['execution_mode']  ?? 'sql_export';
$lastSync      = $sync_status['last_sync']       ?? null;
$lastStatus    = $sync_status['last_status']     ?? 'never';
$totalSyncs    = (int)($sync_status['total_syncs'] ?? 0);

// Route URLs
$compareUrl  = url('/app/developer/sync/compare');
$dryRunUrl   = url('/app/developer/sync/dry-run');
$pushUrl     = url('/app/developer/sync/push');
$verifyUrl   = url('/app/developer/sync/verify');
$previewUrl  = url('/app/developer/sync/preview');

?>

<!-- Page Header -->
<div style="margin-bottom: 2rem;">
    <div style="font-family: var(--mono); font-size: 0.6875rem; color: var(--dev-text-muted); margin-bottom: 0.5rem;">
        <a href="<?= url('/app/developer') ?>" style="color:var(--dev-accent); text-decoration:none;">developer</a>
        <span style="color:#444c56;"> / </span>
        <span style="color:#3ecf8e;">sync</span>
    </div>
    <h1 style="font-size: 1.5rem; font-weight: 800; color: var(--dev-text); margin-bottom: 0.25rem;">
        Synchronization
    </h1>
    <p style="font-size: 0.8125rem; color: var(--dev-text-muted);">
        Manual MySQL → Supabase schema synchronization. All actions require explicit confirmation.
    </p>
</div>

<!-- Status Banner -->
<div class="dev-card" style="margin-bottom: 2rem; <?= !$sbConfigured ? 'border-color:rgba(210,153,34,0.3);' : ($hasPat ? 'border-color:rgba(62,207,142,0.3);' : 'border-color:rgba(88,166,255,0.3);') ?>">
    <div class="dev-card-body" style="display:flex; align-items:center; gap:1.5rem; flex-wrap:wrap;">
        <div style="font-size:2rem; color:<?= !$sbConfigured ? '#d29922' : ($hasPat ? '#3ecf8e' : 'var(--dev-accent)') ?>;">
            <i class="fa-solid fa-<?= !$sbConfigured ? 'cloud-slash' : ($hasPat ? 'arrows-rotate' : 'cloud-arrow-up') ?>"></i>
        </div>
        <div>
            <div style="font-weight:700; font-size:0.9375rem; color:var(--dev-text); margin-bottom:0.125rem;" id="mirror-status-label">
                <?php
                if (!$sbConfigured) echo 'Supabase Not Configured';
                elseif ($hasPat)    echo 'Synchronization Ready';
                else                echo 'SQL Export Mode';
                ?>
            </div>
            <div style="font-size:0.8125rem; color:var(--dev-text-muted);">
                Execution Mode: <span style="font-family:var(--mono); color:var(--dev-accent);"><?= escape_html($execMode) ?></span>
                · Last Sync: <span style="font-family:var(--mono);"><?= escape_html($lastSync ?? 'Never') ?></span>
                · Total Syncs: <span style="font-family:var(--mono); color:var(--dev-accent2);"><?= $totalSyncs ?></span>
            </div>
        </div>
        <div style="margin-left:auto; display:flex; gap:0.75rem; align-items:center; flex-wrap:wrap;">
            <a href="<?= url('/app/developer/sync/log') ?>" style="font-family:var(--mono); font-size:0.75rem; color:var(--dev-text-muted); text-decoration:none;">
                View History →
            </a>
        </div>
    </div>
</div>

<!-- Operation Result Panel (hidden until action runs) -->
<div id="op-result" style="display:none; margin-bottom:1.5rem;" role="status" aria-live="polite">
    <div class="dev-card" id="op-result-card">
        <div class="dev-card-header">
            <span class="dev-card-title" id="op-result-title">Result</span>
            <span id="op-result-badge"></span>
        </div>
        <div class="dev-card-body" id="op-result-body"></div>
    </div>
</div>

<!-- SQL Preview Panel (hidden until generated) -->
<div id="sql-preview-panel" style="display:none; margin-bottom:1.5rem;">
    <div class="dev-card">
        <div class="dev-card-header">
            <span class="dev-card-title">
                <i class="fa-solid fa-code" style="color:var(--dev-accent); margin-right:0.375rem;"></i>
                SQL Preview
            </span>
            <div style="display:flex; gap:0.5rem; align-items:center;">
                <span id="sql-stmt-count" style="font-family:var(--mono); font-size:0.6875rem; color:var(--dev-text-muted);"></span>
                <button onclick="copySql()" style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.25rem 0.625rem; background:rgba(88,166,255,0.1); border:1px solid rgba(88,166,255,0.3); border-radius:4px; font-family:var(--mono); font-size:0.6875rem; color:var(--dev-accent); cursor:pointer;">
                    <i class="fa-solid fa-copy"></i> Copy
                </button>
                <button onclick="downloadSql()" style="display:inline-flex; align-items:center; gap:0.375rem; padding:0.25rem 0.625rem; background:rgba(62,207,142,0.1); border:1px solid rgba(62,207,142,0.3); border-radius:4px; font-family:var(--mono); font-size:0.6875rem; color:#3ecf8e; cursor:pointer;">
                    <i class="fa-solid fa-download"></i> Download .sql
                </button>
            </div>
        </div>
        <div class="dev-card-body" style="padding:0;">
            <pre id="sql-preview-content" style="font-family:var(--mono); font-size:0.6875rem; color:var(--dev-text-muted); background:var(--dev-surface2); border-radius:0 0 8px 8px; padding:1.25rem; margin:0; overflow-x:auto; max-height:400px; overflow-y:auto; line-height:1.6;"></pre>
        </div>
    </div>
</div>

<!-- ══════════════════════════════════════════════════════════════════════════ -->
<!-- Action Cards                                                               -->
<!-- ══════════════════════════════════════════════════════════════════════════ -->

<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 2rem;">

    <!-- Compare Schema -->
    <div class="dev-card">
        <div class="dev-card-header">
            <span class="dev-card-title">
                <i class="fa-solid fa-code-compare" style="color:var(--dev-accent); margin-right:0.375rem;"></i>
                Compare Schema
            </span>
            <span class="badge-ok">● Active</span>
        </div>
        <div class="dev-card-body">
            <p style="font-size:0.8125rem; color:var(--dev-text-muted); margin-bottom:1rem; line-height:1.5;">
                Compare MySQL and Supabase schemas at the table and column level. No changes made.
            </p>
            <button id="btn-compare" onclick="runCompare()" <?= !$sbConfigured ? 'disabled' : '' ?>
                    class="dev-action-btn" style="background:rgba(88,166,255,0.1); border-color:rgba(88,166,255,0.3); color:var(--dev-accent);">
                <i class="fa-solid fa-code-compare"></i> Compare Schema
            </button>
        </div>
    </div>

    <!-- Dry Run -->
    <div class="dev-card">
        <div class="dev-card-header">
            <span class="dev-card-title">
                <i class="fa-solid fa-flask" style="color:var(--dev-warn); margin-right:0.375rem;"></i>
                Dry Run
            </span>
            <span class="badge-ok">● Active</span>
        </div>
        <div class="dev-card-body">
            <p style="font-size:0.8125rem; color:var(--dev-text-muted); margin-bottom:1rem; line-height:1.5;">
                Compare, generate SQL, and estimate impact. <strong style="color:var(--dev-accent2);">Never executes SQL.</strong>
            </p>
            <button id="btn-dry-run" onclick="runDryRun()" <?= !$sbConfigured ? 'disabled' : '' ?>
                    class="dev-action-btn" style="background:rgba(210,153,34,0.1); border-color:rgba(210,153,34,0.3); color:var(--dev-warn);">
                <i class="fa-solid fa-flask"></i> Dry Run
            </button>
        </div>
    </div>

    <!-- Generate Schema / SQL Preview -->
    <div class="dev-card">
        <div class="dev-card-header">
            <span class="dev-card-title">
                <i class="fa-solid fa-file-code" style="color:var(--dev-purple); margin-right:0.375rem;"></i>
                Generate Schema
            </span>
            <span class="badge-ok">● Active</span>
        </div>
        <div class="dev-card-body">
            <p style="font-size:0.8125rem; color:var(--dev-text-muted); margin-bottom:1rem; line-height:1.5;">
                Generate PostgreSQL DDL from MySQL schema. Preview, copy, or download the SQL.
            </p>
            <div style="display:flex; gap:0.5rem; flex-wrap:wrap;">
                <button id="btn-preview-incr" onclick="runPreview('incremental')"
                        class="dev-action-btn" style="background:rgba(188,140,255,0.1); border-color:rgba(188,140,255,0.3); color:var(--dev-purple);">
                    <i class="fa-solid fa-arrows-turn-to-dots"></i> Incremental DDL
                </button>
                <button id="btn-preview-full" onclick="runPreview('full')"
                        class="dev-action-btn" style="background:rgba(188,140,255,0.08); border-color:rgba(188,140,255,0.2); color:var(--dev-purple);">
                    <i class="fa-solid fa-list"></i> Full DDL
                </button>
            </div>
        </div>
    </div>

    <!-- Verify Mirror -->
    <div class="dev-card">
        <div class="dev-card-header">
            <span class="dev-card-title">
                <i class="fa-solid fa-shield-check" style="color:var(--dev-accent2); margin-right:0.375rem;"></i>
                Verify Mirror
            </span>
            <span class="badge-ok">● Active</span>
        </div>
        <div class="dev-card-body">
            <p style="font-size:0.8125rem; color:var(--dev-text-muted); margin-bottom:1rem; line-height:1.5;">
                Verify Supabase mirror integrity: tables, columns, indexes, data types.
            </p>
            <button id="btn-verify" onclick="runVerify()" <?= !$sbConfigured ? 'disabled' : '' ?>
                    class="dev-action-btn" style="background:rgba(63,185,80,0.1); border-color:rgba(63,185,80,0.3); color:var(--dev-accent2);">
                <i class="fa-solid fa-shield-check"></i> Verify Mirror
            </button>
        </div>
    </div>

</div>

<!-- Push to Supabase (primary action) -->
<div class="dev-card" style="margin-bottom: 2rem; border-color: rgba(62,207,142,0.25);">
    <div class="dev-card-header">
        <span class="dev-card-title">
            <i class="fa-solid fa-cloud-arrow-up" style="color:#3ecf8e; margin-right:0.375rem;"></i>
            Push to Supabase
        </span>
        <?php if ($hasPat): ?>
            <span class="badge-ok">● Management API</span>
        <?php elseif ($sbConfigured): ?>
            <span class="badge-warn">SQL Export Mode</span>
        <?php else: ?>
            <span class="badge-warn">Not Configured</span>
        <?php endif; ?>
    </div>
    <div class="dev-card-body">
        <?php if (!$sbConfigured): ?>
            <div style="padding:0.875rem; background:rgba(210,153,34,0.06); border:1px solid rgba(210,153,34,0.2); border-radius:6px; font-size:0.8125rem; color:var(--dev-text-muted);">
                Configure Supabase credentials in <code style="font-family:var(--mono); color:var(--dev-accent);">.env</code> to enable push.
                <a href="<?= url('/app/developer/supabase') ?>" style="color:#3ecf8e; margin-left:0.5rem;">Configure →</a>
            </div>
        <?php else: ?>
        <p style="font-size:0.8125rem; color:var(--dev-text-muted); margin-bottom:1.25rem; line-height:1.5;">
            <?php if ($hasPat): ?>
                Executes generated DDL via Supabase Management API.
                A <strong style="color:var(--dev-warn);">confirmation dialog</strong> is required before execution.
            <?php else: ?>
                <strong style="color:var(--dev-accent2);">SQL Export Mode:</strong>
                Generates DDL and offers it as a downloadable <code style="font-family:var(--mono);">.sql</code> file.
                Add <code style="font-family:var(--mono); color:var(--dev-accent);">SUPABASE_ACCESS_TOKEN</code> to enable direct execution.
            <?php endif; ?>
        </p>
        <div style="display:flex; gap:0.75rem; flex-wrap:wrap; align-items:center;">
            <button id="btn-push-incr" onclick="confirmPush('incremental')"
                    class="dev-action-btn" style="background:rgba(62,207,142,0.12); border-color:rgba(62,207,142,0.4); color:#3ecf8e; font-weight:700;">
                <i class="fa-solid fa-cloud-arrow-up"></i>
                <?= $hasPat ? 'Push (Incremental)' : 'Export Incremental DDL' ?>
            </button>
            <button id="btn-push-full" onclick="confirmPush('full')"
                    class="dev-action-btn" style="background:rgba(62,207,142,0.06); border-color:rgba(62,207,142,0.25); color:#3ecf8e;">
                <i class="fa-solid fa-list"></i>
                <?= $hasPat ? 'Push (Full Schema)' : 'Export Full DDL' ?>
            </button>
        </div>
        <?php endif; ?>
    </div>
</div>

<!-- Pull from Supabase (disabled) -->
<div class="dev-card" style="margin-bottom: 2rem; opacity: 0.65;">
    <div class="dev-card-header">
        <span class="dev-card-title">
            <i class="fa-solid fa-cloud-arrow-down" style="color:#444c56; margin-right:0.375rem;"></i>
            Pull from Supabase
        </span>
        <span class="badge-warn">Disabled</span>
    </div>
    <div class="dev-card-body">
        <div style="display:flex; align-items:flex-start; gap:0.75rem;">
            <i class="fa-solid fa-shield-halved" style="color:var(--dev-warn); margin-top:0.125rem; flex-shrink:0;"></i>
            <div>
                <p style="font-size:0.8125rem; color:var(--dev-text-muted); line-height:1.5; margin-bottom:0.5rem;">
                    <strong style="color:var(--dev-warn);">Reserved for Disaster Recovery.</strong>
                    MySQL is the source of truth. Pulling from Supabase is not recommended during normal operation
                    as it could overwrite production data.
                </p>
                <p style="font-size:0.75rem; color:#444c56; font-family:var(--mono);">
                    To enable: contact the database architect for DX003 disaster recovery procedures.
                </p>
            </div>
        </div>
        <button disabled style="margin-top:1rem; display:inline-flex; align-items:center; gap:0.5rem; padding:0.5rem 1rem; background:var(--dev-surface2); border:1px solid var(--dev-border); border-radius:6px; font-family:var(--mono); font-size:0.75rem; color:#444c56; cursor:not-allowed;">
            <i class="fa-solid fa-cloud-arrow-down"></i> Pull from Supabase — Disabled
        </button>
    </div>
</div>

<!-- Recent Sync History -->
<?php if (!empty($recent_logs)): ?>
<div class="dev-section-title" style="margin-bottom:0.75rem;">Recent Sync History</div>
<div class="dev-card" style="margin-bottom:2rem;">
    <div style="overflow-x:auto;">
        <table class="dev-table">
            <thead><tr>
                <th>Timestamp</th><th>Type</th><th>Tables</th><th>Result</th><th>Duration</th><th>Mode</th>
            </tr></thead>
            <tbody>
            <?php foreach ($recent_logs as $log): ?>
                <tr>
                    <td class="mono" style="font-size:0.6875rem;"><?= escape_html($log['timestamp'] ?? '—') ?></td>
                    <td>
                        <?php if ($log['is_dry_run'] ?? false): ?>
                            <span class="badge-warn">Dry Run</span>
                        <?php else: ?>
                            <span class="badge-ok" style="font-size:0.5rem;">Push</span>
                        <?php endif; ?>
                    </td>
                    <td><?= (int)($log['tables_affected'] ?? 0) ?></td>
                    <td>
                        <?php $res = $log['result'] ?? '—'; ?>
                        <span style="font-family:var(--mono); font-size:0.6875rem; color:<?= $res === 'success' ? 'var(--dev-accent2)' : ($res === 'error' ? 'var(--dev-danger)' : 'var(--dev-warn)') ?>;"><?= escape_html($res) ?></span>
                    </td>
                    <td class="muted"><?= number_format((int)($log['duration_ms'] ?? 0)) ?> ms</td>
                    <td class="mono muted" style="font-size:0.6875rem;"><?= escape_html($log['execution_mode'] ?? '—') ?></td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>
    </div>
    <div style="padding:0.75rem 1rem; border-top:1px solid var(--dev-border2);">
        <a href="<?= url('/app/developer/sync/log') ?>" style="font-size:0.75rem; color:var(--dev-accent); text-decoration:none; font-family:var(--mono);">
            View Full History →
        </a>
    </div>
</div>
<?php endif; ?>

<!-- Confirmation Modal -->
<div id="confirm-modal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.7); z-index:1000; display:none; align-items:center; justify-content:center;">
    <div style="background:var(--dev-surface); border:1px solid var(--dev-border); border-radius:12px; padding:2rem; max-width:480px; width:90%; box-shadow:0 20px 60px rgba(0,0,0,0.5);">
        <h3 style="font-size:1.125rem; font-weight:800; color:var(--dev-text); margin-bottom:0.5rem;">
            <i class="fa-solid fa-triangle-exclamation" style="color:var(--dev-warn); margin-right:0.375rem;"></i>
            Confirm Push to Supabase
        </h3>
        <p id="confirm-modal-body" style="font-size:0.8125rem; color:var(--dev-text-muted); margin-bottom:1.5rem; line-height:1.6;"></p>
        <div style="display:flex; gap:0.75rem; justify-content:flex-end;">
            <button onclick="closeModal()" style="padding:0.5rem 1.25rem; background:var(--dev-surface2); border:1px solid var(--dev-border); border-radius:6px; font-family:var(--mono); font-size:0.75rem; color:var(--dev-text-muted); cursor:pointer;">
                Cancel
            </button>
            <button id="confirm-modal-ok" style="padding:0.5rem 1.25rem; background:rgba(62,207,142,0.2); border:1px solid rgba(62,207,142,0.5); border-radius:6px; font-family:var(--mono); font-size:0.75rem; color:#3ecf8e; cursor:pointer; font-weight:700;">
                Confirm Push
            </button>
        </div>
    </div>
</div>

<style>
.dev-action-btn {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.5rem 1rem; border-radius: 6px; border: 1px solid;
    font-family: var(--mono); font-size: 0.75rem; cursor: pointer;
    transition: opacity 0.15s;
}
.dev-action-btn:hover:not(:disabled) { opacity: 0.8; }
.dev-action-btn:disabled { opacity: 0.4; cursor: not-allowed; }
</style>

<script>
const urls = {
    compare: '<?= escape_javascript($compareUrl) ?>',
    dryRun:  '<?= escape_javascript($dryRunUrl) ?>',
    push:    '<?= escape_javascript($pushUrl) ?>',
    verify:  '<?= escape_javascript($verifyUrl) ?>',
    preview: '<?= escape_javascript($previewUrl) ?>',
};

let currentSql = '';
let pendingPushMode = '';

// ── Helpers ────────────────────────────────────────────────────────────────

function setLoading(btnId, loading) {
    const btn = document.getElementById(btnId);
    if (!btn) return;
    btn.disabled = loading;
    if (loading) btn.dataset.orig = btn.innerHTML;
    else btn.innerHTML = btn.dataset.orig || btn.innerHTML;
    if (loading) btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Working…';
}

function showResult(title, badgeHtml, bodyHtml) {
    document.getElementById('op-result').style.display = 'block';
    document.getElementById('op-result-title').textContent = title;
    document.getElementById('op-result-badge').innerHTML  = badgeHtml;
    document.getElementById('op-result-body').innerHTML   = bodyHtml;
    document.getElementById('op-result').scrollIntoView({ behavior: 'smooth', block: 'start' });
}

function postJson(url, body = {}) {
    return fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
        body: JSON.stringify(body)
    }).then(r => r.json());
}

function fmtDiff(comparison) {
    const rows = [
        ['MySQL Tables',     comparison.mysql_tables     || 0],
        ['Supabase Tables',  comparison.supabase_tables  || 0],
        ['Missing in Supabase', (comparison.missing_in_supabase || []).length],
        ['Extra in Supabase',   (comparison.missing_in_mysql    || []).length],
        ['Matched',          (comparison.matched  || []).length],
        ['Modified',         Object.keys(comparison.modified || {}).length],
    ];
    return '<div style="display:grid; grid-template-columns:repeat(3,1fr); gap:0.75rem;">' +
        rows.map(([label, val]) =>
            `<div><div class="dev-stat-label">${label}</div>
             <div class="dev-stat-value" style="font-size:1rem;">${val}</div></div>`
        ).join('') + '</div>' +
        (comparison.drift_summary ? `<div style="margin-top:0.75rem; font-size:0.75rem; color:var(--dev-warn); font-family:var(--mono);">${comparison.drift_summary}</div>` : '');
}

// ── Compare ────────────────────────────────────────────────────────────────

function runCompare() {
    setLoading('btn-compare', true);
    postJson(urls.compare)
        .then(data => {
            const ok = data.success;
            const c  = data.comparison || {};
            showResult(
                'Schema Comparison',
                ok ? '<span class="badge-ok">● Complete</span>' : '<span class="badge-err">✕ Failed</span>',
                ok ? fmtDiff(c) : `<div style="color:var(--dev-danger); font-size:0.8125rem;">${data.error || 'Comparison failed'}</div>`
            );
        })
        .catch(() => showResult('Error', '<span class="badge-err">✕</span>', '<div style="color:var(--dev-danger);">Network error</div>'))
        .finally(() => setLoading('btn-compare', false));
}

// ── Dry Run ────────────────────────────────────────────────────────────────

function runDryRun() {
    setLoading('btn-dry-run', true);
    postJson(urls.dryRun)
        .then(data => {
            const ok = data.success;
            const body = ok
                ? `<div style="display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:0.75rem; margin-bottom:1rem;">
                       <div><div class="dev-stat-label">Tables Affected</div><div class="dev-stat-value" style="font-size:1rem; color:var(--dev-warn);">${data.tables_affected || 0}</div></div>
                       <div><div class="dev-stat-label">Columns Affected</div><div class="dev-stat-value" style="font-size:1rem;">${data.columns_affected || 0}</div></div>
                       <div><div class="dev-stat-label">SQL Statements</div><div class="dev-stat-value" style="font-size:1rem;">${data.sql_statements || 0}</div></div>
                       <div><div class="dev-stat-label">Duration</div><div class="dev-stat-value" style="font-size:1rem;">${data.duration_ms || 0} ms</div></div>
                   </div>
                   <div style="font-size:0.75rem; color:var(--dev-accent2); font-family:var(--mono);">✓ No SQL was executed. This was a simulation only.</div>`
                : `<div style="color:var(--dev-danger);">${data.error || 'Dry run failed'}</div>`;

            showResult('Dry Run Complete',
                ok ? '<span class="badge-warn">Dry Run</span>' : '<span class="badge-err">✕ Failed</span>',
                body
            );

            if (ok && data.ddl_sql) {
                showSqlPreview(data.ddl_sql, data.sql_statements);
            }
        })
        .catch(() => showResult('Error', '<span class="badge-err">✕</span>', '<div style="color:var(--dev-danger);">Network error</div>'))
        .finally(() => setLoading('btn-dry-run', false));
}

// ── SQL Preview ────────────────────────────────────────────────────────────

function runPreview(mode) {
    const btnId = mode === 'full' ? 'btn-preview-full' : 'btn-preview-incr';
    setLoading(btnId, true);
    postJson(urls.preview, { mode })
        .then(data => {
            if (data.success) {
                showSqlPreview(data.sql, data.statements);
                showResult('SQL Preview Generated',
                    '<span class="badge-ok">● Ready</span>',
                    `<div style="font-size:0.8125rem; color:var(--dev-text-muted);">Mode: <span style="font-family:var(--mono); color:var(--dev-accent);">${data.mode}</span> · ${data.statements} statements generated. Review SQL below before executing.</div>`
                );
            } else {
                showResult('Preview Failed', '<span class="badge-err">✕</span>', `<div style="color:var(--dev-danger);">${data.error}</div>`);
            }
        })
        .catch(() => showResult('Error', '<span class="badge-err">✕</span>', '<div style="color:var(--dev-danger);">Network error</div>'))
        .finally(() => setLoading(btnId, false));
}

function showSqlPreview(sql, stmtCount) {
    currentSql = sql;
    document.getElementById('sql-preview-panel').style.display = 'block';
    document.getElementById('sql-preview-content').textContent = sql;
    document.getElementById('sql-stmt-count').textContent = (stmtCount || 0) + ' statements';
}

function copySql() {
    if (currentSql) navigator.clipboard.writeText(currentSql).then(() => alert('SQL copied to clipboard.'));
}

function downloadSql() {
    if (!currentSql) return;
    const blob = new Blob([currentSql], { type: 'text/plain' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'inveetaire_supabase_' + new Date().toISOString().slice(0,19).replace(/:/g,'-') + '.sql';
    a.click();
}

// ── Verify ─────────────────────────────────────────────────────────────────

function runVerify() {
    setLoading('btn-verify', true);
    postJson(urls.verify)
        .then(data => {
            const statusColor = data.status === 'healthy' ? 'var(--dev-accent2)' : (data.status === 'warning' ? 'var(--dev-warn)' : 'var(--dev-danger)');
            const badge = data.status === 'healthy'
                ? '<span class="badge-ok">● Healthy</span>'
                : (data.status === 'warning' ? '<span class="badge-warn">⚠ Warning</span>' : '<span class="badge-err">✕ Error</span>');

            let body = `<div style="margin-bottom:0.75rem; font-weight:700; color:${statusColor};">${data.status_label || data.status}</div>`;
            body += `<div style="display:grid; grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); gap:0.75rem; margin-bottom:1rem;">
                <div><div class="dev-stat-label">MySQL Tables</div><div class="dev-stat-value" style="font-size:1rem;">${data.mysql_tables||0}</div></div>
                <div><div class="dev-stat-label">Supabase Tables</div><div class="dev-stat-value" style="font-size:1rem; color:#3ecf8e;">${data.supabase_tables||0}</div></div>
                <div><div class="dev-stat-label">Missing Tables</div><div class="dev-stat-value" style="font-size:1rem; color:var(--dev-danger);">${(data.missing_tables||[]).length}</div></div>
                <div><div class="dev-stat-label">Column Issues</div><div class="dev-stat-value" style="font-size:1rem; color:var(--dev-warn);">${(data.column_issues||[]).length}</div></div>
            </div>`;

            if ((data.issues||[]).length > 0) {
                body += '<div style="margin-top:0.5rem; font-size:0.75rem; color:var(--dev-danger); font-family:var(--mono);">' +
                    data.issues.slice(0,5).map(i => '• ' + i).join('<br>') + '</div>';
            }

            showResult('Mirror Verification', badge, body);
        })
        .catch(() => showResult('Error', '<span class="badge-err">✕</span>', '<div style="color:var(--dev-danger);">Network error</div>'))
        .finally(() => setLoading('btn-verify', false));
}

// ── Push ───────────────────────────────────────────────────────────────────

function confirmPush(mode) {
    pendingPushMode = mode;
    const isFullMode = mode === 'full';
    document.getElementById('confirm-modal-body').innerHTML =
        `You are about to push the <strong style="color:var(--dev-warn);">${isFullMode ? 'FULL' : 'incremental'}</strong> MySQL schema to Supabase.<br><br>
        ${isFullMode ? '<strong style="color:var(--dev-danger);">Full mode will recreate all tables.</strong> Existing data in Supabase will be lost.<br><br>' : ''}
        This action is <strong>irreversible</strong>. Ensure you have run a Dry Run first.<br><br>
        Type <code style="font-family:var(--mono); color:var(--dev-accent);">confirm</code> to proceed:
        <br><input id="confirm-input" type="text" placeholder="confirm" style="margin-top:0.75rem; width:100%; padding:0.5rem; background:var(--dev-surface2); border:1px solid var(--dev-border); border-radius:4px; color:var(--dev-text); font-family:var(--mono); font-size:0.875rem;">`;

    const modal = document.getElementById('confirm-modal');
    modal.style.display = 'flex';
    document.getElementById('confirm-modal-ok').onclick = executePush;
    setTimeout(() => document.getElementById('confirm-input')?.focus(), 100);
}

function closeModal() {
    document.getElementById('confirm-modal').style.display = 'none';
    pendingPushMode = '';
}

function executePush() {
    const input = document.getElementById('confirm-input');
    if (!input || input.value.trim() !== 'confirm') {
        alert('Please type "confirm" to proceed.');
        return;
    }
    closeModal();

    const btnId = pendingPushMode === 'full' ? 'btn-push-full' : 'btn-push-incr';
    setLoading(btnId, true);

    postJson(urls.push, { confirmed: true, mode: pendingPushMode })
        .then(data => {
            const ok = data.success;
            let body = `<div style="display:grid; grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); gap:0.75rem; margin-bottom:1rem;">
                <div><div class="dev-stat-label">Execution Mode</div><div style="font-family:var(--mono); font-size:0.8125rem; color:var(--dev-accent);">${data.execution_mode||'—'}</div></div>
                <div><div class="dev-stat-label">Tables Affected</div><div class="dev-stat-value" style="font-size:1rem;">${data.tables_affected||0}</div></div>
                <div><div class="dev-stat-label">Statements</div><div class="dev-stat-value" style="font-size:1rem;">${data.sql_statements||0}</div></div>
                <div><div class="dev-stat-label">Duration</div><div class="dev-stat-value" style="font-size:1rem;">${data.duration_ms||0} ms</div></div>
            </div>`;

            if (data.sql_for_download) {
                showSqlPreview(data.sql_for_download, data.sql_statements);
                body += '<div style="font-size:0.8125rem; color:var(--dev-warn); margin-top:0.5rem;">SQL Export Mode: Review and execute the SQL below in your Supabase Dashboard.</div>';
            }
            if (data.error) body += `<div style="color:var(--dev-danger); margin-top:0.5rem; font-size:0.8125rem;">${data.error}</div>`;

            showResult('Push Result',
                ok ? '<span class="badge-ok">● Success</span>' : '<span class="badge-err">✕ Failed</span>',
                body
            );
        })
        .catch(() => showResult('Error', '<span class="badge-err">✕</span>', '<div style="color:var(--dev-danger);">Network error during push.</div>'))
        .finally(() => setLoading(btnId, false));
}

// Close modal on backdrop click
document.getElementById('confirm-modal')?.addEventListener('click', function(e) {
    if (e.target === this) closeModal();
});
</script>
