<?php
session_start();
require_once __DIR__ . '/auth.php';
include __DIR__ . '/includes/admin_header.php';

/**
 * Cloudflare Web Stats (GraphQL) - Smurfettes Country Delights
 * Loads secrets from outside web root (IIS safe folder), same pattern as your old sites.
 *
 * Default secrets path:
 *   C:\inetpub\Authentication\api\smurfettes.php
 *
 * File format:
 *   <?php return ['zone_id' => '...', 'api_token' => '...'];
 */

$configPath = 'C:/inetpub/Authentication/api/smurfettes.php';

$CF_ZONE_ID   = '';
$CF_API_TOKEN = '';

if (file_exists($configPath)) {
  $cf = require $configPath;
  $CF_ZONE_ID   = trim((string)($cf['zone_id'] ?? ''));
  $CF_API_TOKEN = trim((string)($cf['api_token'] ?? ''));
}

$tokenMissing = ($CF_API_TOKEN === '' || preg_match('/\s/', $CF_API_TOKEN) || $CF_ZONE_ID === '');

// ----------------- Helpers -----------------
function iso_utc(int $ts): string { return gmdate('Y-m-d\TH:i:s\Z', $ts); }
function fmt_int($n): string { if ($n === null || $n === '') return '—'; return number_format((float)$n, 0, '.', ','); }
function fmt_bytes($bytes): string {
  if ($bytes === null || $bytes === '') return '—';
  $bytes = (float)$bytes;
  $units = ['B','KB','MB','GB','TB']; $i = 0;
  while ($bytes >= 1024 && $i < count($units)-1) { $bytes /= 1024; $i++; }
  return number_format($bytes, $i === 0 ? 0 : 2) . ' ' . $units[$i];
}
function fmt_pct($n): string { if ($n === null || $n === '') return '—'; return rtrim(rtrim(number_format((float)$n, 2, '.', ''), '0'), '.') . '%'; }

function cf_rest_get(string $url, string $token): array {
  $token = trim((string)$token);
  $ch = curl_init($url);
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
      'Authorization: Bearer ' . $token,
      'Accept: application/json',
      'Content-Type: application/json',
    ],
  ]);
  $raw  = curl_exec($ch);
  $err  = curl_error($ch);
  $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  if ($raw === false) return ['success' => false, 'errors' => [['message' => 'cURL error: ' . $err]], '_http_code' => $code];
  $json = json_decode($raw, true);
  if (!is_array($json)) return ['success' => false, 'errors' => [['message' => 'Invalid JSON. HTTP ' . $code]], '_http_code' => $code, '_raw' => substr((string)$raw, 0, 300)];
  $json['_http_code'] = $code;
  return $json;
}

function cf_gql(string $query, array $vars, string $token): array {
  $token = trim((string)$token);
  $ch = curl_init("https://api.cloudflare.com/client/v4/graphql");
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
      'Authorization: Bearer ' . $token,
      'Content-Type: application/json',
      'Accept: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['query' => $query, 'variables' => $vars]),
  ]);
  $raw  = curl_exec($ch);
  $err  = curl_error($ch);
  $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  if ($raw === false) return ['_http_code' => $code, '_raw' => null, 'errors' => [['message' => 'cURL error: ' . $err]]];
  $json = json_decode($raw, true);
  if (!is_array($json)) return ['_http_code' => $code, '_raw' => substr((string)$raw, 0, 500), 'errors' => [['message' => 'Invalid JSON from GraphQL']]];
  $json['_http_code'] = $code;
  return $json;
}

function extract_http_1h_groups(array $gql): array {
  $groups = $gql['data']['viewer']['zones'][0]['httpRequests1hGroups'] ?? [];
  $series = [];
  foreach ($groups as $row) {
    $series[] = [
      't' => $row['dimensions']['datetime'] ?? '',
      'requests' => $row['sum']['requests'] ?? null,
      'bytes' => $row['sum']['bytes'] ?? null,
      'cachedRequests' => $row['sum']['cachedRequests'] ?? null,
      'cachedBytes' => $row['sum']['cachedBytes'] ?? null,
      'threats' => $row['sum']['threats'] ?? null,
      'pageViews' => $row['sum']['pageViews'] ?? null,
      'uniques' => $row['uniq']['uniques'] ?? null,
    ];
  }
  return $series;
}

function totals_from_series(array $series): array {
  $tot = ['requests'=>0,'bytes'=>0,'cachedRequests'=>0,'cachedBytes'=>0,'threats'=>0,'pageViews'=>0,'uniques'=>null,'cacheHitPct'=>null];
  $maxUniques = null;
  foreach ($series as $r) {
    $tot['requests'] += (int)($r['requests'] ?? 0);
    $tot['bytes'] += (int)($r['bytes'] ?? 0);
    $tot['cachedRequests'] += (int)($r['cachedRequests'] ?? 0);
    $tot['cachedBytes'] += (int)($r['cachedBytes'] ?? 0);
    $tot['threats'] += (int)($r['threats'] ?? 0);
    $tot['pageViews'] += (int)($r['pageViews'] ?? 0);
    if ($r['uniques'] !== null) {
      $u = (int)$r['uniques'];
      $maxUniques = ($maxUniques === null) ? $u : max($maxUniques, $u);
    }
  }
  $tot['uniques'] = $maxUniques;
  $tot['cacheHitPct'] = ($tot['requests'] > 0) ? round(($tot['cachedRequests'] / $tot['requests']) * 100, 2) : null;
  return $tot;
}

// Tiny inline sparkline SVG (no JS)
function sparkline(array $values, int $w=220, int $h=40): string {
  $vals = array_values(array_filter($values, function($v){ return $v !== null && $v !== ''; }));
  if (count($vals) < 2) return '<span style="opacity:.7;">—</span>';

  $min = min($vals); $max = max($vals);
  $range = ($max - $min) ?: 1;

  $pts = [];
  $n = count($vals);
  for ($i=0; $i<$n; $i++) {
    $x = ($w - 4) * ($i / ($n - 1)) + 2;
    $y = ($h - 4) * (1 - (($vals[$i] - $min) / $range)) + 2;
    $pts[] = round($x,2) . ',' . round($y,2);
  }
  $poly = implode(' ', $pts);

  return '<svg width="'.$w.'" height="'.$h.'" viewBox="0 0 '.$w.' '.$h.'" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="trend" style="color:var(--accent);">
    <polyline fill="none" stroke="currentColor" stroke-width="2" points="'.$poly.'"/>
  </svg>';
}

// =========================================================
// FETCH STATS
// =========================================================
$now   = time();
$until = iso_utc($now);
$since24 = iso_utc($now - 86400);
$since72 = iso_utc($now - 86400 * 3);

$GQL = <<<'GQL'
query($zoneTag: String!, $since: DateTime!, $until: DateTime!) {
  viewer {
    zones(filter: { zoneTag: $zoneTag }) {
      httpRequests1hGroups(
        limit: 1000
        filter: { datetime_geq: $since, datetime_leq: $until }
      ) {
        dimensions { datetime }
        sum {
          requests
          bytes
          cachedRequests
          cachedBytes
          threats
          pageViews
        }
        uniq { uniques }
      }
    }
  }
}
GQL;

$g24 = $g72 = $verify = null;
$s24 = $s72 = [];
$t24 = $t72 = [];
$errorMsg = null;

if (!$tokenMissing) {
  $vars24 = ['zoneTag' => $CF_ZONE_ID, 'since' => $since24, 'until' => $until];
  $vars72 = ['zoneTag' => $CF_ZONE_ID, 'since' => $since72, 'until' => $until];

  $g24 = cf_gql($GQL, $vars24, $CF_API_TOKEN);
  $g72 = cf_gql($GQL, $vars72, $CF_API_TOKEN);
  $verify = cf_rest_get("https://api.cloudflare.com/client/v4/user/tokens/verify", $CF_API_TOKEN);

  if (!empty($g24['errors'])) $errorMsg = $g24['errors'][0]['message'] ?? 'GraphQL error (24h).';
  elseif (!empty($g72['errors'])) $errorMsg = $g72['errors'][0]['message'] ?? 'GraphQL error (72h).';
  else {
    $s24 = extract_http_1h_groups($g24);
    $s72 = extract_http_1h_groups($g72);
    $t24 = totals_from_series($s24);
    $t72 = totals_from_series($s72);
  }
}

// DEBUG MODE (admin only)
if (isset($_GET['debug']) && (($_SESSION['role'] ?? '') === 'admin')) {
  header('Content-Type: text/plain; charset=utf-8');

  echo "=== SYSTEM ===\n";
  echo "curl loaded: " . (extension_loaded('curl') ? "YES\n" : "NO\n");
  echo "openssl loaded: " . (extension_loaded('openssl') ? "YES\n" : "NO\n");
  echo "token missing: " . ($tokenMissing ? "YES\n" : "NO\n");
  echo "token length: " . strlen($CF_API_TOKEN) . "\n";
  echo "contains whitespace: " . (preg_match('/\s/', $CF_API_TOKEN) ? "YES\n" : "NO\n");
  echo "zone id length: " . strlen($CF_ZONE_ID) . "\n";
  echo "token preview: " . ($CF_API_TOKEN ? (substr($CF_API_TOKEN, 0, 4) . "..." . substr($CF_API_TOKEN, -4)) : "—") . "\n";
  echo "config file exists: " . (file_exists($configPath) ? "YES\n" : "NO\n") . "\n";
  echo "config path: " . $configPath . "\n\n";

  echo "=== TOKEN VERIFY (REST) ===\n";
  echo "HTTP Code: " . ($verify['_http_code'] ?? 'none') . "\n";
  echo json_encode($verify, JSON_PRETTY_PRINT) . "\n\n";

  echo "=== GRAPHQL 24H ===\n";
  echo "HTTP Code: " . ($g24['_http_code'] ?? 'none') . "\n";
  echo "errors: " . json_encode($g24['errors'] ?? [], JSON_PRETTY_PRINT) . "\n";
  echo "first row: " . json_encode(($g24['data']['viewer']['zones'][0]['httpRequests1hGroups'][0] ?? null), JSON_PRETTY_PRINT) . "\n\n";

  echo "=== GRAPHQL 72H ===\n";
  echo "HTTP Code: " . ($g72['_http_code'] ?? 'none') . "\n";
  echo "errors: " . json_encode($g72['errors'] ?? [], JSON_PRETTY_PRINT) . "\n";
  echo "first row: " . json_encode(($g72['data']['viewer']['zones'][0]['httpRequests1hGroups'][0] ?? null), JSON_PRETTY_PRINT) . "\n\n";

  echo "=== TOTALS (24H) ===\n";
  echo json_encode($t24, JSON_PRETTY_PRINT) . "\n\n";
  echo "=== TOTALS (72H) ===\n";
  echo json_encode($t72, JSON_PRETTY_PRINT) . "\n";

  exit;
}
?>

<section class="content-card center-text">
  <h1 class="admin-title">📈 Cloudflare Web Stats</h1>
  <p style="opacity:.85;margin-top:-6px;">Smurfettes Country Delights</p>
  <div style="margin-top:10px;">
    <a href="/admin/index.php" class="admin-card-link" style="display:inline-block;padding:10px 14px;max-width:220px;">← Return to Admin</a>
  </div>
</section>

<?php if ($tokenMissing): ?>
  <section class="content-card">
    <h2 style="margin-top:0;">⚠️ Cloudflare API Token missing/invalid</h2>
    <p style="opacity:.9;">
      Secrets should be in:<br>
      <code><?= htmlspecialchars($configPath) ?></code><br><br>
      Ensure it contains <code>zone_id</code> and <code>api_token</code> and token has no spaces/newlines.
    </p>
  </section>

<?php elseif ($errorMsg): ?>
  <section class="content-card">
    <h2 style="margin-top:0;">⚠️ Could not load Cloudflare stats</h2>
    <p style="opacity:.9;">
      <?= htmlspecialchars($errorMsg) ?><br><br>
      <span style="opacity:.8;">Tip: try <code>?debug=1</code> (admin only) to see token verify + GraphQL output.</span>
    </p>
  </section>

<?php else: ?>

  <section class="content-card">
    <div class="admin-grid" style="grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px;">

      <div class="admin-card-link" style="text-align:left;">
        <div style="font-weight:900;font-size:18px;">Last 24h Requests</div>
        <div style="font-size:28px;font-weight:900;margin-top:6px;"><?= fmt_int($t24['requests'] ?? null) ?></div>
        <div style="margin-top:8px;"><?= sparkline(array_map(function($r){ return $r['requests']; }, $s24)) ?></div>
      </div>

      <div class="admin-card-link" style="text-align:left;">
        <div style="font-weight:900;font-size:18px;">Last 24h Bandwidth</div>
        <div style="font-size:28px;font-weight:900;margin-top:6px;"><?= fmt_bytes($t24['bytes'] ?? null) ?></div>
        <div style="margin-top:8px;"><?= sparkline(array_map(function($r){ return $r['bytes']; }, $s24)) ?></div>
      </div>

      <div class="admin-card-link" style="text-align:left;">
        <div style="font-weight:900;font-size:18px;">Last 24h Uniques</div>
        <div style="font-size:28px;font-weight:900;margin-top:6px;"><?= fmt_int($t24['uniques'] ?? null) ?></div>
        <div style="margin-top:8px;"><?= sparkline(array_map(function($r){ return $r['uniques']; }, $s24)) ?></div>
      </div>

      <div class="admin-card-link" style="text-align:left;">
        <div style="font-weight:900;font-size:18px;">Last 24h Pageviews</div>
        <div style="font-size:28px;font-weight:900;margin-top:6px;"><?= fmt_int($t24['pageViews'] ?? null) ?></div>
        <div style="margin-top:8px;"><?= sparkline(array_map(function($r){ return $r['pageViews']; }, $s24)) ?></div>
      </div>

      <div class="admin-card-link" style="text-align:left;">
        <div style="font-weight:900;font-size:18px;">Last 24h Threats</div>
        <div style="font-size:28px;font-weight:900;margin-top:6px;"><?= fmt_int($t24['threats'] ?? null) ?></div>
        <div style="margin-top:8px;"><?= sparkline(array_map(function($r){ return $r['threats']; }, $s24)) ?></div>
      </div>

      <div class="admin-card-link" style="text-align:left;">
        <div style="font-weight:900;font-size:18px;">24h Cache Hit</div>
        <div style="font-size:28px;font-weight:900;margin-top:6px;"><?= fmt_pct($t24['cacheHitPct'] ?? null) ?></div>
        <div style="margin-top:8px;">
          <?= sparkline(array_map(function($r){
            $req = (int)($r['requests'] ?? 0);
            $c   = (int)($r['cachedRequests'] ?? 0);
            return $req > 0 ? round(($c/$req)*100, 2) : null;
          }, $s24)) ?>
        </div>
      </div>

      <div class="admin-card-link" style="text-align:left;">
        <div style="font-weight:900;font-size:18px;">Last 72h Requests</div>
        <div style="font-size:28px;font-weight:900;margin-top:6px;"><?= fmt_int($t72['requests'] ?? null) ?></div>
        <div style="margin-top:8px;"><?= sparkline(array_map(function($r){ return $r['requests']; }, $s72)) ?></div>
      </div>

      <div class="admin-card-link" style="text-align:left;">
        <div style="font-weight:900;font-size:18px;">Last 72h Bandwidth</div>
        <div style="font-size:28px;font-weight:900;margin-top:6px;"><?= fmt_bytes($t72['bytes'] ?? null) ?></div>
        <div style="margin-top:8px;"><?= sparkline(array_map(function($r){ return $r['bytes']; }, $s72)) ?></div>
      </div>

    </div>
  </section>

<?php endif; ?>

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