<?php

declare(strict_types=1);

$dialect = getenv('POC_DIALECT');
$url = rtrim((string)getenv('POC_BASE_URL'), '/');
$activityId = (int)getenv('POC_ACTIVITY_ID');
if (!in_array($dialect, ['mysql', 'dm'], true) || !$url || $activityId <= 0) exit(2);
$pdo = static function (bool $ai) use ($dialect): PDO {
    $prefix = $ai ? 'POC_AI_' : 'POC_';
    $host = getenv($prefix . 'HOST');
    $port = getenv($prefix . 'PORT');
    $schema = getenv($prefix . 'SCHEMA');
    $dsn = $dialect === 'dm'
        ? "dm:host=$host;port=$port;schema=$schema"
        : "mysql:host=$host;port=$port;dbname=$schema;charset=utf8mb4";
    return new PDO($dsn, getenv($prefix . 'USER'), getenv($prefix . 'PASSWORD'),
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
};
$ai = $pdo(true);
$store = $pdo(false);
$activity = $dialect === 'dm' ? 'YOSHOP_ACTIVITY' : 'yoshop_activity';
$registration = $dialect === 'dm' ? 'YOSHOP_ACTIVITY_REGISTER' : 'yoshop_activity_register';
$health = $dialect === 'dm' ? 'YDY_HEALTH_RECORD' : 'ydy_health_record';
$session = $dialect === 'dm' ? 'YDY_MEASUREMENT_SESSION' : 'ydy_measurement_session';
$query = $ai->prepare('SELECT START_TIME,END_TIME FROM ' . $activity . ' WHERE ID=?');
$query->execute([$activityId]);
$range = array_change_key_case($query->fetch(PDO::FETCH_ASSOC) ?: [], CASE_LOWER);
if (empty($range['start_time']) || empty($range['end_time'])) exit(3);
$query = $ai->prepare('SELECT USER_ID FROM ' . $registration . ' WHERE ACTIVITY_ID=?');
$query->execute([$activityId]);
$userIds = array_values(array_unique(array_map('intval', $query->fetchAll(PDO::FETCH_COLUMN))));
if (!$userIds) exit(3);
$marks = implode(',', array_fill(0, count($userIds), '?'));
$query = $store->prepare('SELECT R.AI_USER_ID AS USER_ID,MAX(R.VALUE) AS BEST_COUNT FROM '
    . $health . ' R JOIN ' . $session . ' S ON R.SESSION_ID=S.SESSION_ID'
    . ' WHERE R.AI_USER_ID IN (' . $marks . ')'
    . " AND S.DEVICE_TYPE='jump_rope' AND S.IS_VALID=1 AND R.METRIC_CODE='jump_count'"
    . ' AND R.START_TIME BETWEEN ? AND ? GROUP BY R.AI_USER_ID ORDER BY BEST_COUNT DESC');
$query->execute(array_merge($userIds, [(string)$range['start_time'], (string)$range['end_time']]));
$expected = array_map(static function (array $row): array {
    $row = array_change_key_case($row, CASE_LOWER);
    return ['userId' => (int)$row['user_id'], 'bestCount' => (int)$row['best_count']];
}, $query->fetchAll(PDO::FETCH_ASSOC));
if (!$expected) throw new RuntimeException('Nonempty leaderboard fixture unexpectedly has no health data');
$body = file_get_contents($url . '/api/activity/leaderboard?storeId=10001&id=' . $activityId . '&limit=50');
$response = is_string($body) ? json_decode($body, true) : null;
if (!is_array($response) || (int)($response['status'] ?? 0) !== 200) {
    throw new RuntimeException('Activity leaderboard HTTP request failed');
}
$actual = array_map(static function (array $row): array {
    return ['userId' => (int)($row['userId'] ?? 0), 'bestCount' => (int)($row['bestCount'] ?? 0)];
}, (array)($response['data']['list'] ?? []));
if ($actual !== $expected) {
    throw new RuntimeException('Activity leaderboard differs from cross-database readback');
}
echo json_encode(['dialect' => $dialect, 'activity_id' => $activityId,
    'registrations' => count($userIds), 'leaderboard_rows' => count($actual),
    'cross_database_readback_matches' => true]) . PHP_EOL;
