<?php
/**
 * Live engagement statistics — PHP/MySQL edition.
 *
 *   POST /api/stats/heartbeat              (auth) → record device ping
 *   GET  /api/stats/heartbeat              (auth) → same (allows easy GET)
 *   GET  /api/admin/stats/live             (admin) → live-watcher counter
 *   GET  /api/admin/stats/installs         (admin) → total/active/DAU/WAU
 *
 * Tables:
 *   • stats_heartbeats — auto-created on first request
 *
 * Live = unique device_ids that pinged within the last 90 seconds.
 */

function stats_ensure_schema(): void {
    static $done = false;
    if ($done) return;
    $done = true;

    $sql = <<<SQL
CREATE TABLE IF NOT EXISTS `stats_heartbeats` (
  `device_id`      VARCHAR(64)  NOT NULL PRIMARY KEY,
  `user_id`        VARCHAR(64)           DEFAULT NULL,
  `channel`        VARCHAR(255) NOT NULL DEFAULT '',
  `kind`           VARCHAR(16)  NOT NULL DEFAULT 'live',
  `created_at_ts`  INT UNSIGNED NOT NULL,
  `updated_at_ts`  INT UNSIGNED NOT NULL,
  `updated_at_iso` VARCHAR(40)  NOT NULL,
  INDEX `ix_heartbeats_updated` (`updated_at_ts`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SQL;
    foreach (explode(';', $sql) as $stmt) {
        $stmt = trim($stmt);
        if ($stmt !== '') db()->exec($stmt);
    }
}

function _stats_heartbeat_record(): void {
    $u = require_auth();
    $body = [];
    if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') {
        $raw = file_get_contents('php://input') ?: '';
        $j = json_decode($raw, true);
        if (is_array($j)) $body = $j;
    }
    $device_id = trim((string)($body['device_id'] ?? $_GET['device_id'] ?? ''));
    if ($device_id === '') $device_id = 'web-' . substr(md5($u['id'] . ($_SERVER['REMOTE_ADDR'] ?? '')), 0, 12);

    stats_ensure_schema();
    $now = time();
    $stmt = db()->prepare(
        'INSERT INTO stats_heartbeats
            (device_id, user_id, channel, kind, created_at_ts, updated_at_ts, updated_at_iso)
         VALUES (?, ?, ?, ?, ?, ?, ?)
         ON DUPLICATE KEY UPDATE
            user_id = VALUES(user_id),
            channel = VALUES(channel),
            kind = VALUES(kind),
            updated_at_ts = VALUES(updated_at_ts),
            updated_at_iso = VALUES(updated_at_iso)'
    );
    $stmt->execute([
        $device_id, $u['id'],
        (string)($body['channel'] ?? $_GET['channel'] ?? ''),
        (string)($body['kind']    ?? $_GET['kind']    ?? 'live'),
        $now, $now, gmdate('c', $now),
    ]);
    send_json(['ok' => true, 'device_id' => $device_id]);
}

function route_stats_heartbeat_get(): void  { _stats_heartbeat_record(); }
function route_stats_heartbeat_post(): void { _stats_heartbeat_record(); }

function route_admin_stats_live(): void {
    require_admin();
    stats_ensure_schema();
    $now = time();
    $window = max(30, min(600, (int)($_GET['window'] ?? 90)));
    $threshold = $now - $window;

    $stmt = db()->prepare('SELECT COUNT(*) FROM stats_heartbeats WHERE updated_at_ts >= ?');
    $stmt->execute([$threshold]);
    $live = (int)$stmt->fetchColumn();

    $by_kind = [];
    $stmt = db()->prepare(
        'SELECT kind, COUNT(*) AS c FROM stats_heartbeats
         WHERE updated_at_ts >= ? GROUP BY kind'
    );
    $stmt->execute([$threshold]);
    foreach ($stmt->fetchAll() as $r) $by_kind[(string)$r['kind']] = (int)$r['c'];

    $top_channels = [];
    $stmt = db()->prepare(
        "SELECT channel, COUNT(*) AS viewers FROM stats_heartbeats
         WHERE updated_at_ts >= ? AND channel <> ''
         GROUP BY channel ORDER BY viewers DESC LIMIT 10"
    );
    $stmt->execute([$threshold]);
    foreach ($stmt->fetchAll() as $r) {
        $top_channels[] = ['channel' => (string)$r['channel'], 'viewers' => (int)$r['viewers']];
    }

    send_json([
        'live_watchers'  => $live,
        'window_seconds' => $window,
        'by_kind'        => $by_kind,
        'top_channels'   => $top_channels,
        'as_of'          => gmdate('c', $now),
    ]);
}

function route_admin_stats_installs(): void {
    require_admin();
    stats_ensure_schema();
    fcm_ensure_schema(); // declared in notifications.php — same request

    $now = time();
    $day  = $now - 86400;
    $week = $now - 7 * 86400;

    $total  = (int)db()->query('SELECT COUNT(*) FROM fcm_tokens')->fetchColumn();
    $active = (int)db()->query('SELECT COUNT(*) FROM fcm_tokens WHERE is_active = 1')->fetchColumn();

    $stmt = db()->prepare('SELECT COUNT(DISTINCT device_id) FROM stats_heartbeats WHERE updated_at_ts >= ?');
    $stmt->execute([$day]);
    $dau = (int)$stmt->fetchColumn();
    $stmt->execute([$week]);
    $wau = (int)$stmt->fetchColumn();

    $by_platform = [];
    foreach (db()->query('SELECT platform, COUNT(*) AS c FROM fcm_tokens GROUP BY platform')->fetchAll() as $r) {
        $by_platform[(string)$r['platform']] = (int)$r['c'];
    }

    send_json([
        'total_installs'  => $total,
        'active_installs' => $active,
        'dau'             => $dau,
        'wau'             => $wau,
        'by_platform'     => $by_platform,
        'as_of'           => gmdate('c', $now),
    ]);
}
