<?php
// ==========================================
// 1. KONFIGURACE AKTUALIZACE
// ==========================================
define('UPDATE_ZIP_URL', 'https://update.mysoft.cz/radiowebsystem/update.zip'); // Zde vložte URL adresu vašeho ZIP souboru
define('AFTER_UPDATE_SCRIPT', 'admin.php'); // Soubor, který se spustí po dokončení (např. hlavní stránka systému)
define('UPDATE_NOTIFY_EMAIL', 'admin@vas-web.cz'); // E-mail pro notifikaci (nechte prázdné pro vypnutí)

// ==========================================
// 2. BACKEND (Zpracování aktualizace - SSE)
// ==========================================
if (isset($_GET['action']) && $_GET['action'] === 'update') {
    // Nastavení hlaviček pro Server-Sent Events (živý přenos dat do prohlížeče)
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    header('Connection: keep-alive');
    header('X-Accel-Buffering: no'); // Deaktivace bufferování pro Nginx

    // Vypnutí output bufferingu pro okamžitý výpis
    while (ob_get_level() > 0) {
        ob_end_clean();
    }

    // Pomocná funkce pro odesílání zpráv do frontendu
    function sendMsg($step, $progress, $log, $isDone = false) {
        $data = json_encode([
            'step' => $step,
            'progress' => $progress,
            'log' => $log,
            'done' => $isDone
        ]);
        echo "data: {$data}\n\n";
        @flush();
    }

    $zipFile = __DIR__ . '/temp_update.zip';

    // Fáze 1: Stahování
    sendMsg('download', 0, "Zahajuji stahování aktualizace z " . UPDATE_ZIP_URL . "...");

    // Pokus o zjištění velikosti souboru pro přesný progress bar
    $headers = @get_headers(UPDATE_ZIP_URL, 1);
    $fileSize = 0;
    if ($headers && isset($headers['Content-Length'])) {
        $fileSize = is_array($headers['Content-Length']) ? end($headers['Content-Length']) : $headers['Content-Length'];
    }

    $remote = @fopen(UPDATE_ZIP_URL, 'rb');
    if (!$remote) {
        sendMsg('error', 0, "[CHYBA] Nelze se připojit ke zdroji aktualizace. Zkontrolujte URL.", true);
        exit;
    }

    $local = @fopen($zipFile, 'wb');
    if (!$local) {
        sendMsg('error', 0, "[CHYBA] Nelze vytvořit dočasný soubor na serveru. Zkontrolujte oprávnění složky.", true);
        exit;
    }

    $downloaded = 0;
    $lastProgress = -1;
    
    // Čtení vzdáleného souboru po částech (chunk)
    while (!feof($remote)) {
        $chunk = fread($remote, 8192);
        fwrite($local, $chunk);
        $downloaded += strlen($chunk);

        if ($fileSize > 0) {
            $progress = round(($downloaded / $fileSize) * 100);
            if ($progress > $lastProgress) {
                sendMsg('download', $progress, "Stahování... {$progress}%");
                $lastProgress = $progress;
            }
        } else {
            // Pokud server nepošle velikost, alespoň vypisujeme stažené MB
            $mb = round($downloaded / 1048576, 2);
            sendMsg('download', 50, "Stahování... staženo {$mb} MB");
        }
    }
    fclose($remote);
    fclose($local);
    sendMsg('download', 100, "Stahování úspěšně dokončeno.");

    // Fáze 2: Zálohování stávajících souborů
    sendMsg('backup', 0, "Vytvářím zálohu současného stavu (backup.zip)...");
    $backupFile = __DIR__ . '/backup.zip';
    if (file_exists($backupFile)) {
        @unlink($backupFile); // Smazání staré zálohy, pokud existuje
    }
    
    $backupZip = new ZipArchive;
    if ($backupZip->open($backupFile, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
        $dirIterator = new RecursiveDirectoryIterator(__DIR__, FilesystemIterator::SKIP_DOTS);
        $files = new RecursiveIteratorIterator($dirIterator, RecursiveIteratorIterator::LEAVES_ONLY);
        
        $filesToBackup = [];
        foreach ($files as $file) {
            $filePath = $file->getRealPath();
            // Do zálohy nezahrnujeme čerstvě stažený update ani samotný backup soubor
            if ($filePath !== $zipFile && $filePath !== $backupFile) {
                $filesToBackup[] = $filePath;
            }
        }

        $totalBackupFiles = count($filesToBackup);
        sendMsg('backup', 0, "Nalezeno celkem {$totalBackupFiles} souborů k zálohování.");

        $backupIndex = 0;
        foreach ($filesToBackup as $filePath) {
            $relativePath = substr($filePath, strlen(__DIR__) + 1);
            $backupZip->addFile($filePath, $relativePath);
            
            $backupIndex++;
            // Optimalizace výpisu: posíláme průběh po blocích, aby nebyl terminál přehlcen
            if ($backupIndex % 10 === 0 || $backupIndex === $totalBackupFiles) {
                $progress = round(($backupIndex / $totalBackupFiles) * 100);
                sendMsg('backup', $progress, "Zálohuji: " . basename($filePath) . " ... {$progress}%");
            }
        }
        
        sendMsg('backup', 99, "Ukládám archiv backup.zip na disk (toto může chvíli trvat)...");
        $backupZip->close();
        sendMsg('backup', 100, "Zálohování bylo úspěšně dokončeno.");
    } else {
        sendMsg('error', 0, "[CHYBA] Nepodařilo se vytvořit záložní archiv backup.zip.", true);
        exit;
    }

    // Fáze 3: Rozbalování
    sendMsg('extract', 0, "Otevírám stažený ZIP archiv...");
    $zip = new ZipArchive;
    $res = $zip->open($zipFile);
    
    if ($res === TRUE) {
        $totalFiles = $zip->numFiles;
        sendMsg('extract', 0, "Nalezeno celkem {$totalFiles} souborů k rozbalení.");

        for ($i = 0; $i < $totalFiles; $i++) {
            $filename = $zip->getNameIndex($i);
            // Rozbalí a automaticky přepíše existující
            $zip->extractTo(__DIR__, array($filename));
            $progress = round((($i + 1) / $totalFiles) * 100);

            // Vypíše aktuálně rozbalovaný soubor do terminálu
            sendMsg('extract', $progress, "Rozbaluji: {$filename} ... {$progress}%");
        }
        $zip->close();
        sendMsg('extract', 100, "Rozbalování dokončeno.");
    } else {
        sendMsg('error', 0, "[CHYBA] Nelze otevřít ZIP archiv (Kód: $res).", true);
        exit;
    }

    // Fáze 4: Úklid
    if (file_exists($zipFile)) {
        unlink($zipFile);
        sendMsg('cleanup', 100, "Úklid: Dočasný instalační soubor byl smazán.");
    }

    // Fáze 5: Notifikace
    if (defined('UPDATE_NOTIFY_EMAIL') && !empty(UPDATE_NOTIFY_EMAIL)) {
        sendMsg('notify', 100, "Odesílám informační e-mail na " . UPDATE_NOTIFY_EMAIL . "...");
        
        $domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'Neznámá doména';
        $date = date('d.m.Y H:i:s');
        
        $subject = "Aktualizace systemu uspesna - $domain";
        $message = "Dobrý den,\n\n"
                 . "aktualizace systému na doméně $domain byla úspěšně dokončena.\n\n"
                 . "Podrobnosti k aktualizaci:\n"
                 . "- Doména: $domain\n"
                 . "- Absolutní cesta: " . __DIR__ . "\n"
                 . "- Čas dokončení: $date\n"
                 . "- Zdroj aktualizace: " . UPDATE_ZIP_URL . "\n\n"
                 . "Tato zpráva je automatická.";
                 
        $headers = "From: noreply@$domain\r\n"
                 . "Reply-To: noreply@$domain\r\n"
                 . "X-Mailer: PHP/" . phpversion();
                 
        if (@mail(UPDATE_NOTIFY_EMAIL, $subject, $message, $headers)) {
            sendMsg('notify', 100, "E-mail byl úspěšně odeslán.");
        } else {
            sendMsg('notify', 100, "[VAROVÁNÍ] E-mail se nepodařilo odeslat. Zkontrolujte nastavení serveru.");
        }
    }

    sendMsg('done', 100, "Aktualizace byla úspěšně dokončena!", true);
    exit;
}
?>
<!DOCTYPE html>
<html lang="cs">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Aktualizace Systému</title>
    <style>
        :root {
            --primary: #00ffcc; /* Zářivá neonově tyrkysová (Glow) */
            --bg: #121212;
            --glass-bg: rgba(255, 255, 255, 0.03);
            --glass-border: rgba(255, 255, 255, 0.08);
        }
        body {
            margin: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--bg);
            color: #fff;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background-image: radial-gradient(circle at top left, #2a2a2a, #0a0a0a);
        }
        .container {
            width: 90%;
            max-width: 800px;
            background: var(--glass-bg);
            backdrop-filter: blur(16px);
            -webkit-backdrop-filter: blur(16px);
            border: 1px solid var(--glass-border);
            border-radius: 24px;
            padding: 50px;
            box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
            text-align: center;
        }
        h1 { margin-top: 0; font-weight: 300; letter-spacing: 2px; }
        .btn {
            background: rgba(0, 255, 204, 0.05);
            border: 1px solid var(--primary);
            color: var(--primary);
            padding: 16px 36px;
            font-size: 1.1rem;
            border-radius: 12px;
            cursor: pointer;
            transition: all 0.3s ease;
            text-transform: uppercase;
            letter-spacing: 2px;
            box-shadow: 0 0 15px rgba(0, 255, 204, 0.2);
            margin: 20px 0;
            text-decoration: none;
            display: inline-block;
            font-weight: 600;
        }
        .btn:hover {
            background: var(--primary);
            color: #000;
            box-shadow: 0 0 30px rgba(0, 255, 204, 0.7);
        }
        .progress-container { display: none; margin-top: 40px; text-align: left; }
        .progress-bar-bg {
            width: 100%; height: 12px; background: rgba(0,0,0,0.6);
            border-radius: 10px; overflow: hidden; border: 1px solid var(--glass-border);
        }
        .progress-bar {
            height: 100%; width: 0%; background: var(--primary);
            box-shadow: 0 0 15px var(--primary); transition: width 0.2s linear;
        }
        .status-text { margin-top: 10px; font-size: 0.9rem; color: #aaa; font-weight: 500;}
        .terminal {
            display: none; margin-top: 30px; background: #050505;
            border: 1px solid #222; border-radius: 12px; padding: 20px;
            height: 280px; overflow-y: auto; text-align: left;
            font-family: 'Consolas', 'Courier New', monospace; font-size: 13px;
            color: #0f0; box-shadow: inset 0 0 20px rgba(0,0,0,1);
        }
        .terminal p { margin: 4px 0; line-height: 1.4; }
        .terminal .error-msg { color: #ff3333; }
        #btn-run { display: none; }
        
        /* Custom Scrollbar pro terminál */
        .terminal::-webkit-scrollbar { width: 8px; }
        .terminal::-webkit-scrollbar-track { background: #111; }
        .terminal::-webkit-scrollbar-thumb { background: #333; border-radius: 4px; }
        .terminal::-webkit-scrollbar-thumb:hover { background: #555; }
    </style>
</head>
<body>

<div class="container">
    <h1>Aktualizace Systému</h1>
    <p style="color: #bbb; margin-bottom: 40px;">Bude stažena a aplikována nejnovější verze.</p>

    <button id="btn-update" class="btn" onclick="startUpdate()">Aktualizovat</button>
    <a id="btn-run" class="btn" href="<?= AFTER_UPDATE_SCRIPT ?>">Spustit aktualizovaný systém</a>

    <div class="progress-container" id="progress-container">
        <div class="progress-bar-bg">
            <div class="progress-bar" id="progress-bar"></div>
        </div>
        <div class="status-text" id="status-text">Připravuji spojení...</div>
    </div>

    <div class="terminal" id="terminal"></div>
</div>

<script>
    function logToTerminal(message, isError = false) {
        const terminal = document.getElementById('terminal');
        const p = document.createElement('p');
        p.textContent = '> ' + message;
        if (isError) p.classList.add('error-msg');
        terminal.appendChild(p);
        terminal.scrollTop = terminal.scrollHeight; // Automatický odscrollování dolů
    }

    function updateProgress(percent, text) {
        document.getElementById('progress-bar').style.width = percent + '%';
        document.getElementById('status-text').textContent = text;
    }

    function startUpdate() {
        document.getElementById('btn-update').style.display = 'none';
        document.getElementById('progress-container').style.display = 'block';
        document.getElementById('terminal').style.display = 'block';
        logToTerminal('Inicializace aktualizačního procesu...');

        // Otevření spojení se serverem pro získávání reálných dat
        const source = new EventSource('?action=update');

        source.onmessage = function(event) {
            try {
                const data = JSON.parse(event.data);

                if (data.log) {
                    logToTerminal(data.log, data.step === 'error');
                }
                
                if (data.progress !== undefined) {
                    let prefix = data.step === 'download' ? 'Stahuji' : 
                                 (data.step === 'backup' ? 'Zálohuji' : 
                                 (data.step === 'extract' ? 'Rozbaluji' : 'Zpracovávám'));
                    if(data.step === 'cleanup' || data.step === 'done' || data.step === 'notify') prefix = 'Dokončování';
                    updateProgress(data.progress, `${prefix}... ${data.progress}%`);
                }
                
                if (data.done) {
                    source.close();
                    if (data.step !== 'error') {
                        document.getElementById('btn-run').style.display = 'inline-block';
                        updateProgress(100, 'Aktualizace úspěšná.');
                    } else {
                        updateProgress(100, 'Aktualizace selhala.');
                        document.getElementById('progress-bar').style.backgroundColor = '#ff3333';
                        document.getElementById('progress-bar').style.boxShadow = '0 0 15px #ff3333';
                    }
                }
            } catch(e) {
                console.error('Chyba při čtení dat ze serveru.', e);
            }
        };

        source.onerror = function() {
            logToTerminal('[CHYBA SÍTĚ] Připojení k serveru bylo nečekaně ukončeno.', true);
            source.close();
        };
    }
</script>
</body>
</html>