// Auto-extracted from backup-page.js (verbatim) — augments BackupPage.prototype. Loaded after the base.
Object.assign(BackupPage.prototype, {
    openRestoreModal(app, locIdx, snapshot) {
        const locName = this.locName(locIdx);
        const modal = document.getElementById('backup-restore-modal');
        const body = document.getElementById('backup-restore-modal-body');
        if (!modal || !body) return;
        body.innerHTML = `
            <p>Restore <strong>${this.escape(app)}</strong> from backup <code>${this.escape(snapshot)}</code> at <strong>${this.escape(locName)}</strong>?</p>
            <p class="backup-card-hint">The app will be stopped, its folder wiped, the backup restored in place, then the app started again. App-specific pre/post-restore hooks run if present.</p>
        `;
        modal.dataset.app = app;
        modal.dataset.locIdx = locIdx;
        modal.dataset.snapshot = snapshot;
        modal.classList.add('open');
    },
    openDeleteModal(app, locIdx, snapshot) {
        const locName = this.locName(locIdx);
        const modal = document.getElementById('backup-delete-modal');
        const body = document.getElementById('backup-delete-modal-body');
        if (!modal || !body) return;
        body.innerHTML = `
            <p>Delete backup <code>${this.escape(snapshot)}</code> for <strong>${this.escape(app)}</strong> from <strong>${this.escape(locName)}</strong>?</p>
            <p class="backup-card-hint">This cannot be undone. Append-only locations will reject the operation.</p>
        `;
        modal.dataset.app = app;
        modal.dataset.locIdx = locIdx;
        modal.dataset.snapshot = snapshot;
        modal.classList.add('open');
    },
    async confirmRestore() {
        const modal = document.getElementById('backup-restore-modal');
        const { app, locIdx, snapshot } = modal.dataset;
        this.closeAllModals();
        await this.runTask(`libreportal restore app start ${app} ${snapshot} ${locIdx}`, 'restore', app);
    },
    async confirmDelete() {
        const modal = document.getElementById('backup-delete-modal');
        const { app, locIdx, snapshot } = modal.dataset;
        this.closeAllModals();
        await this.runTask(`libreportal backup app delete ${app} ${locIdx}:${snapshot}`, 'backup', app);
    },
    async runBackupAllApps() {
        await this.runTask(`libreportal backup all`, 'backup', null);
    },
    async runBackupSystem() {
        await this.runTask(`libreportal backup system`, 'backup', null);
    },
    async confirmRestoreSystem() {
        if (!confirm('Restore the latest system-config snapshot?\n\nIt is restored into a staging folder (not applied) — review it, then copy what you need (e.g. backup-location credentials, login, settings) into the live config. Your running config is NOT overwritten.')) return;
        await this.runTask(`libreportal restore system`, 'restore', null);
    },
    openBackupPickModal(opts = {}) {
        const modal = document.getElementById('backup-pick-modal');
        const body  = document.getElementById('backup-pick-modal-body');
        if (!modal || !body) return;

        const apps = this.dashboard?.apps || [];
        const sys  = this.dashboard?.system || {};
        const preTickSystem = !!opts.preTickSystem;
        const preTickApps   = new Set(opts.preTickApps || []);

        // System row at the top — uses the LibrePortal icon to match the
        // dashboard tile. Then every installed app, alphabetical.
        const sortedApps = apps.slice().sort((a, b) => a.app.localeCompare(b.app));

        const row = (key, iconSrc, label, sub, checked) => `
            <label class="backup-pick-row" style="display:flex; align-items:center; gap:12px; padding:10px 12px; border:1px solid rgba(var(--text-rgb),0.08); border-radius:8px; margin-bottom:6px; cursor:pointer">
                <input type="checkbox" class="backup-pick-cb" value="${this.escape(key)}" ${checked ? 'checked' : ''}>
                <img src="${this.escape(iconSrc)}" alt="" style="width:28px; height:28px; flex-shrink:0; border-radius:6px" onerror="this.style.display='none'">
                <div style="flex:1; min-width:0">
                    <div style="font-weight:600">${this.escape(label)}</div>
                    <div class="backup-card-hint" style="font-size:.82em">${this.escape(sub)}</div>
                </div>
            </label>
        `;

        const sysSub = sys.latest_snapshot
            ? 'Last backed up ' + this.formatRelative(sys.latest_time)
            : 'No backup yet';

        const rows = [
            row('__system__', '/core/icons/apps/libreportal.svg', 'Configs', sysSub, preTickSystem),
            ...sortedApps.map(app => {
                const meta = this.appMeta(app.app);
                const sub = app.latest_snapshot
                    ? 'Last backed up ' + this.formatRelative(app.latest_time)
                    : 'No backup yet';
                return row(app.app, meta.icon, meta.displayName, sub, preTickApps.has(app.app));
            })
        ].join('');

        body.innerHTML = `
            <p class="backup-card-hint" style="margin:0 0 10px">
                Pick what to snapshot. Each selection runs in the background and shows up on the Tasks page.
            </p>
            <div style="display:flex; gap:14px; margin-bottom:10px; font-size:.85em">
                <a href="#" data-pick-action="select-all" style="color:var(--accent); text-decoration:none">Select all</a>
                <a href="#" data-pick-action="select-none" style="color:var(--accent); text-decoration:none">Clear</a>
            </div>
            <div class="backup-pick-list" style="max-height:60vh; overflow-y:auto">${rows}</div>
        `;

        // The select-all / clear links live inside the modal body so we wire
        // them once here per open (they get rebuilt every open, no listener
        // leak).
        body.querySelectorAll('[data-pick-action]').forEach(a => {
            a.addEventListener('click', (e) => {
                e.preventDefault();
                const all = a.dataset.pickAction === 'select-all';
                body.querySelectorAll('.backup-pick-cb').forEach(cb => { cb.checked = all; });
            });
        });

        modal.classList.add('open');
    },
    async confirmBackupPick() {
        const modal = document.getElementById('backup-pick-modal');
        if (!modal) return;
        const selected = Array.from(modal.querySelectorAll('.backup-pick-cb:checked'))
            .map(cb => cb.value);
        if (!selected.length) {
            this.notify('Pick at least one thing to back up.', 'error');
            return;
        }
        this.closeAllModals();

        const apps = this.dashboard?.apps || [];
        const totalThings = apps.length + 1; // +1 for system
        const wantsSystem = selected.includes('__system__');
        const appSlugs = selected.filter(s => s !== '__system__');

        // Whole-fleet shortcut — `backup all` queues a single task and also
        // covers system, instead of N+1 separate tasks. Requires at least one
        // app so a system-only pick never collapses into "backup all".
        if (wantsSystem && apps.length > 0 && appSlugs.length === apps.length) {
            await this.runTask('libreportal backup all', 'backup', null);
            return;
        }
        if (wantsSystem) {
            await this.runTask('libreportal backup system', 'backup', null);
        }
        for (const slug of appSlugs) {
            await this.runTask(`libreportal backup app create ${slug}`, 'backup', slug);
        }
    },
});
