<?php
// Check if user is authenticated
if (!defined('AUTH_USER')) {
    header('Location: login.php');
    exit();
}

require_once 'libs/CpanelBackupImporter.php';
require_once 'libs/mysqlmgmt.php';

$pageTitle = "cPanel Backup Import";
$currentPage = 'cpanel-import';

// Initialize database connection
$MySQLMgmt = new mysqlmgmt();
$pdo = $MySQLMgmt->getMySQLConnection();

// AJAX requests are handled by /api/cpanel-import-ajax.php

// Look up the sandbox-container execution mode so the intro card can
// describe what actually happens. settings.json is the source of truth
// per reference_whp_settings_storage. Missing key → direct (legacy
// in-process extract). Missing file → direct.
$cpanel_import_mode = 'direct';
$cpanel_import_image = '';
$settings_path = '/docker/whp/settings.json';
if (is_readable($settings_path)) {
    $raw = @file_get_contents($settings_path);
    if (is_string($raw)) {
        $decoded = json_decode($raw, true);
        if (is_array($decoded) && isset($decoded['cpanel_import']) && is_array($decoded['cpanel_import'])) {
            $cpanel_import_mode  = (string) ($decoded['cpanel_import']['execution_mode'] ?? 'direct');
            $cpanel_import_image = (string) ($decoded['cpanel_import']['image'] ?? '');
        }
    }
}
$sandbox_enabled = ($cpanel_import_mode === 'sanitization-container');

// Root-only quick-access lookup. Fetch the most recent import_id of each
// kind so the top toolbar can pre-populate links without the operator
// having to find the row in the History panel + click into it. We do
// these as two cheap indexed lookups rather than re-using the
// list_imports endpoint because the page renders them server-side; an
// extra round-trip would race the page-load JS.
$last_results_id  = null;
$last_selector_id = null;
if (AUTH_USER === 'root') {
    try {
        // Only completed imports have a summary JSON the results page can
        // render — failed imports return 404 from api/cpanel-import-summary.php
        // (no JSON was ever written). Surfacing the failed-row's import_id
        // in the toolbar would land the operator on a 404.
        $stmt = $pdo->prepare("
            SELECT import_id FROM whp.cpanel_imports
            WHERE status = 'completed'
            ORDER BY id DESC LIMIT 1
        ");
        $stmt->execute();
        $last_results_id = $stmt->fetchColumn() ?: null;

        $stmt = $pdo->prepare("
            SELECT import_id FROM whp.cpanel_imports
            WHERE status = 'awaiting_selection'
            ORDER BY id DESC LIMIT 1
        ");
        $stmt->execute();
        $last_selector_id = $stmt->fetchColumn() ?: null;
    } catch (PDOException $e) {
        // Best-effort — if the lookup fails the toolbar just renders
        // without those buttons; the History panel below still works.
        error_log('cpanel-import toolbar lookup failed: ' . $e->getMessage());
    }
}

?>

<!-- cPanel Backup Import Content -->
<div class="container-fluid">
        <div class="row">
            <div class="col-12">
                <?php if (AUTH_USER === 'root' && ($last_results_id || $last_selector_id)): ?>
                <!-- Quick-access toolbar (root only). import_ids are
                     server-side-resolved at page load so a fresh navigation
                     here surfaces the most recent eligible row without
                     waiting on the History-panel AJAX. -->
                <div class="d-flex align-items-center gap-2 mb-3 flex-wrap">
                    <span class="text-muted small me-2">Quick links:</span>
                    <?php if ($last_results_id): ?>
                    <a href="?page=cpanel-import-results&import_id=<?= htmlspecialchars(urlencode($last_results_id)) ?>"
                       class="btn btn-sm btn-outline-primary">
                        <i class="bi bi-file-earmark-text"></i> View Last Results
                        <span class="text-muted ms-1" style="font-family: monospace; font-size: 0.85em;">
                            <?= htmlspecialchars($last_results_id) ?>
                        </span>
                    </a>
                    <?php endif; ?>
                    <?php if ($last_selector_id): ?>
                    <a href="?page=cpanel-import-selector&import_id=<?= htmlspecialchars(urlencode($last_selector_id)) ?>"
                       class="btn btn-sm btn-outline-warning">
                        <i class="bi bi-funnel"></i> Resume Selection
                        <span class="text-muted ms-1" style="font-family: monospace; font-size: 0.85em;">
                            <?= htmlspecialchars($last_selector_id) ?>
                        </span>
                    </a>
                    <?php endif; ?>
                </div>
                <?php endif; ?>

                <!-- How cPanel import works (mode-aware) -->
                <div class="alert alert-info">
                    <div class="d-flex justify-content-between align-items-start flex-wrap gap-2">
                        <div class="flex-grow-1">
                            <h6 class="mb-1"><i class="bi bi-info-circle"></i> How cPanel import works</h6>
                            <p class="mb-0 small">
                                <?php if ($sandbox_enabled): ?>
                                Your cpmove backup is extracted and scanned in an isolated sandbox container before WHP imports anything.
                                ClamAV scans every file; dangerous symlinks are stripped; databases are converted to InnoDB.
                                <?php else: ?>
                                Your cpmove backup is extracted in-process by the import worker. The sanitization sandbox is currently <strong>disabled</strong> in
                                <a href="?page=server-settings#cpanel-import" class="alert-link">Server Settings → Security</a> — only the existing pre-extract symlink scan runs.
                                <?php endif; ?>
                                You'll then pick which sites to import; the worker creates sites, restores files, imports databases with new credentials, replays grants, sets up DNS, and provisions containers.
                            </p>
                        </div>
                        <button class="btn btn-sm btn-outline-secondary" type="button"
                                data-bs-toggle="collapse" data-bs-target="#cpanel-import-intro-details" aria-expanded="false">
                            <i class="bi bi-list-ul"></i> Details
                        </button>
                    </div>
                    <div class="collapse mt-3" id="cpanel-import-intro-details">
                        <hr class="my-2">
                        <div class="row small">
                            <div class="col-md-6">
                                <h6 class="mb-1"><i class="bi bi-1-circle"></i> Analyze pass</h6>
                                <ul class="mb-3">
                                    <li>cpmove tarball moved to scratch space</li>
                                    <?php if ($sandbox_enabled): ?>
                                    <li>Sanitization container spawned (sandboxed: cap-drop=ALL, read-only rootfs, network=none, --user 999)</li>
                                    <li>Pre-extract symlink scan classifies entries — any target at <code>/</code>, <code>/etc</code>, <code>/root</code>, <code>/boot</code>, <code>/proc</code>, <code>/sys</code>, or <code>/dev</code> is stripped via <code>tar --exclude</code> (typical webshell payload pattern)</li>
                                    <li>Files extracted with hardened tar flags; mail tree (<code>homedir/mail/</code>) excluded — WHP does not import cPanel mailboxes</li>
                                    <li>ClamAV scans every extracted file — infected files are quarantined to <code>/docker/whp/cpanel-importer-quarantine/</code></li>
                                    <li>MySQL dumps engine-swapped MyISAM → InnoDB; WordPress content scanned for compromise signatures</li>
                                    <?php else: ?>
                                    <li>Pre-extract symlink scan — DANGEROUS entries (targets under system roots) refuse the tarball before extraction</li>
                                    <li>Files extracted with hardened tar flags directly by the panel worker</li>
                                    <?php endif; ?>
                                    <li>userdata, addons, parked domains, subdomains, MySQL grants, mailbox counts parsed</li>
                                    <li>Manifest written; you're shown the site-group selector</li>
                                </ul>
                                <h6 class="mb-1"><i class="bi bi-2-circle"></i> Selection</h6>
                                <ul class="mb-3">
                                    <li>You pick which sites to import; addon domains land with their real public domain as primary (e.g. <code>&lt;addon&gt;.com</code>, not the cPanel-internal alias subdomain <code>&lt;addon&gt;.&lt;main-domain&gt;.tld</code>)</li>
                                    <li>Parked domains are attached to the main domain's site as additional domains</li>
                                </ul>
                            </div>
                            <div class="col-md-6">
                                <h6 class="mb-1"><i class="bi bi-3-circle"></i> Resume pass (the actual import)</h6>
                                <ul class="mb-3">
                                    <li>WHP sites created with their additional domains, container types matched to the cPanel PHP version</li>
                                    <li>Site files synced into <code>/docker/users/&lt;user&gt;/</code></li>
                                    <li>Databases created in MySQL; users created with <strong>new auto-generated passwords</strong>; grants replayed against the renamed databases</li>
                                    <li>WordPress <code>wp-config.php</code> files rewritten in place with the new DB credentials</li>
                                    <li>DNS zones created in PowerDNS; sites provisioned in containers</li>
                                    <li>Summary email sent with new database credentials for any non-WordPress applications you'll need to reconnect manually (Drupal, custom apps, etc.) — temp passwords expire after 24h</li>
                                </ul>
                                <h6 class="mb-1"><i class="bi bi-shield-check"></i> What's not imported</h6>
                                <ul class="mb-3">
                                    <li><strong>Email accounts and mailbox content</strong> — handled separately (panel-side, not via cpmove)</li>
                                    <li>HAProxy-side rate-limit overrides and cPanel-specific config</li>
                                    <li>Quarantined files — left in <code>/docker/whp/cpanel-importer-quarantine/&lt;import_id&gt;/</code> for review; swept after 90 days per the retention setting</li>
                                </ul>
                                <h6 class="mb-1"><i class="bi bi-person-check"></i> Best practice: match the username</h6>
                                <p class="mb-0">
                                    For the cleanest import, create the WHP user with the <strong>same username as the cPanel account</strong> before starting. cPanel docroots are stored as <code>/home/&lt;cpuser&gt;/&lt;rest&gt;</code>; if the WHP target user matches, in-container paths line up cleanly with no rewriting needed. When the usernames differ, the importer rewrites <code>/home/&lt;cpuser&gt;/</code> to <code>/home/&lt;whpuser&gt;/</code> across PHP/INI/conf/htaccess files and SQL dumps — but anything embedded in serialized binary data, base64 blobs, or third-party caches the rewriter doesn't recognize will need manual fix-up.
                                </p>
                            </div>
                        </div>
                        <div class="mt-3 text-muted small">
                            <i class="bi bi-bug"></i> Found something off? Use the <strong>Import History</strong> panel below to view past runs, or open a ticket with the import_id.
                        </div>
                    </div>
                </div>
                
                <?php if (AUTH_USER === 'root'): ?>
                <!-- Root User - Target User Selection -->
                <div class="alert alert-info">
                    <h6><i class="bi bi-person-gear"></i> Root User - Import for Another User</h6>
                    <div class="mb-3">
                        <label for="target_user_select" class="form-label">Select Target User</label>
                        <select class="form-select" id="target_user_select" required>
                            <option value="">Loading users...</option>
                        </select>
                        <div class="form-text">Select the user account to import the cPanel backup into.</div>
                    </div>
                </div>

                <!-- Import History (root only) -->
                <div class="card mb-3" id="import-history-card">
                    <div class="card-header d-flex justify-content-between align-items-center">
                        <div>
                            <i class="bi bi-clock-history"></i>
                            <strong>Import History</strong>
                            <span class="badge bg-secondary ms-2" id="import-history-count">…</span>
                        </div>
                        <div>
                            <button type="button" class="btn btn-sm btn-outline-secondary" id="import-history-refresh">
                                <i class="bi bi-arrow-clockwise"></i> Refresh
                            </button>
                            <button type="button" class="btn btn-sm btn-outline-secondary"
                                    data-bs-toggle="collapse" data-bs-target="#import-history-body" aria-expanded="false">
                                Show / Hide
                            </button>
                        </div>
                    </div>
                    <div class="collapse" id="import-history-body">
                        <div class="table-responsive">
                            <table class="table table-sm table-hover mb-0 align-middle">
                                <thead>
                                    <tr>
                                        <th>User</th>
                                        <th>Status</th>
                                        <th>Progress</th>
                                        <th>Backup file</th>
                                        <th>Created</th>
                                        <th>Disk</th>
                                        <th class="text-end">Actions</th>
                                    </tr>
                                </thead>
                                <tbody id="import-history-rows">
                                    <tr><td colspan="7" class="text-center text-muted">Loading…</td></tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                <?php endif; ?>
            </div>
        </div>

        <!-- Import Steps -->
        <div class="row mb-4">
            <div class="col-12">
                <div class="card">
                    <div class="card-header">
                        <h5 class="mb-0">Import Process</h5>
                    </div>
                    <div class="card-body">
                        <div class="row">
                            <div class="col-md-3">
                                <div class="text-center">
                                    <div class="bg-primary text-white rounded-circle d-inline-flex align-items-center justify-content-center" 
                                         style="width: 40px; height: 40px;">
                                        <span>1</span>
                                    </div>
                                    <p class="mt-2 mb-0">Upload Backup</p>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="text-center">
                                    <div class="bg-secondary text-white rounded-circle d-inline-flex align-items-center justify-content-center" 
                                         style="width: 40px; height: 40px;" id="step2">
                                        <span>2</span>
                                    </div>
                                    <p class="mt-2 mb-0">Analyze Backup</p>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="text-center">
                                    <div class="bg-secondary text-white rounded-circle d-inline-flex align-items-center justify-content-center" 
                                         style="width: 40px; height: 40px;" id="step3">
                                        <span>3</span>
                                    </div>
                                    <p class="mt-2 mb-0">Import Data</p>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="text-center">
                                    <div class="bg-secondary text-white rounded-circle d-inline-flex align-items-center justify-content-center" 
                                         style="width: 40px; height: 40px;" id="step4">
                                        <span>4</span>
                                    </div>
                                    <p class="mt-2 mb-0">Complete</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Backup Selection Form -->
        <div class="row" id="selection-section">
            <div class="col-12">
                <div class="card">
                    <div class="card-header">
                        <h5 class="mb-0">Step 1: Select cPanel Backup File</h5>
                    </div>
                    <div class="card-body">
                        <div class="alert alert-info">
                            <h6><i class="bi bi-info-circle"></i> Upload Instructions</h6>
                            <p><strong>Before using this tool:</strong></p>
                            <ol class="mb-2">
                                <?php if (AUTH_USER === 'root'): ?>
                                <li>Select the target user account above</li>
                                <li>Upload the cPanel backup (.tar.gz or .tgz) file to the user's <strong>userfiles</strong> directory</li>
                                <li>You can access userfiles through the File Manager or FTP at: <code>/userfiles/</code> for each user</li>
                                <li>Once uploaded, the backup files will appear in the dropdown below</li>
                                <?php else: ?>
                                <li>Upload your cPanel backup (.tar.gz or .tgz) file to your <strong>userfiles</strong> directory</li>
                                <li>You can access userfiles through the File Manager or FTP at: <code>/userfiles/</code></li>
                                <li>Once uploaded, refresh this page and select your backup file below</li>
                                <?php endif; ?>
                            </ol>
                            <p class="mb-0"><strong>This tool will import:</strong> Domains, website files, MySQL databases, and create DNS records. SSL certificates are handled automatically by our system.</p>
                        </div>

                        <div id="backup-files-container">
                            <div class="mb-3">
                                <label for="backup_file_select" class="form-label">Available Backup Files</label>
                                <select class="form-select" id="backup_file_select" required>
                                    <option value="">Loading backup files...</option>
                                </select>
                                <div class="form-text text-muted">
                                    Backup files from your userfiles directory.
                                    <button type="button" class="btn btn-link btn-sm p-0" onclick="refreshBackupFiles()">
                                        <i class="bi bi-arrow-clockwise"></i> Refresh List
                                    </button>
                                </div>
                            </div>
                            
                            <div id="selected-backup-info" class="alert alert-secondary" style="display: none;">
                                <h6>Selected Backup:</h6>
                                <div id="backup-details"></div>
                            </div>

                            <div class="form-check mb-2">
                                <input class="form-check-input" type="checkbox" id="email_summary_enabled" checked>
                                <label class="form-check-label" for="email_summary_enabled">
                                    Email me a copy of the import summary when this finishes (recommended for long imports)
                                </label>
                            </div>
                            <div class="mb-3" id="email_summary_to_wrapper">
                                <label for="email_summary_to" class="form-label">Send to (email)</label>
                                <input type="email" class="form-control" id="email_summary_to" placeholder="ops@example.com" required>
                            </div>

                            <!-- Advanced toggle: bypass the analyze-and-select step and run the legacy
                                 end-to-end import. Default OFF (operator gets the selector). This
                                 matches the WHMCS / headless skip_selection=1 codepath; operators
                                 who want fire-and-forget can flip it here. -->
                            <div class="form-check form-switch mb-3">
                                <input class="form-check-input" type="checkbox" id="skip_selection">
                                <label class="form-check-label" for="skip_selection">
                                    <strong>Advanced:</strong> import every site group automatically — skip the analyze and select step
                                </label>
                                <div class="form-text">
                                    Recommended for clean migrations of small accounts, or for re-imports of a known cpmove. Leave off if you want to opt out of specific site groups.
                                </div>
                            </div>

                            <button type="button" class="btn btn-primary" id="select-backup-btn" disabled>
                                <i class="bi bi-check-circle"></i> Analyze Backup
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Import Progress -->
        <div class="row" id="import-section" style="display: none;">
            <div class="col-12">
                <div class="card">
                    <div class="card-header">
                        <h5 class="mb-0">Import Progress</h5>
                    </div>
                    <div class="card-body">
                        <div class="mb-3">
                            <div class="progress">
                                <div class="progress-bar progress-bar-striped progress-bar-animated" 
                                     id="import-progress" role="progressbar" style="width: 0%"></div>
                            </div>
                        </div>
                        
                        <div id="import-status" class="mb-3">
                            <span class="badge bg-primary">Starting Import...</span>
                        </div>
                        
                        <div class="card">
                            <div class="card-header">
                                <h6 class="mb-0">Import Log</h6>
                            </div>
                            <div class="card-body" style="max-height: 300px; overflow-y: auto;">
                                <pre id="import-log" class="mb-0"></pre>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Import Results -->
        <div class="row" id="results-section" style="display: none;">
            <div class="col-12">
                <div class="card">
                    <div class="card-header">
                        <h5 class="mb-0">Import Complete</h5>
                    </div>
                    <div class="card-body">
                        <div class="alert alert-success">
                            <h6><i class="bi bi-check-circle"></i> Import Successful!</h6>
                            <div id="import-summary"></div>
                        </div>
                        
                        <div class="d-flex gap-2">
                            <a href="?page=sites" class="btn btn-primary">
                                <i class="bi bi-globe"></i> View Sites
                            </a>
                            <a href="?page=dashboard" class="btn btn-outline-secondary">
                                <i class="bi bi-house"></i> Dashboard
                            </a>
                            <button type="button" class="btn btn-outline-primary" onclick="startNewImport()">
                                <i class="bi bi-upload"></i> Import Another Backup
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        const nonce = '<?php echo get_csrf_token(); ?>';
        let currentImportId = null;
        let statusCheckInterval = null;
        let availableBackups = [];

        // Load backup files on page load. If we arrived with ?import_id=...
        // (the selector page redirects here after confirm_selection so the
        // resume pass's progress is visible), skip the backup-picker UI
        // entirely and attach the poller directly to that import.
        document.addEventListener('DOMContentLoaded', function() {
            const urlParams = new URLSearchParams(window.location.search);
            const resumeId = urlParams.get('import_id');
            if (resumeId && /^import_[A-Za-z0-9.]+$/.test(resumeId)) {
                currentImportId = resumeId;
                document.getElementById('selection-section').style.display = 'none';
                document.getElementById('import-section').style.display = 'block';
                updateStepIndicator(3);
                startStatusChecking();
                return;
            }

            <?php if (AUTH_USER === 'root'): ?>
            // For root, load users first, then backup files will load when user is selected
            loadUsers();
            // Hydrate the Import History panel + wire its refresh/delete handlers.
            loadImportHistory();
            const refreshBtn = document.getElementById('import-history-refresh');
            if (refreshBtn) refreshBtn.addEventListener('click', loadImportHistory);
            <?php else: ?>
            // For regular users, load backup files immediately
            refreshBackupFiles();
            <?php endif; ?>
        });

        <?php if (AUTH_USER === 'root'): ?>
        // Import History panel — root-only listing of every cpanel_imports
        // row with a per-row Delete affordance. Drives list_imports +
        // delete_import on the AJAX endpoint.
        async function loadImportHistory() {
            const tbody = document.getElementById('import-history-rows');
            const countBadge = document.getElementById('import-history-count');
            if (!tbody) return;
            tbody.replaceChildren();
            tbody.insertAdjacentHTML('beforeend',
                '<tr><td colspan="7" class="text-center text-muted">Loading…</td></tr>');
            try {
                const r = await fetch('/api/cpanel-import-ajax.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'X-CSRF-Token': nonce,
                    },
                    body: new URLSearchParams({action: 'list_imports'}),
                });
                const data = await r.json();
                if (!data.success) {
                    tbody.replaceChildren();
                    tbody.insertAdjacentHTML('beforeend',
                        '<tr><td colspan="7" class="text-danger text-center">' +
                        (data.error || 'Failed to load history') + '</td></tr>');
                    return;
                }
                const imports = Array.isArray(data.imports) ? data.imports : [];
                countBadge.textContent = String(imports.length);
                tbody.replaceChildren();
                if (!imports.length) {
                    tbody.insertAdjacentHTML('beforeend',
                        '<tr><td colspan="7" class="text-center text-muted">No imports recorded.</td></tr>');
                    return;
                }
                for (const imp of imports) {
                    tbody.appendChild(renderImportHistoryRow(imp));
                }
            } catch (e) {
                tbody.replaceChildren();
                tbody.insertAdjacentHTML('beforeend',
                    '<tr><td colspan="7" class="text-danger text-center">Network error: ' +
                    String(e.message || e) + '</td></tr>');
            }
        }

        function renderImportHistoryRow(imp) {
            const tr = document.createElement('tr');

            // User
            const userTd = document.createElement('td');
            userTd.textContent = imp.username || '–';
            tr.appendChild(userTd);

            // Status badge
            const statusTd = document.createElement('td');
            const badge = document.createElement('span');
            const status = String(imp.status || '');
            badge.className = 'badge ' + ({
                completed: 'bg-success',
                failed: 'bg-danger',
                running: 'bg-primary',
                awaiting_selection: 'bg-warning text-dark',
                pending: 'bg-secondary',
            }[status] || 'bg-secondary');
            badge.textContent = status.toUpperCase();
            statusTd.appendChild(badge);
            tr.appendChild(statusTd);

            // Progress
            const progTd = document.createElement('td');
            progTd.textContent = (imp.progress == null ? '–' : (imp.progress + '%'));
            tr.appendChild(progTd);

            // Backup file (basename only — full paths are noisy)
            const fileTd = document.createElement('td');
            const fname = (imp.backup_file || '').split('/').pop() || '–';
            fileTd.textContent = fname;
            fileTd.style.maxWidth = '280px';
            fileTd.style.overflow = 'hidden';
            fileTd.style.textOverflow = 'ellipsis';
            fileTd.style.whiteSpace = 'nowrap';
            fileTd.title = imp.backup_file || '';
            tr.appendChild(fileTd);

            // Created (relative)
            const createdTd = document.createElement('td');
            createdTd.textContent = imp.created_at || '–';
            createdTd.style.fontSize = '0.85em';
            createdTd.style.fontFamily = 'monospace';
            tr.appendChild(createdTd);

            // Disk usage
            const diskTd = document.createElement('td');
            diskTd.textContent = formatBytes(imp.disk_bytes || 0);
            tr.appendChild(diskTd);

            // Actions
            const actionsTd = document.createElement('td');
            actionsTd.className = 'text-end';
            // Per-status routing:
            //   completed          → results page (summary JSON exists)
            //   failed             → import page with import_id (live-progress UI
            //                        attaches the poller, log buffer renders the
            //                        failure trail — the results page itself 404s
            //                        for failed because no summary was ever written)
            //   awaiting_selection → selector page (resume the analyze flow)
            //   running            → import page with import_id (live poll)
            //   anything else      → no link button (delete only)
            if (status === 'completed') {
                const a = document.createElement('a');
                a.href = '?page=cpanel-import-results&import_id=' + encodeURIComponent(imp.import_id);
                a.className = 'btn btn-sm btn-outline-primary me-1';
                a.textContent = 'View';
                actionsTd.appendChild(a);
            } else if (status === 'awaiting_selection') {
                const a = document.createElement('a');
                a.href = '?page=cpanel-import-selector&import_id=' + encodeURIComponent(imp.import_id);
                a.className = 'btn btn-sm btn-outline-warning me-1';
                a.textContent = 'Resume';
                actionsTd.appendChild(a);
            } else if (status === 'failed' || status === 'running') {
                const a = document.createElement('a');
                a.href = '?page=cpanel-import&import_id=' + encodeURIComponent(imp.import_id);
                a.className = 'btn btn-sm btn-outline-info me-1';
                a.textContent = (status === 'running') ? 'Watch' : 'Log';
                actionsTd.appendChild(a);
            }
            // Delete button
            const delBtn = document.createElement('button');
            delBtn.type = 'button';
            delBtn.className = 'btn btn-sm btn-outline-danger';
            delBtn.textContent = 'Delete';
            delBtn.addEventListener('click', () => deleteImportRow(imp));
            actionsTd.appendChild(delBtn);
            tr.appendChild(actionsTd);

            return tr;
        }

        async function deleteImportRow(imp) {
            const importId = imp.import_id;
            const human = `${imp.username || '?'} — ${importId} (${imp.status})`;
            if (!confirm(
                `Delete this import?\n\n${human}\n\nAll on-disk artifacts (extract/quarantine trees, manifest, summary) will be removed and the row dropped from cpanel_imports. This is not reversible.`
            )) return;
            try {
                const r = await fetch('/api/cpanel-import-ajax.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'X-CSRF-Token': nonce,
                    },
                    body: new URLSearchParams({action: 'delete_import', import_id: importId}),
                });
                const data = await r.json();
                if (!data.success) {
                    alert('Delete failed: ' + (data.error || 'unknown'));
                    return;
                }
                // Surface a non-blocking summary then refresh the table.
                const msgParts = [];
                if (data.dirs_removed)  msgParts.push(`${data.dirs_removed} dir(s)`);
                if (data.files_removed) msgParts.push(`${data.files_removed} file(s)`);
                if (data.db_rows)       msgParts.push(`${data.db_rows} DB row(s)`);
                const summary = msgParts.length ? msgParts.join(', ') : 'nothing on disk';
                if (data.errors && data.errors.length) {
                    alert(`Deleted (with warnings: ${data.errors.join('; ')}). Removed: ${summary}`);
                } else {
                    // Brief inline feedback; the row will vanish on refresh.
                    console.log(`Removed: ${summary}`);
                }
                loadImportHistory();
            } catch (e) {
                alert('Network error: ' + String(e.message || e));
            }
        }

        function formatBytes(b) {
            if (!b) return '–';
            const units = ['B','KB','MB','GB','TB'];
            let i = 0;
            while (b >= 1024 && i < units.length - 1) { b /= 1024; i++; }
            return b.toFixed(b < 10 && i > 0 ? 1 : 0) + ' ' + units[i];
        }
        <?php endif; ?>

        <?php if (AUTH_USER === 'root'): ?>
        // Load users for root user
        async function loadUsers() {
            try {
                const response = await fetch('/api/cpanel-import-ajax.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'X-CSRF-Token': nonce
                    },
                    body: new URLSearchParams({
                        action: 'list_users'
                    })
                });

                const result = await response.json();
                const userSelect = document.getElementById('target_user_select');

                if (result.success) {
                    userSelect.innerHTML = '<option value="">Select a user...</option>';
                    result.users.forEach(user => {
                        const option = document.createElement('option');
                        option.value = user;
                        option.textContent = user;
                        userSelect.appendChild(option);
                    });
                    
                    // Add event listener to refresh backup files when user changes
                    userSelect.addEventListener('change', function() {
                        if (this.value) {
                            refreshBackupFiles();
                        } else {
                            // Clear backup files if no user selected
                            const backupSelect = document.getElementById('backup_file_select');
                            backupSelect.innerHTML = '<option value="">Select a user first</option>';
                            document.getElementById('select-backup-btn').disabled = true;
                        }
                    });
                } else {
                    userSelect.innerHTML = '<option value="">Failed to load users</option>';
                }
            } catch (error) {
                console.error('Failed to load users:', error);
                document.getElementById('target_user_select').innerHTML = '<option value="">Error loading users</option>';
            }
        }
        <?php endif; ?>

        // Refresh backup files list
        async function refreshBackupFiles() {
            try {
                const params = {
                    action: 'get_backup_files'
                };
                
                <?php if (AUTH_USER === 'root'): ?>
                // For root, include the selected target user
                const targetUserSelect = document.getElementById('target_user_select');
                if (targetUserSelect && targetUserSelect.value) {
                    params.target_user = targetUserSelect.value;
                } else if (targetUserSelect && !targetUserSelect.value) {
                    // No user selected yet, show message
                    const backupSelect = document.getElementById('backup_file_select');
                    backupSelect.innerHTML = '<option value="">Select a user first</option>';
                    return;
                }
                <?php endif; ?>
                
                const response = await fetch('/api/cpanel-import-ajax.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'X-CSRF-Token': nonce
                    },
                    body: new URLSearchParams(params)
                });

                const result = await response.json();
                
                if (result.success) {
                    availableBackups = result.files;
                    updateBackupFilesList();
                } else {
                    console.error('Failed to load backup files:', result.error);
                    updateBackupFilesList([]);
                }
            } catch (error) {
                console.error('Error loading backup files:', error);
                updateBackupFilesList([]);
            }
        }

        // Update the backup files dropdown
        function updateBackupFilesList() {
            const select = document.getElementById('backup_file_select');
            select.innerHTML = '';

            if (availableBackups.length === 0) {
                select.innerHTML = '<option value="">No backup files found in userfiles directory</option>';
                document.getElementById('select-backup-btn').disabled = true;
            } else {
                select.innerHTML = '<option value="">Select a backup file...</option>';
                
                availableBackups.forEach(backup => {
                    const option = document.createElement('option');
                    option.value = backup.filename;
                    option.textContent = `${backup.filename} (${formatFileSize(backup.size)} - ${formatDate(backup.modified)})`;
                    select.appendChild(option);
                });
            }
        }

        // Handle backup file selection
        document.getElementById('backup_file_select').addEventListener('change', function() {
            const selectedFilename = this.value;
            const selectedBackup = availableBackups.find(b => b.filename === selectedFilename);

            if (selectedBackup) {
                // Show backup details
                const detailsDiv = document.getElementById('backup-details');
                detailsDiv.innerHTML = `
                    <strong>File:</strong> ${selectedBackup.filename}<br>
                    <strong>Size:</strong> ${formatFileSize(selectedBackup.size)}<br>
                    <strong>Modified:</strong> ${formatDate(selectedBackup.modified)}
                `;
                document.getElementById('selected-backup-info').style.display = 'block';
                document.getElementById('select-backup-btn').disabled = false;
                // Re-evaluate the username-match warning when the operator
                // picks a different backup file.
                evaluateUsernameMatch();
            } else {
                document.getElementById('selected-backup-info').style.display = 'none';
                document.getElementById('select-backup-btn').disabled = true;
                clearUsernameMatchWarning();
            }
        });

        // Parse cpanel username from a cpmove filename. Standard cPanel
        // backup tar naming is cpmove-<cpuser>.tar.gz; cPanel also ships
        // backups named backup-MM-DD-YYYY_<cpuser>.tar.gz for the legacy
        // wraith-style format. Return '' if the filename doesn't match a
        // known pattern (operator just renamed the file, etc.).
        function parseCpanelUsernameFromFilename(filename) {
            if (!filename) return '';
            let m = filename.match(/^cpmove-([a-z_][a-z0-9_-]*)\.tar(\.gz|\.bz2|\.xz)?$/i);
            if (m) return m[1];
            m = filename.match(/^backup-\d+-\d+-\d+_([a-z_][a-z0-9_-]*)\.tar(\.gz|\.bz2|\.xz)?$/i);
            if (m) return m[1];
            return '';
        }

        function clearUsernameMatchWarning() {
            const el = document.getElementById('username-match-warning');
            if (el) el.remove();
        }

        function evaluateUsernameMatch() {
            clearUsernameMatchWarning();
            const selectedFilename = document.getElementById('backup_file_select').value;
            const cpUser = parseCpanelUsernameFromFilename(selectedFilename);
            if (!cpUser) return;

            // Determine target WHP user. For root, it's the target_user_select
            // value; for non-root, AUTH_USER itself is the target.
            let targetUser = '';
            const targetSelect = document.getElementById('target_user_select');
            if (targetSelect) {
                targetUser = targetSelect.value;
            } else {
                targetUser = <?= json_encode(AUTH_USER) ?>;
            }
            if (!targetUser) return; // operator hasn't picked yet

            if (cpUser === targetUser) return; // matches — no warning

            // Mismatch. Render a non-blocking warning above the backup info.
            const warning = document.createElement('div');
            warning.id = 'username-match-warning';
            warning.className = 'alert alert-warning mt-2';
            warning.innerHTML =
                '<strong><i class="bi bi-exclamation-triangle"></i> Username mismatch.</strong> ' +
                'The backup was created for cPanel user <code>' + cpUser + '</code> but you\'re importing to WHP user <code>' + targetUser + '</code>. ' +
                'The import will continue and rewrite hardcoded <code>/home/' + cpUser + '/</code> references to <code>/home/' + targetUser + '/</code> inside imported files and SQL dumps, ' +
                'but matching usernames is the most reliable path — anything that ends up with a path embedded in a binary blob, a base64 chunk, ' +
                'or a serialized length the rewriter can\'t recompute will need manual fix-up after import.';
            const detailsDiv = document.getElementById('selected-backup-info');
            if (detailsDiv) detailsDiv.appendChild(warning);
        }

        <?php if (AUTH_USER === 'root'): ?>
        // Re-evaluate when root picks a different target user too.
        document.getElementById('target_user_select').addEventListener('change', evaluateUsernameMatch);
        <?php endif; ?>

        // Handle backup selection confirmation
        document.getElementById('select-backup-btn').addEventListener('click', async function() {
            const selectedFilename = document.getElementById('backup_file_select').value;
            
            if (!selectedFilename) {
                alert('Please select a backup file');
                return;
            }

            try {
                const wantEmail = document.getElementById('email_summary_enabled').checked;
                const emailTo = document.getElementById('email_summary_to').value.trim();
                if (wantEmail && !emailTo.match(/^[^@\s]+@[^@\s]+\.[^@\s]+$/)) {
                    alert('Please provide a valid email address, or uncheck "Email me a copy".');
                    document.getElementById('email_summary_to').focus();
                    return;
                }

                const params = {
                    action: 'select_backup',
                    backup_file: selectedFilename,
                    nonce: nonce
                };

                <?php if (AUTH_USER === 'root'): ?>
                // Root impersonates another user — backup lives in that user's userfiles dir.
                const targetUserSelect = document.getElementById('target_user_select');
                if (!targetUserSelect.value) {
                    alert('Please select a target user before choosing a backup');
                    return;
                }
                params.target_user = targetUserSelect.value;
                <?php endif; ?>

                const response = await fetch('/api/cpanel-import-ajax.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'X-CSRF-Token': nonce
                    },
                    body: new URLSearchParams(params)
                });

                const result = await response.json();

                if (result.success) {
                    // Update step indicator
                    updateStepIndicator(2);

                    // Start import
                    startImport(result.path, wantEmail ? emailTo : null);
                } else {
                    alert('Failed to select backup: ' + result.error);
                }
            } catch (error) {
                alert('Failed to select backup: ' + error.message);
            }
        });

        async function startImport(backupFilePath, emailSummaryTo) {
            <?php if (AUTH_USER === 'root'): ?>
            // Check if target user is selected for root
            const targetUserSelect = document.getElementById('target_user_select');
            if (!targetUserSelect.value) {
                alert('Please select a target user for the import');
                return;
            }
            <?php endif; ?>

            try {
                const params = {
                    action: 'start_import',
                    backup_file: backupFilePath
                };
                if (emailSummaryTo) params.email_summary_to = emailSummaryTo;
                // skip_selection=1 bypasses the analyze step and runs the
                // legacy end-to-end fire-and-forget import. Toggled via the
                // "Advanced" switch on the form (off by default).
                const skipEl = document.getElementById('skip_selection');
                if (skipEl && skipEl.checked) params.skip_selection = '1';

                <?php if (AUTH_USER === 'root'): ?>
                params.target_user = targetUserSelect.value;
                <?php endif; ?>
                
                const response = await fetch('/api/cpanel-import-ajax.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'X-CSRF-Token': nonce
                    },
                    body: new URLSearchParams(params)
                });

                const result = await response.json();

                if (result.success) {
                    currentImportId = result.import_id;
                    
                    // Hide selection section and show import progress
                    document.getElementById('selection-section').style.display = 'none';
                    document.getElementById('import-section').style.display = 'block';
                    
                    // Update step indicator
                    updateStepIndicator(3);
                    
                    // Start status checking
                    startStatusChecking();
                } else {
                    alert('Failed to start import: ' + result.error);
                }
            } catch (error) {
                alert('Failed to start import: ' + error.message);
            }
        }

        function startStatusChecking() {
            statusCheckInterval = setInterval(checkImportStatus, 2000);
            checkImportStatus(); // Check immediately
        }

        async function checkImportStatus() {
            if (!currentImportId) return;

            try {
                const response = await fetch('/api/cpanel-import-ajax.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'X-CSRF-Token': nonce
                    },
                    body: new URLSearchParams({
                        action: 'get_import_status',
                        import_id: currentImportId
                    })
                });

                const result = await response.json();

                if (result.success) {
                    updateImportProgress(result);

                    if (result.status === 'completed') {
                        clearInterval(statusCheckInterval);
                        window.location.href = '?page=cpanel-import-results&import_id=' + encodeURIComponent(currentImportId);
                    } else if (result.status === 'failed') {
                        clearInterval(statusCheckInterval);
                        showImportError(result.error);
                    } else if (result.status === 'awaiting_selection') {
                        // Analyze pass is complete — the worker dropped the
                        // manifest at /var/lib/whp/cpanel-imports/<id>.manifest.json
                        // and flipped status. Hand control off to the
                        // selector page; it will POST the operator's pick
                        // back to confirm_selection which kicks off the
                        // resume pass and brings us back here.
                        clearInterval(statusCheckInterval);
                        window.location.href = '?page=cpanel-import-selector&import_id=' + encodeURIComponent(currentImportId);
                    }
                } else {
                    // Surface a polling error in-page instead of swallowing it.
                    // Silent-fail here is what hid the "Import not found"
                    // scoping bug for root-driven target_user imports.
                    const statusDiv = document.getElementById('import-status');
                    if (statusDiv) {
                        const badge = document.createElement('span');
                        badge.className = 'badge bg-warning';
                        badge.textContent = 'Status polling: ' + (result.error || 'unknown error');
                        statusDiv.replaceChildren(badge);
                    }
                    console.warn('checkImportStatus non-success:', result);
                }
            } catch (error) {
                console.error('Failed to check import status:', error);
            }
        }

        function updateImportProgress(status) {
            const progressBar = document.getElementById('import-progress');
            const statusDiv = document.getElementById('import-status');
            const logDiv = document.getElementById('import-log');

            // Update progress bar
            progressBar.style.width = (status.progress || 0) + '%';

            // Update status. The two-phase flow introduces an
            // 'awaiting_selection' state — surface it with a different
            // label and colour so the operator understands it's not the
            // standard 'running' (and so the page is about to redirect
            // them to the selector).
            let badgeClass = 'bg-primary';
            let badgeLabel = String(status.status || '').toUpperCase();
            if (status.status === 'completed') {
                badgeClass = 'bg-success';
            } else if (status.status === 'failed') {
                badgeClass = 'bg-danger';
            } else if (status.status === 'awaiting_selection') {
                badgeClass = 'bg-warning text-dark';
                badgeLabel = 'AWAITING SELECTION — redirecting…';
            } else if (status.status === 'running' && (status.progress || 0) < 40) {
                badgeLabel = 'ANALYZING…';
            } else if (status.status === 'running') {
                badgeLabel = 'IMPORTING…';
            }

            // Build the badge with DOM nodes (no innerHTML of status fields
            // — status comes from the DB but a future schema change could
            // widen the field to operator-influenced strings).
            statusDiv.replaceChildren();
            const span = document.createElement('span');
            span.className = 'badge ' + badgeClass;
            span.textContent = badgeLabel;
            statusDiv.appendChild(span);

            // Update log
            if (status.log && status.log.length > 0) {
                logDiv.textContent = status.log.join('\n');
                logDiv.scrollTop = logDiv.scrollHeight;
            }
        }

        function showImportResults(status) {
            // Update step indicator
            updateStepIndicator(4);
            
            // Hide import progress
            document.getElementById('import-section').style.display = 'none';
            
            // Show results
            document.getElementById('results-section').style.display = 'block';
            
            // TODO: Parse and display import summary from status
            const summary = document.getElementById('import-summary');
            // Build the summary via DOM nodes (rather than innerHTML) so the
            // server-supplied `status.completed_at` value is treated as text.
            // The .local-time span lets the global whp-times.js handler
            // rewrite it to the user's locale + timezone.
            summary.replaceChildren();
            const intro = document.createElement('p');
            intro.textContent = 'Your cPanel backup has been successfully imported!';
            const completed = document.createElement('p');
            completed.appendChild(document.createTextNode('Import completed at: '));
            const timeEl = document.createElement('span');
            timeEl.className = 'local-time';
            timeEl.setAttribute('data-utc', status.completed_at);
            timeEl.setAttribute('data-format', 'datetime-seconds');
            timeEl.textContent = status.completed_at;
            completed.appendChild(timeEl);
            summary.appendChild(intro);
            summary.appendChild(completed);
        }

        function showImportError(error) {
            alert('Import failed: ' + error);
            
            // Reset to selection form
            document.getElementById('import-section').style.display = 'none';
            document.getElementById('selection-section').style.display = 'block';
            updateStepIndicator(1);
        }

        function updateStepIndicator(step) {
            for (let i = 1; i <= 4; i++) {
                const stepElement = document.getElementById(`step${i}`);
                if (stepElement) {
                    if (i <= step) {
                        stepElement.className = stepElement.className.replace('bg-secondary', 'bg-primary');
                    } else {
                        stepElement.className = stepElement.className.replace('bg-primary', 'bg-secondary');
                    }
                }
            }
        }

        function startNewImport() {
            // Reset form and show selection section
            document.getElementById('backup_file_select').value = '';
            document.getElementById('selected-backup-info').style.display = 'none';
            document.getElementById('select-backup-btn').disabled = true;
            document.getElementById('results-section').style.display = 'none';
            document.getElementById('selection-section').style.display = 'block';
            
            updateStepIndicator(1);
            currentImportId = null;
            
            if (statusCheckInterval) {
                clearInterval(statusCheckInterval);
            }
            
            refreshBackupFiles();
        }

        // Utility functions
        function formatFileSize(bytes) {
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            if (bytes === 0) return '0 Bytes';
            const i = Math.floor(Math.log(bytes) / Math.log(1024));
            return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
        }

        function formatDate(timestamp) {
            return new Date(timestamp * 1000).toLocaleString();
        }
    </script>
</div>