<?php
declare(strict_types=1);

require __DIR__ . '/app/bootstrap.php';
$db = DB::connection();
$path = request_path();

function game_card(array $game): void
{
    $icon = $game['icon_url'] ?: app_url('assets/icon.svg');
    ?>
    <article class="game-card">
      <a href="<?= e(app_url('game/' . $game['slug'])) ?>">
        <img src="<?= e($icon) ?>" alt="<?= e($game['title']) ?> icon" width="160" height="160" loading="lazy" referrerpolicy="no-referrer">
        <div class="card-body">
          <h2><?= e($game['title']) ?></h2>
          <p><?= e($game['developer']) ?></p>
          <div class="card-meta"><span><?= e($game['category']) ?></span><?php if ($game['rating'] !== null): ?><span>★ <?= e(number_format((float)$game['rating'], 1)) ?></span><?php endif; ?></div>
        </div>
      </a>
    </article>
    <?php
}

function pagination(int $page, int $pages, string $base, array $query = []): void
{
    if ($pages <= 1) {
        return;
    }
    echo '<nav class="pagination" aria-label="Pages">';
    foreach (array_unique(array_filter([1, $page - 1, $page, $page + 1, $pages], static fn(int $p): bool => $p >= 1 && $p <= $pages)) as $p) {
        $query['page'] = $p;
        $href = app_url($base) . '?' . http_build_query($query);
        echo '<a class="' . ($p === $page ? 'active' : '') . '" href="' . e($href) . '">' . $p . '</a>';
    }
    echo '</nav>';
}

function static_page(string $title, string $body): never
{
    page_header($title, strip_tags($body));
    echo '<article class="prose"><h1>' . e($title) . '</h1>' . $body . '</article>';
    page_footer();
    exit;
}

if ($path === 'robots.txt') {
    header('Content-Type: text/plain; charset=UTF-8');
    echo "User-agent: *\nAllow: /\nDisallow: /admin/\nDisallow: /install/\nDisallow: /cron.php\nSitemap: " . app_url('sitemap.xml') . "\n";
    exit;
}

if ($path === 'sitemap.xml') {
    header('Content-Type: application/xml; charset=UTF-8');
    $count = (int)$db->query("SELECT COUNT(*) FROM games WHERE status='published'")->fetchColumn();
    $pages = max(1, (int)ceil($count / 5000));
    echo '<?xml version="1.0" encoding="UTF-8"?>';
    echo '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
    echo '<sitemap><loc>' . e(app_url('sitemap-static.xml')) . '</loc><lastmod>' . date('Y-m-d') . '</lastmod></sitemap>';
    for ($i = 1; $i <= $pages; $i++) {
        echo '<sitemap><loc>' . e(app_url('sitemap-games-' . $i . '.xml')) . '</loc><lastmod>' . date('Y-m-d') . '</lastmod></sitemap>';
    }
    echo '</sitemapindex>';
    exit;
}

if ($path === 'sitemap-static.xml') {
    header('Content-Type: application/xml; charset=UTF-8');
    echo '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
    foreach (['', 'categories', 'about', 'contact', 'privacy', 'terms', 'disclaimer'] as $route) {
        echo '<url><loc>' . e(app_url($route)) . '</loc><lastmod>' . date('Y-m-d') . '</lastmod></url>';
    }
    $categories = $db->query("SELECT category,MAX(updated_at) updated_at FROM games WHERE status='published' GROUP BY category ORDER BY category");
    foreach ($categories as $category) {
        echo '<url><loc>' . e(app_url('category/' . slugify($category['category']))) . '</loc><lastmod>' . e(substr($category['updated_at'], 0, 10)) . '</lastmod></url>';
    }
    echo '</urlset>';
    exit;
}

if (preg_match('/^sitemap-games-(\d+)\.xml$/', $path, $match)) {
    header('Content-Type: application/xml; charset=UTF-8');
    $page = max(1, (int)$match[1]);
    $offset = ($page - 1) * 5000;
    $rows = $db->query("SELECT slug,icon_url,title,updated_at FROM games WHERE status='published' ORDER BY id LIMIT 5000 OFFSET {$offset}");
    echo '<?xml version="1.0" encoding="UTF-8"?>';
    echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">';
    foreach ($rows as $row) {
        echo '<url><loc>' . e(app_url('game/' . $row['slug'])) . '</loc><lastmod>' . e(substr($row['updated_at'], 0, 10)) . '</lastmod>';
        if ($row['icon_url']) {
            echo '<image:image><image:loc>' . e($row['icon_url']) . '</image:loc><image:title>' . e($row['title']) . '</image:title></image:image>';
        }
        echo '</url>';
    }
    echo '</urlset>';
    exit;
}

if ($path === 'feed.xml') {
    header('Content-Type: application/rss+xml; charset=UTF-8');
    $games = $db->query("SELECT title,slug,short_description,updated_at FROM games WHERE status='published' ORDER BY updated_at DESC LIMIT 50");
    echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>' . e(setting('site_name', 'GamesJi Apps')) . '</title><link>' . e(app_url()) . '</link><description>' . e(setting('site_description')) . '</description>';
    foreach ($games as $game) {
        echo '<item><title>' . e($game['title']) . '</title><link>' . e(app_url('game/' . $game['slug'])) . '</link><guid>' . e(app_url('game/' . $game['slug'])) . '</guid><description>' . e($game['short_description']) . '</description><pubDate>' . e(date(DATE_RSS, strtotime($game['updated_at']))) . '</pubDate></item>';
    }
    echo '</channel></rss>';
    exit;
}

if ($path === 'about') {
    static_page('About GamesJi Apps', '<p>GamesJi Apps is a game-discovery directory. It organises factual information about Android games and sends visitors to verified official listings. No APK or installation file is hosted here.</p><p>The <strong>Play Free Game</strong> link opens GamesJi.com, where GamesJi’s own browser games are available.</p>');
}
if ($path === 'privacy') {
    static_page('Privacy Policy', '<p>We collect only information needed to operate and secure this website. Contact and report forms store the details you submit. Security logs use a one-way hash instead of storing a raw IP address.</p><p>When advertising is enabled, Google and its partners may use cookies or similar technologies to provide, measure and personalise ads. You can manage advertising choices through Google’s ad settings. External sites, including Google Play, apply their own privacy policies.</p><p>To request correction or deletion of information submitted through a form, use the contact page.</p>');
}
if ($path === 'terms') {
    static_page('Terms of Use', '<p>Game details are provided for discovery and may change. Always verify price, compatibility, age rating and availability on the official store before installing.</p><p>You may not use this website to distribute malware, submit abusive content, automate excessive requests or misrepresent GamesJi. All third-party names, icons and trademarks belong to their respective owners.</p>');
}
if ($path === 'disclaimer') {
    static_page('Disclaimer', '<p>GamesJi Apps is an independent discovery website and is not affiliated with or endorsed by Google. Android and Google Play are trademarks of Google LLC.</p><p>We do not host APK files. “View on Google Play” opens the official listing. “Play Free Game” opens GamesJi.com and refers to GamesJi’s own browser games.</p>');
}

if ($path === 'contact') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        verify_csrf();
        $last = (int)($_SESSION['_last_contact'] ?? 0);
        $name = trim((string)($_POST['name'] ?? ''));
        $email = trim((string)($_POST['email'] ?? ''));
        $subject = trim((string)($_POST['subject'] ?? ''));
        $message = trim((string)($_POST['message'] ?? ''));
        if (time() - $last < 45 || ($_POST['website'] ?? '') !== '') {
            flash('error', 'Please wait before sending another message.');
        } elseif ($name === '' || !filter_var($email, FILTER_VALIDATE_EMAIL) || $subject === '' || mb_strlen($message) < 10) {
            flash('error', 'Complete all fields with a valid email and message.');
        } else {
            $stmt = $db->prepare('INSERT INTO contacts (name,email,subject,message,ip_hash,created_at) VALUES (?,?,?,?,?,NOW())');
            $stmt->execute([$name, $email, mb_substr($subject, 0, 180), mb_substr($message, 0, 2000), hash('sha256', ($_SERVER['REMOTE_ADDR'] ?? '') . setting('privacy_salt'))]);
            $_SESSION['_last_contact'] = time();
            flash('success', 'Your message has been received.');
        }
        header('Location: ' . app_url('contact'));
        exit;
    }
    page_header('Contact', 'Contact the GamesJi Apps team.');
    echo '<article class="prose"><h1>Contact</h1>';
    render_flashes();
    ?><form class="form-grid" method="post"><?= csrf_field() ?><label>Name<input name="name" required maxlength="120"></label><label>Email<input type="email" name="email" required maxlength="190"></label><label>Subject<input name="subject" required maxlength="180"></label><label class="hidden-field">Website<input name="website" tabindex="-1" autocomplete="off"></label><label>Message<textarea name="message" required minlength="10" maxlength="2000" rows="7"></textarea></label><button class="primary" type="submit">Send message</button></form></article><?php
    page_footer();
    exit;
}

if ($path === 'categories') {
    $categories = $db->query("SELECT category,COUNT(*) total,MAX(icon_url) icon_url FROM games WHERE status='published' GROUP BY category ORDER BY total DESC,category")->fetchAll();
    page_header('Game Categories', 'Browse Android games by category.');
    echo '<div class="page-heading"><h1>Game Categories</h1><p>Explore games organised by category.</p></div><section class="category-grid">';
    foreach ($categories as $category) {
        echo '<a class="category-card" href="' . e(app_url('category/' . slugify($category['category']))) . '"><strong>' . e($category['category']) . '</strong><span>' . number_format((int)$category['total']) . ' games</span></a>';
    }
    echo '</section>';
    page_footer();
    exit;
}

if (preg_match('~^category/([a-z0-9-]+)$~', $path, $match)) {
    $available = $db->query("SELECT category FROM games WHERE status='published' GROUP BY category")->fetchAll(PDO::FETCH_COLUMN);
    $category = null;
    foreach ($available as $candidate) {
        if (slugify($candidate) === $match[1]) {
            $category = $candidate;
            break;
        }
    }
    if (!$category) {
        http_response_code(404);
        page_header('Category not found', '', ['robots' => 'noindex,follow']);
        echo '<div class="empty"><h1>Category not found</h1><a href="' . e(app_url('categories')) . '">Browse categories</a></div>';
        page_footer();
        exit;
    }
    $perPage = min(60, max(12, (int)setting('games_per_page', '24')));
    $page = max(1, (int)($_GET['page'] ?? 1));
    $countStmt = $db->prepare("SELECT COUNT(*) FROM games WHERE status='published' AND category=?");
    $countStmt->execute([$category]);
    $total = (int)$countStmt->fetchColumn();
    $pages = max(1, (int)ceil($total / $perPage));
    $page = min($page, $pages);
    $offset = ($page - 1) * $perPage;
    $stmt = $db->prepare("SELECT * FROM games WHERE status='published' AND category=? ORDER BY featured DESC,rating_count DESC,updated_at DESC LIMIT {$perPage} OFFSET {$offset}");
    $stmt->execute([$category]);
    page_header($category . ' Games', 'Discover ' . $category . ' Android games, ratings and official store links.', ['canonical' => app_url('category/' . $match[1]) . ($page > 1 ? '?page=' . $page : '')]);
    echo '<div class="page-heading"><h1>' . e($category) . ' Games</h1><p>' . number_format($total) . ' games found.</p></div>' . ad_slot('header') . '<section class="game-grid">';
    foreach ($stmt as $game) {
        game_card($game);
    }
    echo '</section>';
    pagination($page, $pages, 'category/' . $match[1]);
    page_footer();
    exit;
}

if ($path === 'search') {
    $q = trim((string)($_GET['q'] ?? ''));
    $games = [];
    if (mb_strlen($q) >= 2) {
        $stmt = $db->prepare("SELECT * FROM games WHERE status='published' AND (title LIKE ? OR developer LIKE ? OR category LIKE ?) ORDER BY featured DESC,rating_count DESC LIMIT 60");
        $like = '%' . str_replace(['%', '_'], ['\\%', '\\_'], $q) . '%';
        $stmt->execute([$like, $like, $like]);
        $games = $stmt->fetchAll();
    }
    page_header($q ? 'Search: ' . $q : 'Search games', 'Search Android games and developers.', ['robots' => 'noindex,follow']);
    echo '<div class="page-heading"><h1>Search games</h1><p>' . ($q ? count($games) . ' results for “' . e($q) . '”' : 'Enter at least two characters.') . '</p></div><section class="game-grid">';
    foreach ($games as $game) {
        game_card($game);
    }
    echo '</section>';
    page_footer();
    exit;
}

if (preg_match('~^game/([a-z0-9-]+)$~', $path, $match)) {
    $stmt = $db->prepare("SELECT * FROM games WHERE slug=? AND status='published' LIMIT 1");
    $stmt->execute([$match[1]]);
    $game = $stmt->fetch();
    if (!$game) {
        http_response_code(404);
        page_header('Game not found', '', ['robots' => 'noindex,follow']);
        echo '<div class="empty"><h1>Game not found</h1><a href="' . e(app_url()) . '">Discover games</a></div>';
        page_footer();
        exit;
    }
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'report') {
        verify_csrf();
        if (time() - (int)($_SESSION['_last_report'] ?? 0) >= 30 && ($_POST['website'] ?? '') === '') {
            $reason = trim((string)($_POST['reason'] ?? 'Incorrect information'));
            $message = trim((string)($_POST['message'] ?? ''));
            $email = trim((string)($_POST['email'] ?? ''));
            if ($email === '' || filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $report = $db->prepare('INSERT INTO game_reports (game_id,reason,message,email,ip_hash,created_at) VALUES (?,?,?,?,?,NOW())');
                $report->execute([(int)$game['id'], mb_substr($reason, 0, 100), mb_substr($message, 0, 1000), $email ?: null, hash('sha256', ($_SERVER['REMOTE_ADDR'] ?? '') . setting('privacy_salt'))]);
                $_SESSION['_last_report'] = time();
                flash('success', 'Thank you. The report has been submitted.');
            }
        }
        header('Location: ' . app_url('game/' . $game['slug']) . '#report');
        exit;
    }
    $db->prepare('UPDATE games SET page_views=page_views+1 WHERE id=?')->execute([(int)$game['id']]);
    $schema = [
        '@context' => 'https://schema.org',
        '@type' => 'SoftwareApplication',
        'name' => $game['title'],
        'applicationCategory' => $game['category'],
        'operatingSystem' => $game['operating_system'] ?: 'Android',
        'url' => app_url('game/' . $game['slug']),
        'downloadUrl' => $game['play_url'],
        'image' => $game['icon_url'],
        'author' => ['@type' => 'Organization', 'name' => $game['developer']],
        'offers' => ['@type' => 'Offer', 'price' => $game['price'] ?: '0', 'priceCurrency' => $game['currency'] ?: 'INR'],
    ];
    if ($game['rating'] !== null && $game['rating_count'] > 0) {
        $schema['aggregateRating'] = ['@type' => 'AggregateRating', 'ratingValue' => (float)$game['rating'], 'ratingCount' => (int)$game['rating_count'], 'bestRating' => 5, 'worstRating' => 1];
    }
    page_header($game['title'] . ' – Android Game', $game['short_description'], ['image' => $game['icon_url'] ?: app_url('assets/icon.svg'), 'og_type' => 'article']);
    echo '<script type="application/ld+json">' . json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) . '</script>';
    echo '<nav class="breadcrumbs"><a href="' . e(app_url()) . '">Home</a><span>›</span><a href="' . e(app_url('category/' . slugify($game['category']))) . '">' . e($game['category']) . '</a><span>›</span><span>' . e($game['title']) . '</span></nav>';
    render_flashes();
    ?>
    <article class="game-detail">
      <div class="game-hero">
        <img class="game-icon" src="<?= e($game['icon_url'] ?: app_url('assets/icon.svg')) ?>" alt="<?= e($game['title']) ?> icon" width="180" height="180" referrerpolicy="no-referrer">
        <div><p class="eyebrow"><?= e($game['category']) ?></p><h1><?= e($game['title']) ?></h1><p class="developer">By <?= e($game['developer']) ?></p>
        <div class="action-row"><a class="primary button" href="<?= e($game['play_url']) ?>" rel="nofollow external noopener" target="_blank">View on Google Play</a><a class="secondary button" href="<?= e(setting('home_url', 'https://gamesji.com/')) ?>">Play Free Game</a></div></div>
      </div>
      <?= ad_slot('header') ?>
      <section class="facts" aria-label="Game facts">
        <?php if ($game['rating'] !== null): ?><div><span>Rating</span><strong>★ <?= e(number_format((float)$game['rating'], 1)) ?></strong><small><?= number_format((int)$game['rating_count']) ?> ratings</small></div><?php endif; ?>
        <div><span>Price</span><strong><?= ((float)$game['price'] <= 0) ? 'Free' : e($game['price'] . ' ' . $game['currency']) ?></strong></div>
        <?php if ($game['content_rating']): ?><div><span>Content rating</span><strong><?= e($game['content_rating']) ?></strong></div><?php endif; ?>
        <div><span>Platform</span><strong><?= e($game['operating_system'] ?: 'Android') ?></strong></div>
      </section>
      <section class="prose"><h2>About <?= e($game['title']) ?></h2><p><?= e($game['short_description']) ?></p><p>This page provides a concise discovery overview. Availability, device compatibility, price and ratings can change; check the official Google Play page for the latest information.</p></section>
      <?= ad_slot('in_content') ?>
      <section class="prose"><h2>Official installation</h2><p>GamesJi Apps does not host APK or installation files. Use the verified Google Play link above to view the official listing from <?= e($game['developer']) ?>.</p></section>
    </article>
    <?php
    $related = $db->prepare("SELECT * FROM games WHERE status='published' AND category=? AND id<>? ORDER BY featured DESC,rating_count DESC LIMIT 8");
    $related->execute([$game['category'], (int)$game['id']]);
    echo '<section><div class="section-heading"><h2>Related games</h2></div><div class="game-grid">';
    foreach ($related as $item) {
        game_card($item);
    }
    echo '</div></section>';
    ?>
    <details id="report" class="report-box"><summary>Report incorrect information</summary><form class="form-grid" method="post"><?= csrf_field() ?><input type="hidden" name="action" value="report"><label>Reason<select name="reason"><option>Incorrect information</option><option>Game removed</option><option>Wrong category</option><option>Trademark or rights concern</option><option>Other</option></select></label><label>Email (optional)<input type="email" name="email" maxlength="190"></label><label>Details<textarea name="message" maxlength="1000" rows="4"></textarea></label><label class="hidden-field">Website<input name="website" tabindex="-1"></label><button class="secondary button" type="submit">Submit report</button></form></details>
    <?php
    page_footer();
    exit;
}

if ($path !== '') {
    http_response_code(404);
    page_header('Page not found', '', ['robots' => 'noindex,follow']);
    echo '<div class="empty"><h1>Page not found</h1><p>The requested page could not be found.</p><a class="primary button" href="' . e(app_url()) . '">Go to discovery home</a></div>';
    page_footer();
    exit;
}

$perPage = min(60, max(12, (int)setting('games_per_page', '24')));
$page = max(1, (int)($_GET['page'] ?? 1));
$total = (int)$db->query("SELECT COUNT(*) FROM games WHERE status='published'")->fetchColumn();
$pages = max(1, (int)ceil($total / $perPage));
$page = min($page, $pages);
$offset = ($page - 1) * $perPage;
$games = $db->query("SELECT * FROM games WHERE status='published' ORDER BY featured DESC,updated_at DESC LIMIT {$perPage} OFFSET {$offset}");
$categories = $db->query("SELECT category,COUNT(*) total FROM games WHERE status='published' GROUP BY category ORDER BY total DESC LIMIT 12")->fetchAll();
page_header('Discover Android Games', 'Explore Android games, categories, ratings and verified official Google Play links.', ['canonical' => app_url() . ($page > 1 ? '?page=' . $page : '')]);
?>
<section class="hero">
  <div><p class="eyebrow">Android game discovery</p><h1>Find your next game</h1><p>Browse organised game information, ratings and verified official store links. No APK files are hosted.</p>
  <div class="action-row"><a class="primary button" href="<?= e(app_url('categories')) ?>">Browse Categories</a><a class="secondary button" href="<?= e(setting('home_url', 'https://gamesji.com/')) ?>">Play Free Game</a></div></div>
</section>
<?= ad_slot('header') ?>
<?php if ($categories): ?><section><div class="section-heading"><h2>Popular categories</h2><a href="<?= e(app_url('categories')) ?>">View all</a></div><div class="chip-row"><?php foreach ($categories as $category): ?><a href="<?= e(app_url('category/' . slugify($category['category']))) ?>"><?= e($category['category']) ?><span><?= number_format((int)$category['total']) ?></span></a><?php endforeach; ?></div></section><?php endif; ?>
<section><div class="section-heading"><div><h2>Latest games</h2><p><?= number_format($total) ?> discoverable games</p></div></div>
<?php if ($total): ?><div class="game-grid"><?php foreach ($games as $game) game_card($game); ?></div><?php else: ?><div class="empty"><h2>Automation is ready</h2><p>Run the first cron task from the admin dashboard to discover and import live game listings.</p></div><?php endif; ?>
<?php pagination($page, $pages, '', []); ?></section>
<?php page_footer();
