<?php

require __DIR__ . '/bootstrap.php';

use KeyLair\ClaimService;
use KeyLair\Csrf;
use KeyLair\Helpers;
use KeyLair\Platform;
use KeyLair\ProductPlatform;
use KeyLair\RateLimiter;
use KeyLair\Config;

$token = $_GET['token'] ?? '';
$slug = $_GET['slug'] ?? '';

if (!preg_match('/^[a-f0-9]{32}$/', $token) || !preg_match('/^[a-z0-9-]+$/', $slug)) {
    http_response_code(404);
    require __DIR__ . '/not_found.php';
    exit;
}

$link = ClaimService::findLinkByToken($token);
if (!$link) {
    http_response_code(404);
    require __DIR__ . '/not_found.php';
    exit;
}

$product = ClaimService::findProductBySlugForLink((int) $link['id'], $slug);
if (!$product) {
    http_response_code(404);
    require __DIR__ . '/not_found.php';
    exit;
}

$flash = $_SESSION['claim_flash'] ?? null;
unset($_SESSION['claim_flash']);

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    Csrf::requireValid();

    if (RateLimiter::tooManyRequests('claim_select', 15, 60)) {
        $_SESSION['claim_flash'] = ['type' => 'error', 'message' => 'Too many attempts. Please wait a moment and try again.'];
    } else {
        $platform = $_POST['platform'] ?? '';
        $result = ClaimService::claim((int) $link['id'], (int) $product['id'], $platform);

        if ($result['ok']) {
            $_SESSION['claim_flash'] = ['type' => 'success', 'message' => 'Key claimed.'];
        } else {
            $messages = [
                'limit_reached' => "You've already claimed all the keys available to you for this product.",
                'sold_out' => 'No keys are left for that platform. Please choose another.',
                'invalid_platform' => 'Please choose a valid platform.',
                'product_not_assigned' => 'This product is not available on your link.',
                'error' => 'Something went wrong. Please try again.',
            ];
            $_SESSION['claim_flash'] = ['type' => 'error', 'message' => $messages[$result['reason']] ?? $messages['error']];
        }
    }

    Helpers::redirect('/claim/' . $token . '/' . $slug);
}

$stock = $product['platform_stock'];
$claimsRemaining = (int) $product['max_claims'] - (int) $product['claims_used'];
$claimedKeys = ClaimService::claimedKeysForLinkProduct((int) $link['id'], (int) $product['id']);
$media = ClaimService::mediaForProduct((int) $product['id']);

$mediaItems = ClaimService::buildMediaShowcase($media, $product['cover_image_path'] ?? null);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= Helpers::e($product['name']) ?> — Claim Your Key · <?= Helpers::e(\KeyLair\Settings::siteName()) ?></title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/assets/css/tokens.css?product_id=<?= (int) $product['id'] ?>">
<link rel="stylesheet" href="/assets/css/product-page.css?product_id=<?= (int) $product['id'] ?>">
<?= \KeyLair\Settings::faviconTag() ?>
<?php if (!empty($product['custom_css'])): ?>
<style><?= $product['custom_css'] ?></style>
<?php endif; ?>
</head>
<body>
<div class="page">
  <div class="crumb"><a href="/claim/<?= Helpers::e($token) ?>">&larr; All products for this link</a></div>
  <div class="brandbar"><?= \KeyLair\Settings::brandIcon() ?><?= Helpers::e(\KeyLair\Settings::siteName()) ?> · Review Access</div>

  <?php if (!empty($mediaItems)): ?>
  <div class="media-showcase">
    <div class="media-main <?= $mediaItems[0]['type'] === 'shot' ? 'is-shot' : '' ?>" id="media-main">
      <?php if ($mediaItems[0]['type'] === 'video'): ?>
        <iframe src="<?= Helpers::e($mediaItems[0]['src']) ?>" style="width:100%;height:100%;border:0;border-radius:inherit;position:relative;z-index:1;" allowfullscreen loading="lazy"></iframe>
      <?php else: ?>
        <img src="<?= Helpers::e($mediaItems[0]['src']) ?>" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:inherit;position:relative;z-index:1;">
      <?php endif; ?>
    </div>
    <div class="media-thumbs">
      <?php foreach ($mediaItems as $i => $item): ?>
        <div class="thumb <?= $item['type'] ?> <?= $i === 0 ? 'active' : '' ?>"
             data-type="<?= $item['type'] ?>"
             data-src="<?= Helpers::e($item['src']) ?>"
             onclick="showMedia(this)">
          <?php if ($item['type'] === 'video'): ?>
            <span class="thumb-play"><svg viewBox="0 0 24 24" fill="#17212e"><path d="M8 5v14l11-7z"/></svg></span>
          <?php else: ?>
            <img src="<?= Helpers::e($item['src']) ?>" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:inherit;">
          <?php endif; ?>
        </div>
      <?php endforeach; ?>
    </div>
  </div>
  <?php endif; ?>

  <div class="hero">
    <h1><?= Helpers::e($product['name']) ?></h1>
  </div>

  <?php if (!empty($product['intro_text'])): ?>
  <div class="text-block">
    <p class="text-block-label">About this key</p>
    <?= Helpers::renderRichText($product['intro_text']) ?>
  </div>
  <?php endif; ?>

  <?php if ($flash): ?>
    <div class="claims-bar" style="border-color: <?= $flash['type'] === 'success' ? 'var(--signal-dim)' : 'var(--danger)' ?>;">
      <span style="font-size:13px; color:<?= $flash['type'] === 'success' ? 'var(--signal)' : 'var(--danger)' ?>;"><?= Helpers::e($flash['message']) ?></span>
    </div>
  <?php endif; ?>

  <div class="claims-bar">
    <span class="claims-label">Claims used</span>
    <div class="claims-track"><div class="claims-fill" style="width:<?= $product['max_claims'] > 0 ? min(100, round($product['claims_used'] / $product['max_claims'] * 100)) : 0 ?>%"></div></div>
    <span class="claims-count"><?= (int) $product['claims_used'] ?> / <?= (int) $product['max_claims'] ?></span>
  </div>

  <?php if (!empty($claimedKeys)): ?>
    <?php foreach ($claimedKeys as $ck): ?>
      <div class="reveal show">
        <div class="reveal-top">
          <span class="reveal-check"><svg viewBox="0 0 24 24" fill="none" stroke="#17212e" stroke-width="3"><path d="M4 12l5 5L20 6"/></svg></span>
          <span class="reveal-title">Your <?= Helpers::e(Platform::label($ck['platform'])) ?> key</span>
        </div>
        <div class="readout">
          <span class="readout-code"><?= Helpers::e($ck['key_value']) ?></span>
          <button class="copy-btn" onclick="copyCode(this)">Copy key</button>
        </div>
        <p class="reveal-note">This key can only be redeemed once. Save it somewhere safe.</p>
      </div>
    <?php endforeach; ?>
  <?php endif; ?>

  <?php
  function render_platform_tile(string $platform, bool $available, bool $fullWidth = false): void {
      $class = 'tile' . ($fullWidth ? ' tile-full' : '');
      if ($available): ?>
          <form method="post" style="margin:0;" class="<?= $fullWidth ? 'tile-full' : '' ?>">
            <?= Csrf::field() ?>
            <input type="hidden" name="platform" value="<?= $platform ?>">
            <button type="submit" class="<?= $class ?>"><?= Platform::tileInner($platform, true) ?></button>
          </form>
      <?php else: ?>
          <div class="<?= $class ?> disabled"><?= Platform::tileInner($platform, false) ?></div>
      <?php endif;
  }

  /**
   * A "single" (ungrouped) tile only spans one of the grid's two columns,
   * while a platform-family group always spans both -- so a single tile
   * that ends up with no other single tile beside it (its neighbors are
   * groups, or it's first/last) is left occupying half a row for no
   * reason. Mirrors the browser's own row-by-row grid auto-placement to
   * figure out, ahead of render time, which singles that applies to.
   *
   * @param array $entries groupForClaimPage()'s return value
   * @return array<int, bool> entry index => true if it should span the full row
   */
  function isolated_single_indexes(array $entries): array
  {
      $col = 0;
      $isolated = [];
      foreach ($entries as $i => $entry) {
          if ($entry['type'] === 'group') {
              $col = 0;
              continue;
          }
          if ($col === 0) {
              $nextIsSingle = isset($entries[$i + 1]) && $entries[$i + 1]['type'] === 'single';
              if ($nextIsSingle) {
                  $col = 1;
              } else {
                  $isolated[$i] = true;
              }
          } else {
              $col = 0;
          }
      }
      return $isolated;
  }
  ?>

  <?php if ($claimsRemaining > 0): ?>
    <p class="section-label">Choose your platform</p>
    <div class="grid">
      <?php
      $supportedSlugs = ProductPlatform::supportedSlugs((int) $product['id']);
      $platformEntries = Platform::groupForClaimPage($supportedSlugs);
      $isolatedSingles = isolated_single_indexes($platformEntries);
      ?>
      <?php foreach ($platformEntries as $i => $entry): ?>
        <?php if ($entry['type'] === 'single'):
            $available = ($stock[$entry['slug']] ?? 0) > 0;
            render_platform_tile($entry['slug'], $available, $isolatedSingles[$i] ?? false);
        else:
            $groupAvailable = Platform::groupAvailableCount($entry['slugs'], $stock) > 0;
        ?>
          <details class="tile-group <?= $groupAvailable ? '' : 'disabled' ?>">
            <summary class="tile-group-summary">
              <span class="tile-icon"><?= Platform::icon($entry['slugs'][0]) ?></span>
              <span class="tile-info">
                <span class="tile-name"><?= Helpers::e($entry['label']) ?></span>
                <span class="tile-status"><?= Helpers::e(Platform::groupStatusLabel($entry['slugs'], $stock)) ?></span>
              </span>
              <svg class="group-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
            </summary>
            <div class="tile-group-body">
              <?php foreach ($entry['slugs'] as $platform):
                  $available = ($stock[$platform] ?? 0) > 0;
                  render_platform_tile($platform, $available);
              ?>
              <?php endforeach; ?>
            </div>
          </details>
        <?php endif; ?>
      <?php endforeach; ?>
    </div>
  <?php elseif (empty($claimedKeys)): ?>
    <p style="text-align:center; color:var(--text-muted); font-size:13.5px;">No claims are available to you for this product.</p>
  <?php endif; ?>

  <?php if (!empty($product['outro_text'])): ?>
  <div class="text-block" style="margin-top:28px;">
    <p class="text-block-label">Redeeming your key</p>
    <?= Helpers::renderRichText($product['outro_text']) ?>
  </div>
  <?php endif; ?>

  <footer>
    Having trouble? Contact the person who sent you this link.<br>
    Powered by <a href="https://www.keylair.com" target="_blank" rel="noopener"><?= Helpers::e(\KeyLair\Settings::siteName()) ?></a><br>
    <a href="/imprint">Imprint</a> · <a href="/privacy">Privacy</a>
  </footer>
</div>

<script>
  function showMedia(el){
    document.querySelectorAll('.thumb').forEach(t => t.classList.remove('active'));
    el.classList.add('active');
    const main = document.getElementById('media-main');
    const type = el.dataset.type;
    const src = el.dataset.src;
    main.classList.toggle('is-shot', type === 'shot');
    if(type === 'video'){
      main.innerHTML = '<iframe src="'+src+'" style="width:100%;height:100%;border:0;border-radius:inherit;position:relative;z-index:1;" allowfullscreen loading="lazy"></iframe>';
    } else {
      main.innerHTML = '<img src="'+src+'" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:inherit;position:relative;z-index:1;">';
    }
  }
  function copyCode(btn){
    const code = btn.previousElementSibling.textContent;
    navigator.clipboard?.writeText(code);
    const original = btn.textContent;
    btn.textContent = 'Copied';
    setTimeout(()=>btn.textContent = original, 1400);
  }
</script>
</body>
</html>
