<?php
// =============================================================================
// /api/backup.php — download the panel state as a ZIP.
// /api/restore.php uploads + restores.
//
// Contents:
//   data/panel.db        — current SQLite DB
//   uploads/             — slideshow uploads + any future user-uploaded files
//   meta.json            — version + timestamp + checksum
// =============================================================================
require_once __DIR__ . '/_common.php';
require_csrf_unless_get();

// The backup contains the full SQLite DB (admin password hashes, 2FA secrets,
// every webview_settings row including TMDB / paid SportsDB keys). It is an
// admin-only artifact — viewers must never be able to exfiltrate it through
// the GET path.
auth_require_admin('Only admins can download backups.');

list($action, $body) = read_action();

if ($action === 'download' || ($_SERVER['REQUEST_METHOD'] === 'GET' && $action === '')) {
    if (!class_exists('ZipArchive')) json_error('ZipArchive extension required', 500);

    $tmp = tempnam(sys_get_temp_dir(), 'b3backup_');
    $zip = new ZipArchive();
    if ($zip->open($tmp, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
        json_error('zip create failed', 500);
    }

    $db_path = __DIR__ . '/../data/panel.db';
    if (is_file($db_path)) $zip->addFile($db_path, 'data/panel.db');

    $uploads = __DIR__ . '/../uploads';
    if (is_dir($uploads)) {
        $rii = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($uploads, FilesystemIterator::SKIP_DOTS));
        foreach ($rii as $f) {
            if (!$f->isFile()) continue;
            $rel = 'uploads/' . str_replace('\\', '/', substr($f->getPathname(), strlen($uploads) + 1));
            $zip->addFile($f->getPathname(), $rel);
        }
    }

    $meta = [
        'panel_name' => 'b3studios_iboultra',
        'created_at' => date('c'),
        'panel_version' => '1.0',
    ];
    $zip->addFromString('meta.json', json_encode($meta, JSON_PRETTY_PRINT));
    $zip->close();

    $filename = 'panel_backup_' . date('Y-m-d_His') . '.zip';
    header('Content-Type: application/zip');
    header('Content-Disposition: attachment; filename="' . $filename . '"');
    header('Content-Length: ' . filesize($tmp));
    header('Cache-Control: no-store');
    readfile($tmp);
    @unlink($tmp);
    exit;
}

json_error('unknown action', 400);
