<?php
declare(strict_types=1);

/**
 * Gamdom wager-events API (wager-events-api/gamdom) yardımcıları.
 */

/** @var string|null */
$GLOBALS['_gamdom_cacert_path'] = null;

function gamdom_curl_cacert_path(): string
{
    if ($GLOBALS['_gamdom_cacert_path'] !== null) {
        return $GLOBALS['_gamdom_cacert_path'];
    }
    $candidate = __DIR__ . DIRECTORY_SEPARATOR . 'cacert.pem';
    $GLOBALS['_gamdom_cacert_path'] = is_readable($candidate) ? $candidate : '';

    return $GLOBALS['_gamdom_cacert_path'];
}

/** Windows / yerel PHP'de SSL issuer hatasını giderir (api/cacert.pem). */
function gamdom_curl_apply_ssl($ch): void
{
    if (!is_resource($ch) && !($ch instanceof CurlHandle)) {
        return;
    }
    $cacert = gamdom_curl_cacert_path();
    if ($cacert !== '') {
        curl_setopt($ch, CURLOPT_CAINFO, $cacert);
    }
}

function gamdom_month_label_tr(string $monthId): string
{
    if (!preg_match('/^(\d{4})-(\d{2})$/', $monthId, $m)) {
        return $monthId;
    }
    $names = [
        '01' => 'Ocak', '02' => 'Şubat', '03' => 'Mart', '04' => 'Nisan',
        '05' => 'Mayıs', '06' => 'Haziran', '07' => 'Temmuz', '08' => 'Ağustos',
        '09' => 'Eylül', '10' => 'Ekim', '11' => 'Kasım', '12' => 'Aralık',
    ];
    $mon = $names[$m[2]] ?? $m[2];

    return $mon . ' ' . $m[1];
}

function gamdom_iso_to_unix(?string $iso): ?int
{
    if ($iso === null || trim($iso) === '') {
        return null;
    }
    try {
        $dt = new DateTimeImmutable(trim($iso));
        return $dt->getTimestamp();
    } catch (Exception) {
        return null;
    }
}

function gamdom_format_money(string $amount, string $currency): string
{
    $raw = preg_replace('/[^\d.-]/', '', $amount);
    if ($raw === '' || $raw === null) {
        return '';
    }
    $num = (float) $raw;
    $formatted = number_format($num, 2, '.', ',');
    $cur = strtoupper(trim($currency));
    if ($cur === 'TRY' || $cur === 'TL') {
        return $formatted . '₺';
    }
    if ($cur === 'USD' || $cur === 'USDT') {
        return $formatted . '$';
    }
    if ($cur === 'EUR') {
        return $formatted . '€';
    }

    return $formatted . ' ' . $cur;
}

/**
 * @return array{entries: array<int, array>, meta: array<string, mixed>}|null
 */
function gamdom_parse_wager_api_payload(array $decoded): ?array
{
    $data = null;
    if (isset($decoded['data']) && is_array($decoded['data'])) {
        $data = $decoded['data'];
    } elseif (isset($decoded['entries']) && is_array($decoded['entries'])) {
        $data = $decoded;
    }
    if ($data === null) {
        return null;
    }

    $currency = trim((string) ($data['currency'] ?? 'USD'));
    $rewardCurrency = trim((string) ($data['rewardCurrency'] ?? 'TRY'));
    $prizePoolRaw = trim((string) ($data['prizePool'] ?? ''));
    $prizePool = $prizePoolRaw !== '' ? gamdom_format_money($prizePoolRaw, $rewardCurrency) : '';

    $periods = [];
    if (isset($data['availableMonths']) && is_array($data['availableMonths'])) {
        foreach ($data['availableMonths'] as $m) {
            $id = trim((string) $m);
            if ($id === '') {
                continue;
            }
            $periods[] = ['id' => $id, 'label' => gamdom_month_label_tr($id)];
        }
    }

    $selectedMonth = trim((string) ($data['selectedMonth'] ?? ''));
    if ($selectedMonth === '' && $periods !== []) {
        $selectedMonth = $periods[0]['id'];
    }

    $rawEntries = isset($data['entries']) && is_array($data['entries']) ? $data['entries'] : [];
    $entries = [];
    foreach ($rawEntries as $row) {
        if (!is_array($row)) {
            continue;
        }
        $position = isset($row['position']) ? (int) $row['position'] : 0;
        if ($position < 1 || $position > 50) {
            continue;
        }
        $userId = isset($row['user_id']) ? (int) $row['user_id'] : 0;
        $hidden = $userId === -1 || (isset($row['hidden']) && !empty($row['hidden']));
        $username = $hidden ? 'Hidden user' : trim((string) ($row['username'] ?? ''));
        if ($username === '' && !$hidden) {
            $username = '—';
        }
        $pointsRaw = trim((string) ($row['points'] ?? $row['wager'] ?? '0'));
        $wager = (float) preg_replace('/[^\d.-]/', '', $pointsRaw);
        $wagerDisplay = gamdom_format_money($pointsRaw, $currency);
        $rewardRaw = trim((string) ($row['reward'] ?? ''));
        $reward = $rewardRaw !== '' ? gamdom_format_money($rewardRaw, $rewardCurrency) : '';

        $entries[] = [
            'rank' => $position,
            'username' => $username,
            'hidden' => $hidden,
            'wager' => $wager,
            'wagerDisplay' => $wagerDisplay,
            'reward' => $reward,
        ];
    }

    usort($entries, static fn (array $a, array $b): int => ($a['rank'] ?? 0) <=> ($b['rank'] ?? 0));

    return [
        'entries' => $entries,
        'meta' => [
            'title' => trim((string) ($data['name'] ?? '')),
            'prizePool' => $prizePool,
            'currency' => $currency,
            'rewardCurrency' => $rewardCurrency,
            'status' => trim((string) ($data['status'] ?? '')),
            'startAt' => gamdom_iso_to_unix(isset($data['startAt']) ? (string) $data['startAt'] : null),
            'endAt' => gamdom_iso_to_unix(isset($data['endAt']) ? (string) $data['endAt'] : null),
            'periods' => $periods,
            'activePeriodId' => $selectedMonth,
        ],
    ];
}

/**
 * @param array<string, mixed> $api
 * @return array{ok: bool, body?: string, error?: string, httpCode?: int}
 */
function gamdom_fetch_wager_api(array $api, string $month = ''): array
{
    $url = trim((string) ($api['url'] ?? ''));
    if ($url === '' || !preg_match('#^https?://#i', $url)) {
        return ['ok' => false, 'error' => 'API URL geçersiz'];
    }

    $monthParam = trim((string) ($api['monthParam'] ?? 'month'));
    if ($monthParam === '') {
        $monthParam = 'month';
    }
    if ($month !== '' && preg_match('/^\d{4}-\d{2}$/', $month)) {
        $sep = str_contains($url, '?') ? '&' : '?';
        $url .= $sep . rawurlencode($monthParam) . '=' . rawurlencode($month);
    }

    $clientId = trim((string) ($api['clientId'] ?? $api['xClient'] ?? 'mocker.com'));
    $key = trim((string) ($api['apiKey'] ?? ''));
    $origin = trim((string) ($api['origin'] ?? 'https://mocker27.com'));
    $method = strtoupper(trim((string) ($api['method'] ?? 'GET')));
    if (!in_array($method, ['GET', 'POST'], true)) {
        $method = 'GET';
    }

    $headers = [
        'Accept: application/json',
        'Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7',
        'User-Agent: Mozilla/5.0 (compatible; Mocker-Gamdom/1.0)',
        'Origin: ' . $origin,
        'Referer: ' . rtrim($origin, '/') . '/',
    ];
    if ($clientId !== '') {
        $headers[] = 'X-Client: ' . $clientId;
    }
    if ($key !== '') {
        $headers[] = 'Authorization: Bearer ' . $key;
    }

    $ch = curl_init($url);
    if ($ch === false) {
        return ['ok' => false, 'error' => 'cURL başlatılamadı'];
    }

    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS => 3,
        CURLOPT_TIMEOUT => 25,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_ENCODING => '',
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
    ]);
    gamdom_curl_apply_ssl($ch);

    $body = curl_exec($ch);
    $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlErr = curl_error($ch);
    curl_close($ch);

    if ($body === false || $httpCode < 200 || $httpCode >= 300) {
        return [
            'ok' => false,
            'error' => 'API yanıtı alınamadı' . ($curlErr !== '' ? ': ' . $curlErr : " (HTTP $httpCode)"),
            'httpCode' => $httpCode,
        ];
    }

    return ['ok' => true, 'body' => $body, 'httpCode' => $httpCode];
}

/**
 * @param array<string, mixed> $cfg
 * @return array{ok: true, payload: array<string, mixed>}|array{ok: false, error: string}
 */
function gamdom_build_live_payload(array $cfg, string $periodId = ''): array
{
    $api = isset($cfg['api']) && is_array($cfg['api']) ? $cfg['api'] : [];
    if (empty($api['enabled'])) {
        return ['ok' => false, 'error' => 'API kapalı'];
    }

    $fetch = gamdom_fetch_wager_api($api, $periodId);
    if (!$fetch['ok']) {
        return ['ok' => false, 'error' => $fetch['error'] ?? 'fetch failed'];
    }

    $decoded = json_decode($fetch['body'] ?? '', true);
    if (!is_array($decoded)) {
        return ['ok' => false, 'error' => 'API JSON değil'];
    }
    if (isset($decoded['status']) && $decoded['status'] !== true && $decoded['status'] !== 1) {
        return ['ok' => false, 'error' => 'API status false'];
    }

    $parsed = gamdom_parse_wager_api_payload($decoded);
    if ($parsed === null) {
        return ['ok' => false, 'error' => 'API veri yapısı tanınmadı'];
    }

    $meta = $parsed['meta'];
    $activePeriodId = $meta['activePeriodId'] !== '' ? $meta['activePeriodId'] : $periodId;

    $title = trim((string) ($cfg['title'] ?? ''));
    if ($title === '' && $meta['title'] !== '') {
        $title = $meta['title'];
    }
    if ($title === '') {
        $title = 'Gamdom Çevrim Etkinliği';
    }

    $prizePool = trim((string) ($cfg['prizePool'] ?? ''));
    if ($prizePool === '' && $meta['prizePool'] !== '') {
        $prizePool = $meta['prizePool'];
    }

    $endAt = $cfg['endAt'] ?? null;
    if ($endAt === null || $endAt === '') {
        $endAt = $meta['endAt'];
    } else {
        $endAt = (int) $endAt;
    }

    $periods = $meta['periods'];
    if ($periods === [] && isset($cfg['periods']) && is_array($cfg['periods'])) {
        foreach ($cfg['periods'] as $p) {
            if (!is_array($p)) {
                continue;
            }
            $id = trim((string) ($p['id'] ?? ''));
            if ($id === '') {
                continue;
            }
            $periods[] = [
                'id' => $id,
                'label' => trim((string) ($p['label'] ?? '')) ?: gamdom_month_label_tr($id),
            ];
        }
    }

    return [
        'ok' => true,
        'payload' => [
            'ok' => true,
            'enabled' => true,
            'source' => 'api',
            'title' => $title,
            'prizePool' => $prizePool,
            'logoUrl' => trim((string) ($cfg['logoUrl'] ?? '')),
            'ctaLabel' => trim((string) ($cfg['ctaLabel'] ?? '')),
            'ctaUrl' => trim((string) ($cfg['ctaUrl'] ?? '')),
            'rulesUrl' => trim((string) ($cfg['rulesUrl'] ?? '')),
            'rulesText' => trim((string) ($cfg['rulesText'] ?? '')),
            'rulesTitle' => trim((string) ($cfg['rulesTitle'] ?? '')) ?: 'Kurallar ve Şartlar',
            'endAt' => $endAt,
            'activePeriodId' => $activePeriodId,
            'periods' => $periods,
            'entries' => $parsed['entries'],
        ],
    ];
}
