<?php
/**
 * Slate — Plugin manager.
 *
 * Session 2: full UI on top of the PluginLoader API. Super-admins
 * can upload a plugin ZIP, then activate, deactivate, or uninstall
 * each plugin from the card-row actions.
 *
 * All state-changing endpoints are POST with CSRF + permission checks
 * and audit-log entries.
 */
require_once dirname(__DIR__) . '/config.php';
Auth::require();
Auth::requirePerm('plugins.manage');

$pageTitle  = __('plugins', 'Plugins');
$currentNav = 'plugins';

// 10 MB upload cap (also gated by PHP's upload_max_filesize / post_max_size).
const SLATE_PLUGIN_UPLOAD_MAX = 10 * 1024 * 1024;

// ─────────────────────────────────────────────────────────────
// POST handlers — must run before header.php (output buffering)
// ─────────────────────────────────────────────────────────────
$flash = null;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!csrf_verify()) {
        $flash = ['type' => 'error', 'msg' => __('csrf_failed', 'Security check failed.')];
    } else {
        $action = $_POST['_action'] ?? '';

        // ─── Upload ────────────────────────────────────────────
        if ($action === 'upload') {
            if (!Auth::isSuperAdmin()) {
                $flash = ['type' => 'error', 'msg' => __('only_super_admin', 'Only super-admins can upload plugins.')];
            } elseif (empty($_FILES['plugin_zip']) || $_FILES['plugin_zip']['error'] === UPLOAD_ERR_NO_FILE) {
                $flash = ['type' => 'error', 'msg' => __('no_file', 'No file selected.')];
            } else {
                $file = $_FILES['plugin_zip'];
                $err  = $file['error'];

                if ($err !== UPLOAD_ERR_OK) {
                    $msg = match ($err) {
                        UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE =>
                            __('upload_too_large', 'Upload too large. Max 10 MB.'),
                        UPLOAD_ERR_PARTIAL =>
                            __('upload_partial', 'Upload was interrupted. Try again.'),
                        UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE =>
                            __('upload_server_error', 'Server could not store the upload.'),
                        default => __('upload_failed', 'Upload failed.'),
                    };
                    $flash = ['type' => 'error', 'msg' => $msg];
                } elseif ($file['size'] > SLATE_PLUGIN_UPLOAD_MAX) {
                    $flash = ['type' => 'error',
                              'msg'  => __('upload_too_large', 'Upload too large. Max 10 MB.')];
                } elseif (!is_uploaded_file($file['tmp_name'])) {
                    $flash = ['type' => 'error', 'msg' => __('upload_invalid', 'Invalid upload.')];
                } else {
                    // Cheap MIME / extension sanity check
                    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
                    if ($ext !== 'zip') {
                        $flash = ['type' => 'error',
                                  'msg' => __('upload_not_zip', 'File must be a .zip archive.')];
                    } else {
                        $res = PluginLoader::install($file['tmp_name']);
                        if ($res['ok']) {
                            $slug = $res['slug'] ?? '?';
                            AuditLog::record('plugin.installed', $slug);
                            $flash = ['type' => 'success',
                                      'msg' => sprintf(
                                          __('plugin_installed', 'Plugin "%s" installed. Click Activate to enable it.'),
                                          $slug)];
                        } else {
                            $flash = ['type' => 'error', 'msg' => $res['error']];
                        }
                    }
                }
            }
        }

        // ─── Activate ──────────────────────────────────────────
        elseif ($action === 'activate') {
            $slug = trim((string)($_POST['slug'] ?? ''));
            if ($slug === '') {
                $flash = ['type' => 'error', 'msg' => __('missing_slug', 'Missing plugin slug.')];
            } else {
                $res = PluginLoader::activate($slug);
                if ($res['ok']) {
                    AuditLog::record('plugin.activated', $slug);
                    $flash = ['type' => 'success',
                              'msg' => sprintf(__('plugin_activated', 'Plugin "%s" activated.'), $slug)];
                } else {
                    $flash = ['type' => 'error', 'msg' => $res['error']];
                }
            }
        }

        // ─── Deactivate ────────────────────────────────────────
        elseif ($action === 'deactivate') {
            $slug = trim((string)($_POST['slug'] ?? ''));
            if ($slug === '') {
                $flash = ['type' => 'error', 'msg' => __('missing_slug', 'Missing plugin slug.')];
            } else {
                $res = PluginLoader::deactivate($slug);
                if ($res['ok']) {
                    AuditLog::record('plugin.deactivated', $slug);
                    $flash = ['type' => 'success',
                              'msg' => sprintf(__('plugin_deactivated', 'Plugin "%s" deactivated.'), $slug)];
                } else {
                    $flash = ['type' => 'error', 'msg' => $res['error']];
                }
            }
        }

        // ─── Uninstall ─────────────────────────────────────────
        elseif ($action === 'uninstall') {
            if (!Auth::isSuperAdmin()) {
                $flash = ['type' => 'error', 'msg' => __('only_super_admin', 'Only super-admins can uninstall plugins.')];
            } else {
                $slug = trim((string)($_POST['slug'] ?? ''));
                if ($slug === '') {
                    $flash = ['type' => 'error', 'msg' => __('missing_slug', 'Missing plugin slug.')];
                } else {
                    $res = PluginLoader::uninstall($slug);
                    if ($res['ok']) {
                        AuditLog::record('plugin.uninstalled', $slug);
                        $flash = ['type' => 'success',
                                  'msg' => sprintf(__('plugin_uninstalled', 'Plugin "%s" uninstalled. All data removed.'), $slug)];
                    } else {
                        $flash = ['type' => 'error', 'msg' => $res['error']];
                    }
                }
            }
        }
    }
}

// ─────────────────────────────────────────────────────────────
// Page render
// ─────────────────────────────────────────────────────────────
require __DIR__ . '/partials/header.php';

$plugins         = PluginLoader::listAll();
$canUpload       = Auth::isSuperAdmin();
$canUninstall    = Auth::isSuperAdmin();
$hasExampleZip   = file_exists(SLATE_ROOT . '/plugins/_dist/hello-world-v1.0.0.zip');
?>

<?php slate_breadcrumbs([
    ['label' => __('dashboard', 'Dashboard'), 'href' => SLATE_URL . '/admin/'],
    ['label' => __('plugins', 'Plugins')],
]); ?>

<div class="page-header">
    <div>
        <h1><?= __('plugins', 'Plugins') ?></h1>
        <p class="page-header-sub">
            <?= __('plugins_subtitle', 'Add functionality to Slate by installing plugins.') ?>
        </p>
    </div>
</div>

<?php if ($flash): ?>
    <div class="alert alert-<?= e($flash['type']) ?>" role="status"><?= e($flash['msg']) ?></div>
<?php endif; ?>

<?php if ($canUpload): ?>
<div class="card">
    <div class="card-header">
        <h2><?= __('upload_plugin', 'Upload a plugin') ?></h2>
        <?php if ($hasExampleZip): ?>
            <a href="<?= e(SLATE_URL) ?>/plugins/_dist/hello-world-v1.0.0.zip"
               class="btn btn-sm">
                <?= __('download_example', 'Download example plugin') ?>
            </a>
        <?php endif; ?>
    </div>
    <p class="text-muted text-sm mb-3">
        <?= __('upload_hint', 'Upload a .zip file containing a single plugin folder. Max 10 MB.') ?>
    </p>
    <form method="post" enctype="multipart/form-data">
        <?= csrf_field() ?>
        <input type="hidden" name="_action" value="upload">
        <input type="hidden" name="MAX_FILE_SIZE" value="<?= SLATE_PLUGIN_UPLOAD_MAX ?>">

        <div class="field">
            <label class="field-label" for="plugin_zip">
                <?= __('plugin_zip', 'Plugin ZIP file') ?>
            </label>
            <input type="file" id="plugin_zip" name="plugin_zip"
                   accept=".zip,application/zip" required>
        </div>

        <button type="submit" class="btn btn-primary">
            <?= __('upload_and_install', 'Upload &amp; install') ?>
        </button>
    </form>
</div>
<?php endif; ?>

<?php if (empty($plugins)): ?>
    <div class="card">
        <div class="empty">
            <svg class="empty-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                 stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
                <path d="M21 8l-9-5-9 5v8l9 5 9-5V8zM3 8l9 5 9-5M12 13v9"/>
            </svg>
            <div class="empty-title"><?= __('no_plugins_installed', 'No plugins installed') ?></div>
            <p>
                <?= __('no_plugins_intro',
                    'Slate is a clean shell right now. Upload your first plugin above.') ?>
            </p>
        </div>
    </div>
<?php else: ?>
    <div class="card-header">
        <h2><?= __('installed_plugins', 'Installed plugins') ?></h2>
        <span class="text-muted text-sm"><?= count($plugins) ?></span>
    </div>
    <div class="data-list" data-single-open>
        <?php foreach ($plugins as $p):
            $status      = $p['status'];
            $statusColor = match($status) {
                'active'    => 'success',
                'installed' => 'info',
                'inactive'  => 'muted',
                default     => 'muted',
            };
            $manifest = json_decode($p['manifest_json'] ?? '{}', true) ?: [];
            $author   = $manifest['author']      ?? '—';
            $desc     = $manifest['description'] ?? '';
            $homepage = $manifest['homepage']    ?? '';

            // Build action buttons based on status
            ob_start();
            ?>
            <?php if ($status === 'active'): ?>
                <form method="post" style="margin:0">
                    <?= csrf_field() ?>
                    <input type="hidden" name="_action" value="deactivate">
                    <input type="hidden" name="slug" value="<?= e($p['slug']) ?>">
                    <button type="submit" class="btn btn-sm"><?= __('deactivate', 'Deactivate') ?></button>
                </form>
            <?php elseif ($status === 'inactive' || $status === 'installed'): ?>
                <form method="post" style="margin:0">
                    <?= csrf_field() ?>
                    <input type="hidden" name="_action" value="activate">
                    <input type="hidden" name="slug" value="<?= e($p['slug']) ?>">
                    <button type="submit" class="btn btn-sm btn-primary"><?= __('activate', 'Activate') ?></button>
                </form>
            <?php endif; ?>

            <?php if ($canUninstall && $status !== 'active'): ?>
                <form method="post" style="margin:0"
                      onsubmit="return confirm(<?= e(json_encode(
                          sprintf(__('confirm_uninstall',
                              "Uninstall %s? This will delete all of this plugin's data and cannot be undone."),
                              $p['slug']))) ?>);">
                    <?= csrf_field() ?>
                    <input type="hidden" name="_action" value="uninstall">
                    <input type="hidden" name="slug" value="<?= e($p['slug']) ?>">
                    <button type="submit" class="btn btn-sm btn-danger"><?= __('uninstall', 'Uninstall') ?></button>
                </form>
            <?php endif; ?>
            <?php
            $actionsHtml = ob_get_clean();

            // Build detail entries
            $detail = [
                'Slug'      => $p['slug'],
                'Version'   => $p['version'],
                'Status'    => ['label' => 'Status', 'html' =>
                    '<span class="badge badge-' . e($status) . '">' . e(__($status, $status)) . '</span>'],
                'Author'    => $author,
                'Installed' => $p['installed_at'] ?: '—',
            ];
            if ($p['activated_at'] ?? null) {
                $detail['Activated'] = $p['activated_at'];
            }
            if ($homepage !== '') {
                $detail['Homepage'] = ['label' => 'Homepage', 'html' =>
                    '<a href="' . e($homepage) . '" target="_blank" rel="noopener">' . e($homepage) . '</a>'];
            }
            if ($desc !== '') {
                $detail['Description'] = ['label' => 'Description', 'value' => $desc, 'muted' => true];
            }

            slate_data_row([
                'avatar'       => mb_substr($p['name'], 0, 2),
                'avatar_color' => $statusColor,
                'title'        => $p['name'],
                'meta'         => $p['slug'] . ' · v' . $p['version'],
                'badge'        => [__($status, $status), $status],
                'detail'       => $detail,
                'actions'      => trim($actionsHtml) !== '' ? $actionsHtml : null,
            ]);
        endforeach; ?>
    </div>
    <?php slate_data_list_script(); ?>
<?php endif; ?>

<?php require __DIR__ . '/partials/footer.php'; ?>
