<?php
declare(strict_types=1);

require __DIR__ . '/../app/bootstrap.php';
$db = DB::connection();
$page = preg_replace('/[^a-z0-9_-]/', '', (string)($_GET['page'] ?? 'dashboard')) ?: 'dashboard';

function admin_url(string $page = 'dashboard', array $params = []): string
{
    $params = array_merge(['page' => $page], $params);
    return app_url('admin/?' . http_build_query($params));
}

function admin_header(string $title): void
{
    header('Content-Type: text/html; charset=UTF-8');
    ?><!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="robots" content="noindex,nofollow"><title><?= e($title) ?> | GamesJi Admin</title><link rel="stylesheet" href="<?= e(app_url('assets/app.css?v=' . APP_VERSION)) ?>"></head><body class="admin-body">
    <header class="admin-top"><a class="brand" href="<?= e(admin_url()) ?>"><img src="<?= e(app_url('assets/icon.svg')) ?>" width="34" height="34" alt="">GamesJi Admin</a><?php if (is_admin()): ?><div><a href="<?= e(app_url()) ?>" target="_blank">View site</a><a href="<?= e(admin_url('logout')) ?>">Log out</a></div><?php endif; ?></header>
    <?php if (is_admin()): ?><div class="admin-shell"><aside class="admin-nav">
      <?php foreach ([
          'dashboard' => 'Dashboard', 'games' => 'Games', 'import' => 'Import',
          'sources' => 'Sources', 'reports' => 'Reports', 'contacts' => 'Messages',
          'settings' => 'Settings & Ads', 'activity' => 'Activity', 'health' => 'Health'
      ] as $route => $label): ?><a class="<?= (($_GET['page'] ?? 'dashboard') === $route) ? 'active' : '' ?>" href="<?= e(admin_url($route)) ?>"><?= e($label) ?></a><?php endforeach; ?>
    </aside><main class="admin-main"><?php else: ?><main class="login-wrap"><?php endif; render_flashes();
}

function admin_footer(): void
{
    ?></main><?php if (is_admin()): ?></div><?php endif; ?><script src="<?= e(app_url('assets/app.js?v=' . APP_VERSION)) ?>" defer></script></body></html><?php
}

if ($page === 'logout') {
    if (is_admin()) {
        admin_activity('logout');
    }
    $_SESSION = [];
    session_regenerate_id(true);
    header('Location: ' . app_url('admin/'));
    exit;
}

if (!is_admin()) {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $email = strtolower(trim((string)($_POST['email'] ?? '')));
        $password = (string)($_POST['password'] ?? '');
        $stmt = $db->prepare('SELECT * FROM admins WHERE email=? LIMIT 1');
        $stmt->execute([$email]);
        $admin = $stmt->fetch();
        if ($admin && $admin['locked_until'] && strtotime($admin['locked_until']) > time()) {
            flash('error', 'Account is temporarily locked. Try again later.');
        } elseif ($admin && password_verify($password, $admin['password_hash'])) {
            session_regenerate_id(true);
            $_SESSION['admin_id'] = (int)$admin['id'];
            $_SESSION['admin_name'] = $admin['name'];
            $_SESSION['force_password_change'] = (bool)$admin['force_password_change'];
            $db->prepare('UPDATE admins SET failed_attempts=0,locked_until=NULL,last_login_at=NOW() WHERE id=?')->execute([(int)$admin['id']]);
            admin_activity('login');
            header('Location: ' . admin_url($_SESSION['force_password_change'] ? 'password' : 'dashboard'));
            exit;
        } else {
            if ($admin) {
                $failed = (int)$admin['failed_attempts'] + 1;
                $lock = $failed >= 5 ? date('Y-m-d H:i:s', time() + 900) : null;
                $db->prepare('UPDATE admins SET failed_attempts=?,locked_until=? WHERE id=?')->execute([$failed, $lock, (int)$admin['id']]);
            }
            usleep(400000);
            flash('error', 'Email or password is incorrect.');
        }
        header('Location: ' . app_url('admin/'));
        exit;
    }
    admin_header('Login');
    ?><section class="login-card"><img src="<?= e(app_url('assets/icon.svg')) ?>" width="70" height="70" alt=""><h1>Admin login</h1><p>Manage discovery, imports, SEO and ads.</p><form class="form-grid" method="post"><?= csrf_field() ?><label>Email<input type="email" name="email" required autocomplete="username"></label><label>Password<input type="password" name="password" required autocomplete="current-password"></label><button class="primary" type="submit">Log in</button></form></section><?php
    admin_footer();
    exit;
}

if (!empty($_SESSION['force_password_change']) && $page !== 'password') {
    header('Location: ' . admin_url('password'));
    exit;
}

if ($page === 'password') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $current = (string)($_POST['current_password'] ?? '');
        $new = (string)($_POST['new_password'] ?? '');
        $stmt = $db->prepare('SELECT password_hash FROM admins WHERE id=?');
        $stmt->execute([(int)$_SESSION['admin_id']]);
        $hash = (string)$stmt->fetchColumn();
        if (!password_verify($current, $hash)) {
            flash('error', 'Current password is incorrect.');
        } elseif (strlen($new) < 12) {
            flash('error', 'New password must contain at least 12 characters.');
        } else {
            $db->prepare('UPDATE admins SET password_hash=?,force_password_change=0 WHERE id=?')->execute([password_hash($new, PASSWORD_DEFAULT), (int)$_SESSION['admin_id']]);
            $_SESSION['force_password_change'] = false;
            admin_activity('password_changed');
            flash('success', 'Password changed.');
            header('Location: ' . admin_url());
            exit;
        }
    }
    admin_header('Change password');
    ?><div class="panel narrow"><h1>Change password</h1><form class="form-grid" method="post"><?= csrf_field() ?><label>Current password<input type="password" name="current_password" required></label><label>New password<input type="password" name="new_password" minlength="12" required></label><button class="primary">Save password</button></form></div><?php
    admin_footer();
    exit;
}

if ($page === 'dashboard') {
    $stats = [
        'Published games' => (int)$db->query("SELECT COUNT(*) FROM games WHERE status='published'")->fetchColumn(),
        'Needs review' => (int)$db->query("SELECT COUNT(*) FROM games WHERE status='review'")->fetchColumn(),
        'Pending queue' => (int)$db->query("SELECT COUNT(*) FROM import_queue WHERE status='pending'")->fetchColumn(),
        'Open reports' => (int)$db->query("SELECT COUNT(*) FROM game_reports WHERE status='open'")->fetchColumn(),
    ];
    $lastRun = $db->query('SELECT * FROM cron_runs ORDER BY id DESC LIMIT 1')->fetch();
    $recent = $db->query("SELECT title,slug,status,updated_at FROM games ORDER BY updated_at DESC LIMIT 8")->fetchAll();
    admin_header('Dashboard');
    echo '<div class="admin-heading"><div><h1>Dashboard</h1><p>Automation and publishing overview.</p></div><form method="post" action="' . e(admin_url('run-cron')) . '">' . csrf_field() . '<button class="primary">Run automation now</button></form></div><div class="stat-grid">';
    foreach ($stats as $label => $value) {
        echo '<div class="stat"><strong>' . number_format($value) . '</strong><span>' . e($label) . '</span></div>';
    }
    echo '</div><div class="admin-grid"><section class="panel"><h2>Latest cron run</h2>';
    if ($lastRun) {
        echo '<dl class="detail-list"><dt>Status</dt><dd>' . e($lastRun['status']) . '</dd><dt>Started</dt><dd>' . e($lastRun['started_at']) . '</dd><dt>Imported</dt><dd>' . number_format((int)$lastRun['imported']) . '</dd><dt>Failed</dt><dd>' . number_format((int)$lastRun['failed']) . '</dd><dt>Message</dt><dd>' . e($lastRun['message']) . '</dd></dl>';
    } else {
        echo '<p>No cron run yet. Click “Run automation now”.</p>';
    }
    echo '</section><section class="panel"><h2>Recent games</h2><ul class="clean-list">';
    foreach ($recent as $game) {
        echo '<li><a href="' . e(app_url('game/' . $game['slug'])) . '" target="_blank">' . e($game['title']) . '</a><span>' . e($game['status']) . '</span></li>';
    }
    echo '</ul></section></div>';
    admin_footer();
    exit;
}

if ($page === 'run-cron' && $_SERVER['REQUEST_METHOD'] === 'POST') {
    verify_csrf();
    $run = $db->prepare("INSERT INTO cron_runs (started_at,status,created_at) VALUES (NOW(),'running',NOW())");
    $run->execute();
    $runId = (int)$db->lastInsertId();
    $sourcesChecked = $found = 0;
    $errors = [];
    try {
        $importer = new GooglePlayImporter($db);
        $sources = $db->query("SELECT * FROM sources WHERE active=1 AND (next_run_at IS NULL OR next_run_at<=NOW()) ORDER BY priority DESC LIMIT 3")->fetchAll();
        foreach ($sources as $source) {
            $result = $importer->discoverSource($source);
            $sourcesChecked++;
            $found += (int)$result['found'];
            if (!$result['ok']) {
                $errors[] = $source['name'] . ': ' . $result['error'];
            }
        }
        $queue = $importer->processQueue(8);
        $status = $errors || $queue['failed'] ? 'partial' : 'success';
        $db->prepare('UPDATE cron_runs SET finished_at=NOW(),status=?,sources_checked=?,urls_found=?,queue_processed=?,imported=?,failed=?,message=? WHERE id=?')->execute([$status, $sourcesChecked, $found, $queue['processed'], $queue['ok'], $queue['failed'], mb_substr(implode(' | ', $errors), 0, 1000), $runId]);
        admin_activity('cron_run', 'Imported ' . $queue['ok'] . ', failed ' . $queue['failed']);
        flash($status === 'success' ? 'success' : 'warning', 'Automation finished: ' . $queue['ok'] . ' imported, ' . $queue['failed'] . ' failed.');
    } catch (Throwable $e) {
        $db->prepare("UPDATE cron_runs SET finished_at=NOW(),status='failed',message=? WHERE id=?")->execute([mb_substr($e->getMessage(), 0, 1000), $runId]);
        flash('error', 'Automation failed: ' . $e->getMessage());
    }
    header('Location: ' . admin_url());
    exit;
}

if ($page === 'import') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $input = trim((string)($_POST['packages'] ?? ''));
        $values = preg_split('/[\s,;]+/', $input) ?: [];
        $insert = $db->prepare("INSERT INTO import_queue(package_id,status,priority,attempts,available_at,created_at,updated_at) VALUES(?,'pending',120,0,NOW(),NOW(),NOW()) ON DUPLICATE KEY UPDATE status=IF(status='processing',status,'pending'),priority=120,available_at=NOW(),updated_at=NOW()");
        $count = 0;
        foreach (array_unique($values) as $value) {
            if (str_contains($value, 'play.google.com')) {
                parse_str((string)parse_url($value, PHP_URL_QUERY), $query);
                $value = $query['id'] ?? '';
            }
            if (preg_match('/^[A-Za-z0-9._-]{3,255}$/', $value)) {
                $insert->execute([$value]);
                $count++;
            }
        }
        admin_activity('packages_queued', (string)$count);
        flash('success', $count . ' package IDs added to the automation queue.');
        header('Location: ' . admin_url('import'));
        exit;
    }
    $queue = $db->query("SELECT status,COUNT(*) total FROM import_queue GROUP BY status")->fetchAll();
    admin_header('Import');
    ?><div class="admin-heading"><div><h1>Import package IDs</h1><p>Add Google Play package IDs or listing URLs. Cron fetches and validates factual game metadata.</p></div></div><div class="admin-grid"><form class="panel form-grid" method="post"><?= csrf_field() ?><label>Package IDs or Google Play URLs<textarea name="packages" rows="12" placeholder="com.example.game&#10;https://play.google.com/store/apps/details?id=com.example.game" required></textarea></label><button class="primary">Add to queue</button></form><section class="panel"><h2>Queue status</h2><ul class="clean-list"><?php foreach ($queue as $item): ?><li><span><?= e(ucfirst($item['status'])) ?></span><strong><?= number_format((int)$item['total']) ?></strong></li><?php endforeach; ?></ul><p>Failed records use exponential retry and stop after four attempts. Sources pause after repeated failures.</p></section></div><?php
    admin_footer();
    exit;
}

if ($page === 'games') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $ids = array_map('intval', $_POST['ids'] ?? []);
        $action = (string)($_POST['bulk_action'] ?? '');
        if ($ids && in_array($action, ['published', 'review', 'hidden', 'removed'], true)) {
            $placeholders = implode(',', array_fill(0, count($ids), '?'));
            $params = array_merge([$action], $ids);
            $db->prepare("UPDATE games SET status=?,updated_at=NOW() WHERE id IN ({$placeholders})")->execute($params);
            admin_activity('games_bulk_status', $action . ' ' . implode(',', $ids));
            flash('success', count($ids) . ' games updated.');
        }
        header('Location: ' . admin_url('games'));
        exit;
    }
    $q = trim((string)($_GET['q'] ?? ''));
    $status = (string)($_GET['status'] ?? '');
    $where = ['1=1'];
    $params = [];
    if ($q !== '') {
        $where[] = '(title LIKE ? OR package_id LIKE ? OR developer LIKE ?)';
        $like = '%' . $q . '%';
        array_push($params, $like, $like, $like);
    }
    if (in_array($status, ['published', 'review', 'hidden', 'removed'], true)) {
        $where[] = 'status=?';
        $params[] = $status;
    }
    $pageNo = max(1, (int)($_GET['p'] ?? 1));
    $offset = ($pageNo - 1) * 40;
    $stmt = $db->prepare('SELECT SQL_CALC_FOUND_ROWS * FROM games WHERE ' . implode(' AND ', $where) . " ORDER BY updated_at DESC LIMIT 40 OFFSET {$offset}");
    $stmt->execute($params);
    $games = $stmt->fetchAll();
    $total = (int)$db->query('SELECT FOUND_ROWS()')->fetchColumn();
    admin_header('Games');
    ?><div class="admin-heading"><div><h1>Games</h1><p><?= number_format($total) ?> matching records.</p></div><a class="primary button" href="<?= e(admin_url('import')) ?>">Import games</a></div><form class="filter-bar" method="get"><input type="hidden" name="page" value="games"><input name="q" value="<?= e($q) ?>" placeholder="Title, package or developer"><select name="status"><option value="">All statuses</option><?php foreach (['published','review','hidden','removed'] as $option): ?><option value="<?= e($option) ?>" <?= $status === $option ? 'selected' : '' ?>><?= e(ucfirst($option)) ?></option><?php endforeach; ?></select><button>Filter</button></form><form method="post"><?= csrf_field() ?><div class="bulk-bar"><select name="bulk_action"><option value="">Bulk status…</option><option value="published">Publish</option><option value="review">Move to review</option><option value="hidden">Hide</option><option value="removed">Mark removed</option></select><button>Apply</button></div><div class="table-wrap"><table><thead><tr><th><input type="checkbox" data-check-all></th><th>Game</th><th>Category</th><th>Status</th><th>Rating</th><th>Updated</th><th></th></tr></thead><tbody><?php foreach ($games as $game): ?><tr><td><input type="checkbox" name="ids[]" value="<?= (int)$game['id'] ?>"></td><td><strong><?= e($game['title']) ?></strong><small><?= e($game['package_id']) ?><br><?= e($game['developer']) ?></small></td><td><?= e($game['category']) ?></td><td><span class="badge <?= e($game['status']) ?>"><?= e($game['status']) ?></span></td><td><?= $game['rating'] !== null ? e(number_format((float)$game['rating'], 1)) : '—' ?></td><td><?= e($game['updated_at']) ?></td><td><a href="<?= e(admin_url('game-edit', ['id' => $game['id']])) ?>">Edit</a></td></tr><?php endforeach; ?></tbody></table></div></form><?php
    $pages = max(1, (int)ceil($total / 40));
    if ($pages > 1) {
        echo '<nav class="pagination">';
        foreach (array_unique(array_filter([1, $pageNo - 1, $pageNo, $pageNo + 1, $pages], fn($n) => $n > 0 && $n <= $pages)) as $number) {
            echo '<a class="' . ($number === $pageNo ? 'active' : '') . '" href="' . e(admin_url('games', ['q' => $q, 'status' => $status, 'p' => $number])) . '">' . $number . '</a>';
        }
        echo '</nav>';
    }
    admin_footer();
    exit;
}

if ($page === 'game-edit') {
    $id = (int)($_GET['id'] ?? 0);
    $stmt = $db->prepare('SELECT * FROM games WHERE id=?');
    $stmt->execute([$id]);
    $game = $stmt->fetch();
    if (!$game) {
        flash('error', 'Game not found.');
        header('Location: ' . admin_url('games'));
        exit;
    }
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $title = trim((string)($_POST['title'] ?? ''));
        $slug = slugify((string)($_POST['slug'] ?? ''));
        $summary = trim((string)($_POST['short_description'] ?? ''));
        $category = trim((string)($_POST['category'] ?? 'Games'));
        $status = in_array($_POST['status'] ?? '', ['published', 'review', 'hidden', 'removed'], true) ? $_POST['status'] : 'review';
        if ($title === '' || mb_strlen($summary) < 30) {
            flash('error', 'Title and a useful summary of at least 30 characters are required.');
        } else {
            try {
                $update = $db->prepare('UPDATE games SET title=?,slug=?,short_description=?,category=?,status=?,featured=?,custom_title=1,custom_summary=1,updated_at=NOW() WHERE id=?');
                $update->execute([$title, $slug, mb_substr($summary, 0, 500), $category, $status, isset($_POST['featured']) ? 1 : 0, $id]);
                admin_activity('game_edited', $game['package_id']);
                flash('success', 'Game saved.');
                header('Location: ' . admin_url('game-edit', ['id' => $id]));
                exit;
            } catch (PDOException $e) {
                flash('error', 'Could not save. The slug may already be in use.');
            }
        }
    }
    admin_header('Edit game');
    ?><div class="admin-heading"><div><h1>Edit game</h1><p><?= e($game['package_id']) ?></p></div><a href="<?= e(app_url('game/' . $game['slug'])) ?>" target="_blank">View page</a></div><form class="panel form-grid" method="post"><?= csrf_field() ?><label>Title<input name="title" value="<?= e($game['title']) ?>" maxlength="255" required></label><label>URL slug<input name="slug" value="<?= e($game['slug']) ?>" maxlength="300" required></label><label>Developer<input value="<?= e($game['developer']) ?>" disabled></label><label>Category<input name="category" value="<?= e($game['category']) ?>" maxlength="120" required></label><label>Original, concise summary<textarea name="short_description" rows="5" minlength="30" maxlength="500" required><?= e($game['short_description']) ?></textarea></label><label>Status<select name="status"><?php foreach (['published','review','hidden','removed'] as $option): ?><option value="<?= e($option) ?>" <?= $game['status'] === $option ? 'selected' : '' ?>><?= e(ucfirst($option)) ?></option><?php endforeach; ?></select></label><label class="checkbox"><input type="checkbox" name="featured" value="1" <?= $game['featured'] ? 'checked' : '' ?>> Feature this game</label><button class="primary">Save game</button></form><?php
    admin_footer();
    exit;
}

if ($page === 'sources') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $action = (string)($_POST['action'] ?? 'add');
        if ($action === 'add') {
            $name = trim((string)($_POST['name'] ?? ''));
            $url = trim((string)($_POST['source_url'] ?? ''));
            if ($name && filter_var($url, FILTER_VALIDATE_URL) && parse_url($url, PHP_URL_SCHEME) === 'https' && strtolower((string)parse_url($url, PHP_URL_HOST)) === 'play.google.com') {
                try {
                    $db->prepare("INSERT INTO sources(name,source_type,source_url,active,priority,interval_hours,next_run_at,created_at,updated_at) VALUES(?,'google_play_browse',?,1,50,24,NOW(),NOW(),NOW())")->execute([$name, $url]);
                    admin_activity('source_added', $name);
                    flash('success', 'Source added.');
                } catch (PDOException) {
                    flash('warning', 'That source URL already exists.');
                }
            } else {
                flash('error', 'Enter a source name and an HTTPS play.google.com browse or category URL.');
            }
        }
        if ($action === 'toggle') {
            $db->prepare('UPDATE sources SET active=1-active,next_run_at=NOW() WHERE id=?')->execute([(int)$_POST['id']]);
            admin_activity('source_toggled', (string)$_POST['id']);
        }
        header('Location: ' . admin_url('sources'));
        exit;
    }
    $sources = $db->query('SELECT * FROM sources ORDER BY active DESC,priority DESC,id')->fetchAll();
    admin_header('Sources');
    ?><div class="admin-heading"><div><h1>Discovery sources</h1><p>Browse pages are checked slowly; package IDs are queued and detail pages are validated separately.</p></div></div><form class="panel inline-form" method="post"><?= csrf_field() ?><input type="hidden" name="action" value="add"><label>Name<input name="name" required></label><label>Google Play browse/category URL<input type="url" name="source_url" required></label><button class="primary">Add source</button></form><div class="table-wrap"><table><thead><tr><th>Source</th><th>Active</th><th>Priority</th><th>Last success</th><th>Next run</th><th>Error</th><th></th></tr></thead><tbody><?php foreach ($sources as $source): ?><tr><td><strong><?= e($source['name']) ?></strong><small><?= e($source['source_url']) ?></small></td><td><?= $source['active'] ? 'Yes' : 'No' ?></td><td><?= (int)$source['priority'] ?></td><td><?= e($source['last_success_at'] ?? 'Never') ?></td><td><?= e($source['next_run_at'] ?? 'Now') ?></td><td><small><?= e($source['last_error'] ?? '') ?></small></td><td><form method="post"><?= csrf_field() ?><input type="hidden" name="action" value="toggle"><input type="hidden" name="id" value="<?= (int)$source['id'] ?>"><button><?= $source['active'] ? 'Pause' : 'Enable' ?></button></form></td></tr><?php endforeach; ?></tbody></table></div><?php
    admin_footer();
    exit;
}

if ($page === 'settings') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $allowed = ['site_name','site_description','home_url','auto_publish','games_per_page','ads_enabled','adsense_client','ad_slot_header','ad_slot_in_content','ad_slot_footer','google_site_verification','head_code','footer_code','contact_email'];
        foreach ($allowed as $key) {
            $value = in_array($key, ['auto_publish','ads_enabled'], true) ? (isset($_POST[$key]) ? '1' : '0') : trim((string)($_POST[$key] ?? ''));
            save_setting($key, $value);
        }
        admin_activity('settings_saved');
        flash('success', 'Settings saved.');
        header('Location: ' . admin_url('settings'));
        exit;
    }
    global $config;
    admin_header('Settings');
    ?><div class="admin-heading"><div><h1>Settings & Ads</h1><p>Changes apply across public pages.</p></div></div><form class="panel form-grid" method="post"><?= csrf_field() ?><h2>Website</h2><label>Site name<input name="site_name" value="<?= e(setting('site_name')) ?>" required></label><label>Site description<textarea name="site_description" rows="3" maxlength="160"><?= e(setting('site_description')) ?></textarea></label><label>Play Free Game destination<input type="url" name="home_url" value="<?= e(setting('home_url')) ?>" required></label><label>Games per page<input type="number" name="games_per_page" min="12" max="60" value="<?= e(setting('games_per_page', '24')) ?>"></label><label class="checkbox"><input type="checkbox" name="auto_publish" value="1" <?= setting('auto_publish') === '1' ? 'checked' : '' ?>> Automatically publish validated games</label><h2>Google Search Console</h2><label>Google site verification content value<input name="google_site_verification" value="<?= e(setting('google_site_verification')) ?>"><small>Paste only the content value. The meta tag is added automatically.</small></label><h2>Google AdSense</h2><label class="checkbox"><input type="checkbox" name="ads_enabled" value="1" <?= setting('ads_enabled') === '1' ? 'checked' : '' ?>> Enable ads</label><label>Publisher client ID<input name="adsense_client" placeholder="ca-pub-..." value="<?= e(setting('adsense_client')) ?>"></label><label>Header slot ID<input name="ad_slot_header" value="<?= e(setting('ad_slot_header')) ?>"></label><label>In-content slot ID<input name="ad_slot_in_content" value="<?= e(setting('ad_slot_in_content')) ?>"></label><label>Footer slot ID<input name="ad_slot_footer" value="<?= e(setting('ad_slot_footer')) ?>"></label><h2>Advanced code</h2><label>Head code<textarea name="head_code" rows="5"><?= e(setting('head_code')) ?></textarea></label><label>Footer code<textarea name="footer_code" rows="5"><?= e(setting('footer_code')) ?></textarea></label><label>Contact email<input type="email" name="contact_email" value="<?= e(setting('contact_email')) ?>"></label><button class="primary">Save settings</button></form><section class="panel"><h2>cPanel cron command</h2><p>Run every hour:</p><code>curl -fsS '<?= e(app_url('cron.php?token=' . $config['cron_token'])) ?>' &gt;/dev/null 2&gt;&amp;1</code></section><?php
    admin_footer();
    exit;
}

if ($page === 'reports') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $status = in_array($_POST['status'] ?? '', ['open','resolved','dismissed'], true) ? $_POST['status'] : 'open';
        $db->prepare('UPDATE game_reports SET status=? WHERE id=?')->execute([$status, (int)$_POST['id']]);
        admin_activity('report_updated', (string)$_POST['id']);
        header('Location: ' . admin_url('reports'));
        exit;
    }
    $rows = $db->query('SELECT r.*,g.title,g.slug FROM game_reports r JOIN games g ON g.id=r.game_id ORDER BY r.created_at DESC LIMIT 200')->fetchAll();
    admin_header('Reports');
    echo '<div class="admin-heading"><div><h1>Game reports</h1><p>Review information-quality and rights concerns.</p></div></div><div class="table-wrap"><table><thead><tr><th>Game</th><th>Reason</th><th>Message</th><th>Status</th><th>Date</th><th></th></tr></thead><tbody>';
    foreach ($rows as $row) {
        echo '<tr><td><a target="_blank" href="' . e(app_url('game/' . $row['slug'])) . '">' . e($row['title']) . '</a></td><td>' . e($row['reason']) . '</td><td>' . e($row['message']) . '<small>' . e($row['email']) . '</small></td><td>' . e($row['status']) . '</td><td>' . e($row['created_at']) . '</td><td><form method="post">' . csrf_field() . '<input type="hidden" name="id" value="' . (int)$row['id'] . '"><select name="status"><option>open</option><option>resolved</option><option>dismissed</option></select><button>Save</button></form></td></tr>';
    }
    echo '</tbody></table></div>';
    admin_footer();
    exit;
}

if ($page === 'contacts') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $db->prepare("UPDATE contacts SET status='closed' WHERE id=?")->execute([(int)$_POST['id']]);
        admin_activity('contact_closed', (string)$_POST['id']);
        header('Location: ' . admin_url('contacts'));
        exit;
    }
    $rows = $db->query('SELECT * FROM contacts ORDER BY created_at DESC LIMIT 200')->fetchAll();
    admin_header('Messages');
    echo '<div class="admin-heading"><div><h1>Contact messages</h1></div></div><div class="table-wrap"><table><thead><tr><th>From</th><th>Subject</th><th>Message</th><th>Status</th><th>Date</th><th></th></tr></thead><tbody>';
    foreach ($rows as $row) {
        echo '<tr><td>' . e($row['name']) . '<small><a href="mailto:' . e($row['email']) . '">' . e($row['email']) . '</a></small></td><td>' . e($row['subject']) . '</td><td>' . e($row['message']) . '</td><td>' . e($row['status']) . '</td><td>' . e($row['created_at']) . '</td><td><form method="post">' . csrf_field() . '<input type="hidden" name="id" value="' . (int)$row['id'] . '"><button>Close</button></form></td></tr>';
    }
    echo '</tbody></table></div>';
    admin_footer();
    exit;
}

if ($page === 'activity') {
    $rows = $db->query('SELECT l.*,a.email FROM admin_activity_log l LEFT JOIN admins a ON a.id=l.admin_id ORDER BY l.created_at DESC LIMIT 300')->fetchAll();
    $runs = $db->query('SELECT * FROM cron_runs ORDER BY id DESC LIMIT 100')->fetchAll();
    admin_header('Activity');
    echo '<div class="admin-heading"><div><h1>Activity & cron logs</h1></div></div><div class="admin-grid"><section class="panel"><h2>Admin activity</h2><ul class="clean-list">';
    foreach ($rows as $row) {
        echo '<li><span><strong>' . e($row['action']) . '</strong><small>' . e($row['email']) . ' · ' . e($row['details']) . '</small></span><time>' . e($row['created_at']) . '</time></li>';
    }
    echo '</ul></section><section class="panel"><h2>Cron runs</h2><ul class="clean-list">';
    foreach ($runs as $run) {
        echo '<li><span><strong>' . e($run['status']) . '</strong><small>Imported ' . (int)$run['imported'] . ', failed ' . (int)$run['failed'] . '<br>' . e($run['message']) . '</small></span><time>' . e($run['started_at']) . '</time></li>';
    }
    echo '</ul></section></div>';
    admin_footer();
    exit;
}

if ($page === 'health') {
    global $config;
    $lastRun = $db->query('SELECT finished_at,status FROM cron_runs ORDER BY id DESC LIMIT 1')->fetch();
    $checks = [
        'Database connection' => true,
        'PHP 8.2+' => version_compare(PHP_VERSION, '8.2.0', '>='),
        'PDO MySQL' => extension_loaded('pdo_mysql'),
        'cURL or URL fopen' => extension_loaded('curl') || (bool)ini_get('allow_url_fopen'),
        'Storage writable' => is_writable(APP_ROOT . '/storage'),
        'HTTPS app URL' => parse_url($config['app_url'], PHP_URL_SCHEME) === 'https',
        'Cron ran in last 2 hours' => $lastRun && strtotime($lastRun['finished_at']) > time() - 7200,
        'Default password changed' => empty($_SESSION['force_password_change']),
    ];
    admin_header('Health');
    echo '<div class="admin-heading"><div><h1>System health</h1><p>Use this page after installation and whenever imports stop.</p></div></div><section class="panel"><ul class="check-list">';
    foreach ($checks as $label => $ok) {
        echo '<li class="' . ($ok ? 'pass' : 'fail') . '">' . ($ok ? '✓' : '✕') . ' ' . e($label) . '</li>';
    }
    echo '</ul><dl class="detail-list"><dt>PHP</dt><dd>' . e(PHP_VERSION) . '</dd><dt>App version</dt><dd>' . e(APP_VERSION) . '</dd><dt>App URL</dt><dd>' . e($config['app_url']) . '</dd><dt>Last cron</dt><dd>' . e($lastRun['finished_at'] ?? 'Never') . '</dd><dt>Sitemap</dt><dd><a target="_blank" href="' . e(app_url('sitemap.xml')) . '">Open sitemap.xml</a></dd></dl></section>';
    admin_footer();
    exit;
}

http_response_code(404);
admin_header('Not found');
echo '<div class="empty"><h1>Admin page not found</h1></div>';
admin_footer();
