<?php
/**
 * Live engagement statistics.
 *
 *   GET  /api/stats/heartbeat              (auth) → record a "watching now" ping
 *   POST /api/stats/heartbeat              (auth) → same, body may include channel
 *   GET  /api/admin/stats/live             (admin) → live-watcher counter
 *   GET  /api/admin/stats/installs         (admin) → total installs + DAU/WAU
 *
 * "Live watching" = unique device_ids that pinged within the last 90s.
 * "Total installs" = total fcm_tokens rows (one per device install) +
 *                    DAU (last 24h) + WAU (last 7d) windows.
 *
 * The client should fire `/api/stats/heartbeat` every ~60 seconds while
 * a stream is active (LiveTV / Movies / Series detail page mount).
 */

function stats_heartbeats_col() { return get_db()->stats_heartbeats; }

/** Common heartbeat upsert used by both GET and POST. */
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);
    $now = time();
    stats_heartbeats_col()->updateOne(
        ['device_id' => $device_id],
        [
            '$set' => [
                'device_id' => $device_id,
                'user_id'   => $u['id'],
                'channel'   => (string)($body['channel'] ?? $_GET['channel'] ?? ''),
                'kind'      => (string)($body['kind']    ?? $_GET['kind']    ?? 'live'),
                'updated_at_ts'  => $now,
                'updated_at_iso' => gmdate('c', $now),
            ],
            '$setOnInsert' => ['created_at_ts' => $now],
        ],
        ['upsert' => true]
    );
    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(); }

/** GET /api/admin/stats/live → { live_watchers, by_kind, top_channels } */
function route_admin_stats_live(): void {
    require_admin();
    $now = time();
    $window = max(30, min(600, (int)($_GET['window'] ?? 90))); // seconds
    $col = stats_heartbeats_col();
    $threshold = $now - $window;

    $live = $col->countDocuments(['updated_at_ts' => ['$gte' => $threshold]]);

    // by kind (live / vod / series)
    $by_kind = [];
    $cursor = $col->aggregate([
        ['$match' => ['updated_at_ts' => ['$gte' => $threshold]]],
        ['$group' => ['_id' => '$kind', 'count' => ['$sum' => 1]]],
    ]);
    foreach ($cursor as $row) {
        $r = is_array($row) ? $row : (array)$row;
        $by_kind[(string)($r['_id'] ?? 'unknown')] = (int)$r['count'];
    }

    // top channels (top 10)
    $top_channels = [];
    $cursor = $col->aggregate([
        ['$match' => [
            'updated_at_ts' => ['$gte' => $threshold],
            'channel'       => ['$ne' => ''],
        ]],
        ['$group' => ['_id' => '$channel', 'viewers' => ['$sum' => 1]]],
        ['$sort'  => ['viewers' => -1]],
        ['$limit' => 10],
    ]);
    foreach ($cursor as $row) {
        $r = is_array($row) ? $row : (array)$row;
        $top_channels[] = ['channel' => (string)$r['_id'], '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),
    ]);
}

/** GET /api/admin/stats/installs → total, active, DAU, WAU */
function route_admin_stats_installs(): void {
    require_admin();
    $col = get_db()->fcm_tokens;
    $now = time();
    $day = $now - 86400;
    $week = $now - 7 * 86400;

    $total  = $col->countDocuments([]);
    $active = $col->countDocuments(['is_active' => true]);

    // DAU/WAU based on heartbeats (more accurate than fcm token updates)
    $hb = stats_heartbeats_col();
    $dau = $hb->aggregate([
        ['$match' => ['updated_at_ts' => ['$gte' => $day]]],
        ['$group' => ['_id' => '$device_id']],
        ['$count' => 'n'],
    ])->toArray();
    $wau = $hb->aggregate([
        ['$match' => ['updated_at_ts' => ['$gte' => $week]]],
        ['$group' => ['_id' => '$device_id']],
        ['$count' => 'n'],
    ])->toArray();

    $dau_n = (isset($dau[0]) ? (int)((array)$dau[0])['n'] : 0);
    $wau_n = (isset($wau[0]) ? (int)((array)$wau[0])['n'] : 0);

    // Installs by platform
    $by_platform = [];
    $cursor = $col->aggregate([
        ['$group' => ['_id' => '$platform', 'count' => ['$sum' => 1]]],
    ]);
    foreach ($cursor as $row) {
        $r = is_array($row) ? $row : (array)$row;
        $by_platform[(string)($r['_id'] ?? 'unknown')] = (int)$r['count'];
    }

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