<?php
$cmsUpdate = $updates['cms'] ?? null;
$pluginUpdates = $updates['plugins'] ?? [];
$themeUpdates = $updates['themes'] ?? [];
$totalUpdates = ($cmsUpdate ? 1 : 0) + count($pluginUpdates) + count($themeUpdates);
?>

<div class="flex items-center justify-between mb-6">
    <div>
        <p class="text-gray-500 text-sm">Current CMS version: <strong>v<?= htmlspecialchars($currentVersion) ?></strong></p>
    </div>
    <button type="button" onclick="checkForUpdates()" id="checkBtn"
            class="inline-flex items-center gap-2 px-4 py-2 bg-white text-gray-700 text-sm font-medium rounded-lg border border-gray-300 hover:bg-gray-50 transition-colors">
        <svg id="checkSpinner" class="hidden w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>
        <svg id="checkIcon" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
        Check for Updates
    </button>
</div>

<?php if ($totalUpdates === 0): ?>
    <div class="bg-green-50 border border-green-200 rounded-lg p-8 text-center mb-6">
        <svg class="w-12 h-12 mx-auto text-green-500 mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
        </svg>
        <h3 class="text-lg font-semibold text-green-800 mb-1">Everything is up to date!</h3>
        <p class="text-green-600 text-sm">Your CMS, plugins, and themes are all running the latest versions.</p>
    </div>
<?php else: ?>

    <div class="bg-green-50 border border-green-200 rounded-lg px-5 py-3 mb-5 flex items-start gap-3">
        <svg class="w-5 h-5 text-green-600 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
        <div class="text-sm text-green-800">
            <strong>Your data is safe.</strong> Updates only replace core system files (code, templates, migrations). Your videos, settings, themes, plugins, uploads, and database are never modified or deleted. A backup is automatically created before each update.
        </div>
    </div>

    
    <?php if ($cmsUpdate): ?>
    <div class="bg-white rounded-lg shadow-sm border border-gray-200 mb-6">
        <div class="px-6 py-4 border-b border-gray-200 flex items-center justify-between">
            <div class="flex items-center gap-3">
                <div class="w-10 h-10 rounded-lg bg-blue-100 flex items-center justify-center text-blue-600">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M12 5l7 7-7 7"/></svg>
                </div>
                <div>
                    <h3 class="font-semibold text-gray-900">TubePress CMS Core</h3>
                    <p class="text-sm text-gray-500">
                        v<?= htmlspecialchars($cmsUpdate['current']) ?>
                        <svg class="inline w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
                        <span class="text-blue-600 font-medium">v<?= htmlspecialchars($cmsUpdate['latest']) ?></span>
                    </p>
                </div>
            </div>
            <button type="button" onclick="applyUpdate('cms', 'core', '<?= htmlspecialchars($cmsUpdate['latest']) ?>', '<?= htmlspecialchars($cmsUpdate['checksum'] ?? '') ?>', true, this)"
                    class="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 transition-colors">
                <svg class="w-4 h-4 update-spinner hidden animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>
                Update Now
            </button>
        </div>
        <?php $cmsBehind = (int) ($cmsUpdate['behind'] ?? 1); ?>
        <?php if ($cmsBehind > 1): ?>
        <div class="px-6 py-3 bg-blue-50 flex items-start gap-2 text-sm text-blue-800">
            <svg class="w-4 h-4 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
            <div>You're <strong><?= $cmsBehind ?> releases behind</strong>. This single update installs the latest version (<strong>v<?= htmlspecialchars($cmsUpdate['latest']) ?></strong>) directly &mdash; you don't need to apply each version one by one. Everything below is included.</div>
        </div>
        <?php endif; ?>
        <?php if (!empty($cmsUpdate['releases'])): ?>
        <div class="px-6 py-4 text-sm text-gray-600">
            <p class="font-medium text-gray-700 mb-2"><?= $cmsBehind > 1 ? "What's included &middot; " . $cmsBehind . " releases" : 'Changelog' ?>:</p>
            <div class="space-y-3 max-h-72 overflow-y-auto pr-1">
                <?php foreach ($cmsUpdate['releases'] as $rel): ?>
                <div>
                    <div class="flex items-center gap-2 mb-0.5">
                        <span class="inline-block px-2 py-0.5 rounded bg-gray-100 text-gray-700 text-xs font-semibold">v<?= htmlspecialchars($rel['version'] ?? '') ?></span>
                        <?php if (($rel['version'] ?? '') === ($cmsUpdate['latest'] ?? '')): ?><span class="text-xs font-medium text-blue-600">latest</span><?php endif; ?>
                    </div>
                    <?php if (!empty($rel['changelog'])): ?>
                    <div class="text-gray-500 pl-0.5"><?= nl2br(htmlspecialchars($rel['changelog'])) ?></div>
                    <?php else: ?>
                    <div class="text-gray-400 italic pl-0.5">No release notes.</div>
                    <?php endif; ?>
                </div>
                <?php endforeach; ?>
            </div>
        </div>
        <?php elseif (!empty($cmsUpdate['changelog'])): ?>
        <div class="px-6 py-4 text-sm text-gray-600">
            <p class="font-medium text-gray-700 mb-1">Changelog:</p>
            <div class="text-gray-500"><?= nl2br(htmlspecialchars($cmsUpdate['changelog'])) ?></div>
        </div>
        <?php endif; ?>
    </div>
    <?php endif; ?>

    
    <?php if (!empty($pluginUpdates)): ?>
    <div class="bg-white rounded-lg shadow-sm border border-gray-200 mb-6">
        <div class="px-6 py-4 border-b border-gray-200">
            <h3 class="font-semibold text-gray-900">Plugin Updates (<?= count($pluginUpdates) ?>)</h3>
        </div>
        <div class="divide-y divide-gray-100">
            <?php foreach ($pluginUpdates as $pu): ?>
            <div class="px-6 py-4 flex items-center justify-between" id="update-plugin-<?= htmlspecialchars($pu['slug']) ?>">
                <div>
                    <span class="font-medium text-gray-900"><?= htmlspecialchars($pu['name']) ?></span>
                    <span class="text-gray-400 text-sm ml-2">
                        v<?= htmlspecialchars($pu['current']) ?>
                        <svg class="inline w-3 h-3 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
                        <span class="text-blue-600">v<?= htmlspecialchars($pu['latest']) ?></span>
                    </span>
                    <?php if (!empty($pu['changelog'])): ?>
                        <p class="text-xs text-gray-400 mt-1"><?= htmlspecialchars(mb_substr($pu['changelog'], 0, 120)) ?><?= mb_strlen($pu['changelog']) > 120 ? '...' : '' ?></p>
                    <?php endif; ?>
                </div>
                <?php $puExpired = array_key_exists('updates_entitled', $pu) && $pu['updates_entitled'] === false; ?>
                <div class="flex items-center gap-2">
                    <?php if ($puExpired): ?>
                        <div class="text-right">
                            <div class="text-xs text-amber-700 font-medium flex items-center gap-1 justify-end" title="Your installed version keeps working. Renew update access to install newer versions.">
                                <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
                                Update access ended<?= !empty($pu['updates_until']) ? ' · ' . htmlspecialchars(date('M Y', strtotime((string) $pu['updates_until']))) : '' ?>
                            </div>
                            <a href="<?= htmlspecialchars($pu['renew_url'] ?? 'https://tubepress.io/dashboard/catalogue') ?>" target="_blank" rel="noopener noreferrer"
                               class="inline-flex items-center gap-1.5 mt-1.5 px-3 py-1.5 bg-amber-500 text-white text-sm font-medium rounded-lg hover:bg-amber-600 transition-colors">
                                <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
                                Renew to update<?= !empty($pu['renew_price']) ? ' · ' . number_format((float) $pu['renew_price']) . ' cr' : '' ?>
                            </a>
                        </div>
                    <?php else: ?>
                        <?php if (empty($pu['owned']) && !empty($pu['price_credits']) && $pu['price_credits'] > 0): ?>
                            <span class="text-xs text-amber-600"><?= number_format($pu['price_credits']) ?> credits</span>
                        <?php endif; ?>
                        <button type="button" onclick="applyUpdate('plugin', '<?= htmlspecialchars($pu['slug']) ?>', '<?= htmlspecialchars($pu['latest']) ?>', '<?= htmlspecialchars($pu['checksum'] ?? '') ?>', <?= !empty($pu['is_free']) || (isset($pu['price_credits']) && (float)$pu['price_credits'] === 0.0) ? 'true' : 'false' ?>, this)"
                                class="inline-flex items-center gap-1.5 px-3 py-1.5 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 transition-colors">
                            <svg class="w-3.5 h-3.5 update-spinner hidden animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>
                            Update
                        </button>
                    <?php endif; ?>
                </div>
            </div>
            <?php endforeach; ?>
        </div>
    </div>
    <?php endif; ?>

    
    <?php if (!empty($themeUpdates)): ?>
    <div class="bg-white rounded-lg shadow-sm border border-gray-200 mb-6">
        <div class="px-6 py-4 border-b border-gray-200">
            <h3 class="font-semibold text-gray-900">Theme Updates (<?= count($themeUpdates) ?>)</h3>
        </div>
        <div class="divide-y divide-gray-100">
            <?php foreach ($themeUpdates as $tu): ?>
            <div id="theme-row-<?= htmlspecialchars($tu['slug']) ?>">
                <div class="px-6 py-4 flex items-center justify-between">
                    <div>
                        <span class="font-medium text-gray-900"><?= htmlspecialchars($tu['name']) ?></span>
                        <span class="text-gray-400 text-sm ml-2">
                            v<?= htmlspecialchars($tu['current']) ?>
                            <svg class="inline w-3 h-3 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
                            <span class="text-blue-600">v<?= htmlspecialchars($tu['latest']) ?></span>
                        </span>
                        <?php if (!empty($tu['changelog'])): ?>
                            <p class="text-xs text-gray-400 mt-1"><?= htmlspecialchars(mb_substr($tu['changelog'], 0, 120)) ?><?= mb_strlen($tu['changelog']) > 120 ? '...' : '' ?></p>
                        <?php endif; ?>
                    </div>
                    <?php $tuExpired = array_key_exists('updates_entitled', $tu) && $tu['updates_entitled'] === false; ?>
                    <div class="flex items-center gap-2">
                        <?php if ($tuExpired): ?>
                            <div class="text-right">
                                <div class="text-xs text-amber-700 font-medium flex items-center gap-1 justify-end" title="Your installed version keeps working. Renew update access to install newer versions.">
                                    <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
                                    Update access ended<?= !empty($tu['updates_until']) ? ' · ' . htmlspecialchars(date('M Y', strtotime((string) $tu['updates_until']))) : '' ?>
                                </div>
                                <a href="<?= htmlspecialchars($tu['renew_url'] ?? 'https://tubepress.io/dashboard/catalogue') ?>" target="_blank" rel="noopener noreferrer"
                                   class="inline-flex items-center gap-1.5 mt-1.5 px-3 py-1.5 bg-amber-500 text-white text-sm font-medium rounded-lg hover:bg-amber-600 transition-colors">
                                    <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
                                    Renew to update<?= !empty($tu['renew_price']) ? ' · ' . number_format((float) $tu['renew_price']) . ' cr' : '' ?>
                                </a>
                            </div>
                        <?php else: ?>
                            <?php if (empty($tu['owned']) && !empty($tu['price_credits']) && $tu['price_credits'] > 0): ?>
                                <span class="text-xs text-amber-600"><?= number_format($tu['price_credits']) ?> credits</span>
                            <?php endif; ?>
                            <button type="button" id="theme-update-btn-<?= htmlspecialchars($tu['slug']) ?>"
                                    onclick="DiffReview.start('<?= htmlspecialchars($tu['slug']) ?>', '<?= htmlspecialchars($tu['latest']) ?>', '<?= htmlspecialchars($tu['checksum'] ?? '') ?>', <?= !empty($tu['is_free']) || (isset($tu['price_credits']) && (float)$tu['price_credits'] === 0.0) ? 'true' : 'false' ?>, '<?= htmlspecialchars($tu['name']) ?>', '<?= htmlspecialchars($tu['current']) ?>')"
                                    class="inline-flex items-center gap-1.5 px-3 py-1.5 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 transition-colors">
                                <svg class="w-3.5 h-3.5 update-spinner hidden animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>
                                Review Changes
                            </button>
                        <?php endif; ?>
                    </div>
                </div>
                
                <div id="theme-diff-<?= htmlspecialchars($tu['slug']) ?>" class="hidden"></div>
            </div>
            <?php endforeach; ?>
        </div>
    </div>
    <?php endif; ?>

<?php endif; ?>


<div class="bg-white rounded-lg shadow-sm border border-gray-200 mb-6">
    <div class="px-6 py-4 border-b border-gray-200 flex items-center justify-between cursor-pointer" onclick="toggleHistory()">
        <h3 class="font-semibold text-gray-900">Update History & Rollback</h3>
        <svg id="historyChevron" class="w-5 h-5 text-gray-400 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
    </div>
    <div id="historyPanel" class="hidden">
        <div id="historyContent" class="divide-y divide-gray-100">
            <div class="px-6 py-8 text-center text-gray-400 text-sm">Loading...</div>
        </div>
    </div>
</div>

<style>
.diff-panel{border-top:1px solid #e5e7eb;background:#f9fafb}
.diff-panel-header{display:flex;align-items:center;justify-content:space-between;padding:12px 24px;border-bottom:1px solid #e5e7eb;background:#f1f5f9}
.diff-panel-header .step-label{font-size:13px;font-weight:600;color:#334155}
.diff-panel-body{display:flex;min-height:300px;max-height:520px}
.diff-file-list{width:220px;flex-shrink:0;border-right:1px solid #e5e7eb;overflow-y:auto;background:#f9fafb}
.diff-file-item{display:flex;align-items:center;gap:6px;padding:7px 14px;cursor:pointer;border-left:3px solid transparent;font-size:12px;color:#374151;transition:background .1s}
.diff-file-item:hover{background:#e5e7eb}
.diff-file-item.active{background:#eff6ff;border-left-color:#3b82f6;color:#1d4ed8;font-weight:500}
.diff-status-badge{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:3px;font-size:9px;font-weight:700;flex-shrink:0}
.diff-badge-M{background:#fef3c7;color:#92400e}
.diff-badge-A{background:#d1fae5;color:#065f46}
.diff-badge-D{background:#fee2e2;color:#991b1b}
.diff-badge-B{background:#e0e7ff;color:#3730a3}
.diff-badge-U{background:#f3f4f6;color:#6b7280}
.diff-viewer{flex:1;overflow:auto;background:#fff}
.diff-file-header{position:sticky;top:0;z-index:10;display:flex;align-items:center;gap:8px;padding:8px 14px;background:#f9fafb;border-bottom:1px solid #e5e7eb;font-size:12px;font-weight:600;color:#111827}
.diff-file-header .diff-stat{margin-left:auto;font-weight:400;font-size:11px;color:#6b7280}
.diff-file-header .diff-stat .add-count{color:#16a34a}
.diff-file-header .diff-stat .del-count{color:#dc2626}
.diff-table{width:100%;border-collapse:collapse;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:11px;line-height:1.5}
.diff-table td{padding:0 10px;white-space:pre-wrap;word-break:break-all;vertical-align:top}
.diff-table .line-num{width:44px;min-width:44px;text-align:right;color:#9ca3af;user-select:none;padding:0 6px;border-right:1px solid #e5e7eb}
.diff-line-add{background:#dcfce7}
.diff-line-add .line-num{background:#bbf7d0;color:#166534}
.diff-line-del{background:#fee2e2}
.diff-line-del .line-num{background:#fecaca;color:#991b1b}
.diff-line-hunk{background:#eff6ff;color:#3b82f6;font-style:italic}
.diff-line-hunk td{padding:3px 10px}
.diff-line-ctx{background:#fff}
.diff-empty{padding:32px;text-align:center;color:#9ca3af;font-size:13px}
.diff-summary-pill{display:inline-flex;align-items:center;gap:3px;padding:2px 8px;border-radius:9999px;font-size:11px;font-weight:500}
.diff-summary-pill.s-mod{background:#fef3c7;color:#92400e}
.diff-summary-pill.s-add{background:#d1fae5;color:#065f46}
.diff-summary-pill.s-del{background:#fee2e2;color:#991b1b}
.diff-panel-footer{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:10px 24px;border-top:1px solid #e5e7eb;background:#f9fafb}
.diff-center{display:flex;align-items:center;justify-content:center;flex:1;padding:40px}
</style>


<div id="toast-container" class="fixed top-4 right-4 z-50 flex flex-col gap-2" style="max-width:420px;"></div>

<script>

function esc(s) { var d = document.createElement('div'); d.textContent = s == null ? '' : String(s); return d.innerHTML; }


function showToast(message, type) {
    type = type || 'error';
    const colors = {
        error: 'bg-red-50 border-red-200 text-red-800',
        success: 'bg-green-50 border-green-200 text-green-800',
        warning: 'bg-amber-50 border-amber-200 text-amber-800',
        info: 'bg-blue-50 border-blue-200 text-blue-800'
    };
    const icons = {
        error: '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>',
        success: '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>',
        warning: '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4.5c-.77-.833-2.694-.833-3.464 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"/>',
        info: '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>'
    };
    var el = document.createElement('div');
    el.className = 'flex items-start gap-3 px-4 py-3 rounded-lg border shadow-lg text-sm transition-all ' + (colors[type] || colors.error);
    el.innerHTML = '<svg class="w-5 h-5 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">' + (icons[type] || icons.error) + '</svg>'
        + '<div class="flex-1 font-medium">' + esc(message) + '</div>'
        + '<button onclick="this.parentElement.remove()" class="text-current opacity-50 hover:opacity-100">&times;</button>';
    document.getElementById('toast-container').appendChild(el);
    setTimeout(function() { if (el.parentElement) el.remove(); }, type === 'error' ? 8000 : 5000);
}


var historyLoaded = false;
function toggleHistory() {
    var panel = document.getElementById('historyPanel');
    var chevron = document.getElementById('historyChevron');
    var isHidden = panel.classList.contains('hidden');
    panel.classList.toggle('hidden');
    chevron.style.transform = isHidden ? 'rotate(180deg)' : '';
    if (isHidden && !historyLoaded) { loadHistory(); historyLoaded = true; }
}

var historyBackups = [];
var historyPage = 1;
var HISTORY_PER_PAGE = 8;

function loadHistory() {
    var container = document.getElementById('historyContent');
    fetch('/admin/updates/backups', {credentials:'same-origin'})
        .then(function(r){return r.json();})
        .then(function(data) {
            historyBackups = data.backups || [];
            historyPage = 1;
            renderHistoryPage();
        }).catch(function() {
            container.innerHTML = '<div class="px-6 py-4 text-center text-red-400 text-sm">Failed to load history.</div>';
        });
}

function renderHistoryPage() {
    var container = document.getElementById('historyContent');
    var backups = historyBackups;

    if (!backups.length) {
        container.innerHTML = '<div class="px-6 py-8 text-center text-gray-400 text-sm">No backups available to roll back to yet.</div>';
        return;
    }

    var totalPages = Math.ceil(backups.length / HISTORY_PER_PAGE);
    if (historyPage > totalPages) historyPage = totalPages;
    if (historyPage < 1) historyPage = 1;
    var start = (historyPage - 1) * HISTORY_PER_PAGE;
    var pageItems = backups.slice(start, start + HISTORY_PER_PAGE);

    var html = '<div class="px-6 py-3 bg-gray-50 border-b flex items-center justify-between">'
        + '<span class="text-xs font-semibold text-gray-500 uppercase tracking-wider">Available Backups</span>'
        + '<span class="text-xs text-gray-400">' + backups.length + ' total</span>'
        + '</div>';

    pageItems.forEach(function(b) {
        var d = new Date(b.date * 1000);
        html += '<div class="px-6 py-3 flex items-center justify-between">'
            + '<div class="flex items-center gap-3">'
            + '<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ' + (b.type === 'plugin' ? 'bg-purple-100 text-purple-700' : b.type === 'theme' ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 text-gray-700') + '">' + esc(b.type) + '</span>'
            + '<span class="text-sm text-gray-700">' + esc(b.slug) + '</span>'
            + (b.version ? '<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold bg-emerald-50 text-emerald-700" title="Rolling back restores this version">v' + esc(b.version) + '</span>' : '<span class="text-xs text-gray-400 italic">version n/a</span>')
            + (b.to_version ? '<span class="text-[11px] text-gray-400">&rarr; v' + esc(b.to_version) + '</span>' : '')
            + '<span class="text-xs text-gray-400">' + d.toLocaleDateString() + ' ' + d.toLocaleTimeString() + '</span>'
            + '</div>';
        html += '<button onclick="doRollback(\'' + esc(b.type) + '\',\'' + esc(b.slug) + '\',\'' + esc(b.name) + '\',this)" class="px-2.5 py-1 text-xs font-medium text-amber-700 bg-amber-50 border border-amber-200 rounded-lg hover:bg-amber-100 transition-colors">Rollback</button>';
        html += '</div>';
    });

    if (totalPages > 1) {
        var prevDisabled = historyPage <= 1;
        var nextDisabled = historyPage >= totalPages;
        var baseBtn = 'px-3 py-1 text-xs font-medium rounded-lg border ';
        html += '<div class="px-6 py-3 flex items-center justify-between bg-gray-50 border-t">'
            + '<button onclick="historyGo(-1)" ' + (prevDisabled ? 'disabled' : '') + ' class="' + baseBtn + (prevDisabled ? 'text-gray-300 border-gray-200 cursor-not-allowed' : 'text-gray-600 border-gray-300 hover:bg-gray-100') + '">Previous</button>'
            + '<span class="text-xs text-gray-500">Page ' + historyPage + ' of ' + totalPages + '</span>'
            + '<button onclick="historyGo(1)" ' + (nextDisabled ? 'disabled' : '') + ' class="' + baseBtn + (nextDisabled ? 'text-gray-300 border-gray-200 cursor-not-allowed' : 'text-gray-600 border-gray-300 hover:bg-gray-100') + '">Next</button>'
            + '</div>';
    }

    container.innerHTML = html;
}

function historyGo(delta) {
    historyPage += delta;
    renderHistoryPage();
}

function doRollback(type, slug, backupName, btn) {
    var rbLabel = (type === 'cms') ? 'the CMS core' : (type + ' "' + slug + '"');
    if (!confirm('Roll back ' + rbLabel + ' to backup "' + backupName + '"? This restores the backed-up version in place of the current one.')) return;
    btn.disabled = true;
    btn.textContent = 'Rolling back...';
    fetch('/admin/updates/rollback', {
        method: 'POST',
        headers: {'Content-Type':'application/json','X-CSRF-TOKEN':'<?= Router::csrfToken() ?>'},
        credentials: 'same-origin',
        body: JSON.stringify({type: type, slug: slug, backup_name: backupName})
    })
    .then(function(r){return r.json();})
    .then(function(data) {
        if (data.success) {
            showToast('Rollback successful! ' + slug + ' has been restored.', 'success');
            setTimeout(function() { window.location.reload(); }, 1500);
        } else {
            showToast('Rollback failed: ' + (data.error || 'Unknown error'), 'error');
            btn.disabled = false;
            btn.textContent = 'Rollback';
        }
    })
    .catch(function() {
        showToast('Network error during rollback.', 'error');
        btn.disabled = false;
        btn.textContent = 'Rollback';
    });
}

function checkForUpdates() {
    const btn = document.getElementById('checkBtn');
    const spinner = document.getElementById('checkSpinner');
    const icon = document.getElementById('checkIcon');
    btn.disabled = true;
    spinner.classList.remove('hidden');
    icon.classList.add('hidden');

    fetch('/admin/updates/check', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': '<?= Router::csrfToken() ?>' },
        credentials: 'same-origin'
    })
    .then(r => r.json())
    .then(data => {
        if (data.success) {
            window.location.reload();
        } else {
            showToast(data.error || 'Check failed', 'error');
            btn.disabled = false;
            spinner.classList.add('hidden');
            icon.classList.remove('hidden');
        }
    })
    .catch(() => {
        showToast('Network error. Please try again.', 'error');
        btn.disabled = false;
        spinner.classList.add('hidden');
        icon.classList.remove('hidden');
    });
}

function applyUpdate(type, slug, version, checksum, isFree, btn) {
    btn.disabled = true;
    const spinner = btn.querySelector('.update-spinner');
    if (spinner) spinner.classList.remove('hidden');

    fetch('/admin/updates/apply', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': '<?= Router::csrfToken() ?>' },
        credentials: 'same-origin',
        body: JSON.stringify({ type, slug, version, checksum, is_free: isFree })
    })
    .then(r => r.json())
    .then(data => {
        if (data.success) {
            btn.textContent = 'Updated!';
            btn.className = btn.className.replace('bg-blue-600', 'bg-green-600').replace('hover:bg-blue-700', 'hover:bg-green-700');
            setTimeout(() => window.location.reload(), 1000);
        } else {
            showToast('Update failed: ' + (data.error || 'Unknown error'), 'error');
            btn.disabled = false;
            if (spinner) spinner.classList.add('hidden');
        }
    })
    .catch(() => {
        showToast('Network error. Please try again.', 'error');
        btn.disabled = false;
        if (spinner) spinner.classList.add('hidden');
    });
}

window.DiffReview = (function() {
    let activeId = null;
    let diffData = null;
    let selectedIdx = -1;
    const csrf = '<?= Router::csrfToken() ?>';

    function esc(s) { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
    function badge(st) { return {modified:'M',added:'A',removed:'D',binary_changed:'B',unchanged:'U'}[st]||'?'; }
    function badgeCls(st) { return {modified:'M',added:'A',removed:'D',binary_changed:'B',unchanged:'U'}[st]||'U'; }

    function panel(id) { return document.getElementById('theme-diff-' + id); }
    function btn(id) { return document.getElementById('theme-update-btn-' + id); }

    function showPanel(id, html) {
        const p = panel(id);
        p.innerHTML = '<div class="diff-panel">' + html + '</div>';
        p.classList.remove('hidden');
    }

    function showLoading(id) {
        showPanel(id,
            '<div class="diff-panel-header"><span class="step-label">Step 1 — Reviewing changes...</span></div>' +
            '<div class="diff-center">' +
                '<div class="text-center">' +
                    '<svg class="w-8 h-8 mx-auto text-blue-500 animate-spin mb-2" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>' +
                    '<p class="text-gray-500 text-sm">Downloading and comparing files...</p>' +
                '</div>' +
            '</div>'
        );
    }

    function showError(id, msg) {
        showPanel(id,
            '<div class="diff-panel-header"><span class="step-label">Error</span></div>' +
            '<div class="diff-center">' +
                '<div class="text-center">' +
                    '<svg class="w-8 h-8 mx-auto text-red-500 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' +
                    '<p class="text-red-600 text-sm">' + esc(msg) + '</p>' +
                '</div>' +
            '</div>' +
            '<div class="diff-panel-footer"><button onclick="DiffReview.cancel()" class="px-3 py-1.5 text-sm text-gray-600 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">Close</button></div>'
        );
    }

    function showIdentical(id) {
        showPanel(id,
            '<div class="diff-panel-header"><span class="step-label">Review complete</span></div>' +
            '<div class="diff-center">' +
                '<div class="text-center">' +
                    '<svg class="w-8 h-8 mx-auto text-green-500 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' +
                    '<p class="text-green-700 text-sm font-medium">No differences found</p>' +
                    '<p class="text-gray-400 text-xs mt-1">Your theme files are identical to the update.</p>' +
                '</div>' +
            '</div>' +
            '<div class="diff-panel-footer"><button onclick="DiffReview.cancel()" class="px-3 py-1.5 text-sm text-gray-600 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">Close</button></div>'
        );
    }

    function renderContent(id, data, isDemo) {
        const s = data.summary;
        let badges = '';
        if (s.modified > 0) badges += '<span class="diff-summary-pill s-mod">' + s.modified + ' modified</span>';
        if (s.added > 0) badges += '<span class="diff-summary-pill s-add">' + s.added + ' added</span>';
        if (s.removed > 0) badges += '<span class="diff-summary-pill s-del">' + s.removed + ' removed</span>';

        const visible = data.files.filter(f => f.status !== 'unchanged');

        let fileListHtml = '';
        visible.forEach((f, i) => {
            const l = badge(f.status), c = badgeCls(f.status);
            const short = f.path.length > 28 ? '...' + f.path.slice(-25) : f.path;
            fileListHtml += '<div class="diff-file-item' + (i === 0 ? ' active' : '') + '" data-idx="' + i + '" onclick="DiffReview.selectFile(' + i + ')" title="' + esc(f.path) + '">' +
                '<span class="diff-status-badge diff-badge-' + c + '">' + l + '</span>' +
                '<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + esc(short) + '</span></div>';
        });

        let applyBtn = '';
        if (isDemo) {
            applyBtn = '<button onclick="showToast(\'This is a demo — no changes were applied.\',\'info\')" class="px-3 py-1.5 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700">Apply Update (Demo)</button>';
        } else {
            applyBtn = '<button id="diff-apply-' + id + '" onclick="DiffReview.apply()" class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700">' +
                '<svg class="w-3.5 h-3.5 diff-apply-spin hidden animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>' +
                'Apply Update</button>';
        }

        showPanel(id,
            '<div class="diff-panel-header">' +
                '<span class="step-label">Step 2 — Review changes before updating</span>' +
                '<div class="flex items-center gap-2">' + badges + '</div>' +
            '</div>' +
            '<div class="diff-panel-body">' +
                '<div class="diff-file-list" id="diff-fl-' + id + '">' + fileListHtml + '</div>' +
                '<div class="diff-viewer" id="diff-vw-' + id + '"></div>' +
            '</div>' +
            '<div class="diff-panel-footer">' +
                '<button onclick="DiffReview.cancel()" class="px-3 py-1.5 text-sm text-gray-600 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">Cancel</button>' +
                applyBtn +
            '</div>'
        );

        diffData = data;
        selectedIdx = -1;
        if (visible.length > 0) selectFile(0);
    }

    function selectFile(index) {
        if (!diffData || !activeId) return;
        const visible = diffData.files.filter(f => f.status !== 'unchanged');
        if (index < 0 || index >= visible.length) return;
        selectedIdx = index;
        const fl = document.getElementById('diff-fl-' + activeId);
        if (fl) fl.querySelectorAll('.diff-file-item').forEach((el, i) => el.classList.toggle('active', i === index));
        renderDiff(visible[index]);
    }

    function renderDiff(file) {
        const vw = document.getElementById('diff-vw-' + activeId);
        if (!vw) return;
        if (!file.diff || file.diff === '') { vw.innerHTML = '<div class="diff-empty">No changes</div>'; return; }
        if (file.status === 'binary_changed') { vw.innerHTML = '<div class="diff-empty">Binary file changed</div>'; return; }

        const l = badge(file.status), c = badgeCls(file.status);
        let stat = '';
        if (file.additions > 0) stat += '<span class="add-count">+' + file.additions + '</span> ';
        if (file.deletions > 0) stat += '<span class="del-count">-' + file.deletions + '</span>';

        let html = '<div class="diff-file-header"><span class="diff-status-badge diff-badge-' + c + '">' + l + '</span>' + esc(file.path) + '<span class="diff-stat">' + stat + '</span></div>';

        const lines = file.diff.split('\n');
        let oN = 0, nN = 0, rows = '';
        for (let i = 0; i < lines.length; i++) {
            const ln = lines[i];
            if (ln.startsWith('---') || ln.startsWith('+++')) continue;
            if (ln.startsWith('@@')) {
                const m = ln.match(/@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
                if (m) { oN = parseInt(m[1]) - 1; nN = parseInt(m[2]) - 1; }
                rows += '<tr class="diff-line-hunk"><td class="line-num"></td><td class="line-num"></td><td>' + esc(ln) + '</td></tr>';
            } else if (ln.startsWith('+')) {
                nN++;
                rows += '<tr class="diff-line-add"><td class="line-num"></td><td class="line-num">' + nN + '</td><td>' + esc(ln.substring(1)) + '</td></tr>';
            } else if (ln.startsWith('-')) {
                oN++;
                rows += '<tr class="diff-line-del"><td class="line-num">' + oN + '</td><td class="line-num"></td><td>' + esc(ln.substring(1)) + '</td></tr>';
            } else {
                oN++; nN++;
                rows += '<tr class="diff-line-ctx"><td class="line-num">' + oN + '</td><td class="line-num">' + nN + '</td><td>' + esc(ln.startsWith(' ') ? ln.substring(1) : ln) + '</td></tr>';
            }
        }
        html += '<table class="diff-table"><tbody>' + rows + '</tbody></table>';
        vw.innerHTML = html;
        vw.scrollTop = 0;
    }

    function resetBtn(id) {
        const b = btn(id);
        if (b) { b.disabled = false; const sp = b.querySelector('.update-spinner'); if (sp) sp.classList.add('hidden'); }
    }

    function doFetch(id, url, body, isDemo) {
        activeId = id;
        diffData = null;
        selectedIdx = -1;
        const b = btn(id);
        if (b) { b.disabled = true; const sp = b.querySelector('.update-spinner'); if (sp) sp.classList.remove('hidden'); }
        showLoading(id);

        fetch(url, {
            method: 'POST',
            headers: {'Content-Type':'application/json','X-CSRF-TOKEN': csrf},
            credentials: 'same-origin',
            body: JSON.stringify(body)
        })
        .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
        .then(data => {
            resetBtn(id);
            if (!data.success) { showError(id, data.error || 'Unknown error'); return; }
            const changed = (data.summary.modified || 0) + (data.summary.added || 0) + (data.summary.removed || 0);
            if (changed === 0) { showIdentical(id); return; }
            renderContent(id, data, isDemo);
        })
        .catch(e => { resetBtn(id); showError(id, e.message || 'Network error'); });
    }

    document.addEventListener('keydown', function(e) {
        if (!activeId || !diffData) return;
        if (e.key === 'Escape') { e.preventDefault(); DiffReview.cancel(); return; }
        const visible = diffData.files.filter(f => f.status !== 'unchanged');
        if (!visible.length) return;
        if (e.key === 'ArrowDown' || e.key === 'j') { e.preventDefault(); selectFile(Math.min(selectedIdx + 1, visible.length - 1)); }
        if (e.key === 'ArrowUp' || e.key === 'k') { e.preventDefault(); selectFile(Math.max(selectedIdx - 1, 0)); }
    });

    
    let cur = {};

    return {
        start: function(slug, version, checksum, isFree, name, oldVersion) {
            cur = {slug, version, checksum, isFree};
            doFetch(slug, '/admin/updates/theme-diff', {slug, version, checksum, is_free: isFree}, false);
        },
        startDemo: function(slug) {
            cur = {};
            doFetch(slug + '-demo', '/admin/updates/theme-diff-demo', {slug: slug}, true);
        },
        selectFile: selectFile,
        cancel: function() {
            if (activeId) {
                const p = panel(activeId);
                if (p) { p.innerHTML = ''; p.classList.add('hidden'); }
                resetBtn(activeId);
            }
            activeId = null;
            diffData = null;
            selectedIdx = -1;
        },
        apply: function() {
            if (!cur.slug) return;
            const ab = document.getElementById('diff-apply-' + activeId);
            if (ab) { ab.disabled = true; const sp = ab.querySelector('.diff-apply-spin'); if (sp) sp.classList.remove('hidden'); }

            fetch('/admin/updates/apply', {
                method: 'POST',
                headers: {'Content-Type':'application/json','X-CSRF-TOKEN': csrf},
                credentials: 'same-origin',
                body: JSON.stringify({type:'theme', slug: cur.slug, version: cur.version, checksum: cur.checksum, is_free: cur.isFree})
            })
            .then(r => r.json())
            .then(data => {
                if (data.success) {
                    if (ab) { ab.textContent = 'Updated!'; ab.className = ab.className.replace('bg-blue-600','bg-green-600').replace('hover:bg-blue-700','hover:bg-green-700'); }
                    setTimeout(() => window.location.reload(), 1000);
                } else {
                    showToast('Update failed: ' + (data.error || 'Unknown error'), 'error');
                    if (ab) { ab.disabled = false; const sp = ab.querySelector('.diff-apply-spin'); if (sp) sp.classList.add('hidden'); }
                }
            })
            .catch(() => {
                showToast('Network error.', 'error');
                if (ab) { ab.disabled = false; const sp = ab.querySelector('.diff-apply-spin'); if (sp) sp.classList.add('hidden'); }
            });
        }
    };
})();
</script>
