<?php
/**
 * Rig N Dig - Site Updater PRO
 * Upload a ZIP package to update site files without FTP/cPanel access
 * Only accessible to super_admin role
 */

$adminTitle = 'Site Updater';
require_once __DIR__ . '/includes/header.php';

if ($_SESSION['admin_role'] !== 'super_admin') {
    echo '<div class="text-red-400 p-4">Access denied. Super Admin role required.</div>';
    include __DIR__ . '/includes/footer.php';
    exit;
}

$updateLog   = Database::fetchAll("SELECT u.*, a.name as admin_name FROM update_log u LEFT JOIN admins a ON u.applied_by=a.id ORDER BY u.applied_at DESC LIMIT 20");
$currentVer  = setting('current_version', APP_VERSION);
$messages    = [];
$errors      = [];

// ── Handle ZIP upload ──────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($_FILES) && empty($_POST)) {
    $contentLength = (int)($_SERVER['CONTENT_LENGTH'] ?? 0);
    $postMaxBytes  = (int)ini_get('post_max_size') * 1024 * 1024;
    if ($contentLength > 0 && $postMaxBytes > 0 && $contentLength > $postMaxBytes) {
        $errors[] = 'Upload rejected: ZIP exceeds server limit (' . ini_get('post_max_size') . ').';
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['update_zip'])) {
    $file = $_FILES['update_zip'];
    if ($file['error'] !== UPLOAD_ERR_OK) {
        $errors[] = 'Upload error. Code: ' . $file['error'];
    } else {
        $tmpZip = ROOT_PATH . '/logs/update_' . time() . '.zip';
        if (!move_uploaded_file($file['tmp_name'], $tmpZip)) {
            $errors[] = 'Could not save uploaded file to logs/ directory.';
        } else {
            if (!class_exists('ZipArchive')) {
                $errors[] = 'CRITICAL: PHP ZipArchive extension is missing on this server.';
                @unlink($tmpZip);
            } else {
                $zip = new ZipArchive();
                if ($zip->open($tmpZip) !== true) {
                    $errors[] = 'Could not open ZIP archive.';
                    @unlink($tmpZip);
                } else {
                    // 1. Detect common root folder (e.g. v22_pkg/ or rigndig-LATEST/)
                    $commonRoot = '';
                    $firstFile = $zip->getNameIndex(0);
                    if ($firstFile && strpos($firstFile, '/') !== false) {
                        $parts = explode('/', $firstFile);
                        $rootName = $parts[0];
                        $isConsistent = true;
                        for ($i = 0; $i < $zip->numFiles; $i++) {
                            $thisName = $zip->getNameIndex($i);
                            if ($thisName !== $rootName && strpos($thisName, $rootName . '/') !== 0) {
                                $isConsistent = false;
                                break;
                            }
                        }
                        if ($isConsistent) $commonRoot = $rootName . '/';
                    }

                    // 2. Read Manifest & SQL
                    $manifestRaw = $zip->getFromName($commonRoot . 'update_manifest.json');
                    $manifest    = $manifestRaw ? json_decode($manifestRaw, true) : null;
                    $updateSQL   = $zip->getFromName($commonRoot . 'update.sql');
                    $newVersion  = $manifest['version'] ?? ($_POST['version'] ?? 'manual');
                    $notes       = sanitize($_POST['notes'] ?? '');

                    // 3. Backup Dir
                    $backupDir = ROOT_PATH . '/logs/backup_' . date('Ymd_His');
                    @mkdir($backupDir, 0755, true);

                    $protected = ['config/config.php', 'uploads/documents/', 'uploads/repair/', 'logs/', '.htaccess'];
                    $extracted = 0;
                    $skipped   = 0;

                    // 4. Extraction Loop
                    for ($i = 0; $i < $zip->numFiles; $i++) {
                        $rawName = $zip->getNameIndex($i);
                        if (!$rawName || $rawName === $commonRoot) continue;

                        $filename = $rawName;
                        if ($commonRoot && strpos($filename, $commonRoot) === 0) {
                            $filename = substr($filename, strlen($commonRoot));
                        }
                        $filename = ltrim($filename, '/');
                        if (!$filename) continue;

                        // Skip protected
                        $isProtected = false;
                        foreach ($protected as $p) {
                            if (strpos($filename, $p) === 0) { $isProtected = true; break; }
                        }
                        if ($isProtected) { $skipped++; continue; }
                        if (in_array($filename, ['update_manifest.json', 'update.sql'])) continue;
                        if (strpos($filename, '..') !== false) continue;

                        $dest = ROOT_PATH . '/' . $filename;
                        $dir  = dirname($dest);

                        if (substr($rawName, -1) === '/') {
                             @mkdir($dest, 0755, true);
                        } else {
                            if (!is_dir($dir)) @mkdir($dir, 0755, true);
                            if (file_exists($dest)) {
                                $bPath = $backupDir . '/' . str_replace('/', '_', $filename);
                                @copy($dest, $bPath);
                            }
                            
                            $content = $zip->getFromIndex($i);
                            $success = @file_put_contents($dest, $content);
                            
                            if ($success === false) {
                                @chmod($dir, 0777); 
                                @chmod($dest, 0666);
                                $success = @file_put_contents($dest, $content);
                            }
                            
                            if ($success !== false) {
                                $extracted++;
                                @chmod($dest, 0644);
                            } else {
                                $errors[] = "Permission Denied: $filename";
                            }
                        }
                    }
                    $zip->close();
                    @unlink($tmpZip);

                    // 5. Database Multi-Query
                    $sqlRan = 0;
                    $sqlErrors = [];
                    if ($updateSQL) {
                        try {
                            $mdb = new \mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT ?: 3306);
                            if (!$mdb->connect_errno) {
                                $mdb->set_charset('utf8mb4');
                                if ($mdb->multi_query($updateSQL)) {
                                    do { $sqlRan++; } while ($mdb->more_results() && $mdb->next_result());
                                }
                                if ($mdb->errno && $mdb->errno !== 1062) $sqlErrors[] = $mdb->error;
                                $mdb->close();
                            }
                        } catch (\Throwable $e) { $sqlErrors[] = $e->getMessage(); }
                    }

                    // 6. Finishing
                    Database::execute("UPDATE settings SET setting_value=? WHERE setting_key='current_version'", [$newVersion]);
                    $logNote = "Files: $extracted. SQL: $sqlRan. " . $notes;
                    Database::insert("INSERT INTO update_log (version, notes, applied_by) VALUES (?,?,?)", [$newVersion, $logNote, $_SESSION['admin_id']]);
                    
                    $messages[] = "✅ <strong>Update Applied!</strong> Version v$newVersion. Files: $extracted. SQL: $sqlRan.";
                    if ($sqlErrors) foreach($sqlErrors as $se) $errors[] = "SQL Error: $se";
                    $currentVer = $newVersion;
                    if (function_exists('opcache_reset')) opcache_reset();
                }
            }
        }
    }
}
?>

<div class="max-w-4xl">
  <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
    <div class="card-dark p-5">
      <div class="text-xs text-gray-400 mb-1">Current Version</div>
      <div class="text-2xl font-bold text-orange-500">v<?= e($currentVer) ?></div>
    </div>
    <div class="card-dark p-5">
      <div class="text-xs text-gray-400 mb-1">Updates Applied</div>
      <div class="text-2xl font-bold"><?= count($updateLog) ?></div>
    </div>
    <div class="card-dark p-5">
      <div class="text-xs text-gray-400 mb-1">Status</div>
      <div class="text-2xl font-bold text-green-400">READY</div>
    </div>
  </div>

  <?php foreach ($messages as $m): ?><div class="bg-green-900 border border-green-600 text-green-200 rounded p-4 mb-4 text-sm"><?= $m ?></div><?php endforeach; ?>
  <?php foreach ($errors as $e): ?><div class="bg-red-900 border border-red-600 text-red-200 rounded p-4 mb-4 text-sm"><?= $e ?></div><?php endforeach; ?>

  <div class="card-dark p-6 mb-8">
    <h2 class="font-semibold text-lg mb-2">Platform Elevation Hub</h2>
    <p class="text-sm text-gray-400 mb-6">Upload an ELITE update package to synchronize site files and database schemas.</p>

    <form method="POST" enctype="multipart/form-data">
      <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
        <div>
          <label class="text-xs text-orange-500 font-bold uppercase tracking-widest block mb-2">Update Package (ZIP)</label>
          <div class="relative group">
            <input type="file" name="update_zip" accept=".zip" required class="block w-full text-sm text-gray-400 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-bold file:bg-navy-700 file:text-orange-500 hover:file:bg-navy-600 cursor-pointer">
          </div>
        </div>
        <div>
          <label class="text-xs text-gray-500 font-bold uppercase tracking-widest block mb-2">Override Version</label>
          <input type="text" name="version" placeholder="e.g. 2.2.1" value="<?= e($currentVer) ?>">
        </div>
      </div>
      <div class="mb-6">
        <label class="text-xs text-gray-500 font-bold uppercase tracking-widest block mb-2">Migration Notes</label>
        <textarea name="notes" rows="2" placeholder="Describe the changes in this manual deployment..."></textarea>
      </div>
      <button type="submit" class="bg-orange-600 hover:bg-orange-700 text-white px-8 py-3 rounded-xl font-bold transition-all shadow-xl shadow-orange-900/20 flex items-center gap-3">
        🚀 DEPLOY UPDATE
      </button>
    </form>
  </div>

  <div class="card-dark overflow-hidden">
    <div class="p-4 border-b border-navy-500 bg-navy-800"><h3 class="font-bold text-xs uppercase tracking-widest text-gray-400">Update Ledger</h3></div>
    <table class="data-table">
      <thead><tr><th>Version</th><th>Results</th><th class="hidden md:table-cell">Applied By</th><th>Timestamp</th></tr></thead>
      <tbody>
      <?php foreach ($updateLog as $log): ?>
      <tr>
        <td class="font-black text-orange-500 whitespace-nowrap">v<?= e($log['version']) ?></td>
        <td class="text-xs"><?= e($log['notes']) ?></td>
        <td class="text-xs hidden md:table-cell"><?= e($log['admin_name'] ?? 'System') ?></td>
        <td class="text-[10px] text-gray-500"><?= formatDate($log['applied_at']) ?></td>
      </tr>
      <?php endforeach; ?>
      </tbody>
    </table>
  </div>
</div>

<?php include __DIR__ . '/includes/footer.php'; ?>
