<?php
if (!function_exists('smurf_get_stream_config')) {
function smurf_get_stream_config(): array {
    $cfg = [
        'server_ip' => 'cr3.broadcasturself.com',
        'server_port' => '65001',
        'admin_user' => 'HomeTimeRadio',
        'admin_password' => 'KFnph5qQuBPXaT3VJ4jp',
        'mount_main' => '/stream',
        'mount_auto' => '/autodj',
        'mount_backup' => '/autodj2',
        'listen_url' => 'http://cr3.broadcasturself.com:65001/stream',
    ];

    $settingsFile = dirname(__DIR__) . '/data/settings.json';
    if (is_file($settingsFile)) {
        $settings = json_decode((string)file_get_contents($settingsFile), true);
        if (is_array($settings) && !empty($settings['stream_url'])) {
            $cfg['listen_url'] = trim((string)$settings['stream_url']);
        }
    }

    return $cfg;
}
}

if (!function_exists('smurf_fetch_icecast_xml')) {
function smurf_fetch_icecast_xml(): string {
    $cfg = smurf_get_stream_config();
    $hostname = trim((string)($cfg['server_ip'] ?? ''));
    $port = trim((string)($cfg['server_port'] ?? ''));
    $user = (string)($cfg['admin_user'] ?? '');
    $pass = (string)($cfg['admin_password'] ?? '');

    if ($hostname === '' || $port === '' || $user === '' || $pass === '') {
        return '';
    }

    foreach (["http://{$hostname}:{$port}/admin/stats", "http://{$hostname}:{$port}/admin/stats.xml"] as $url) {
        if (function_exists('curl_init')) {
            $ch = curl_init($url);
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
                CURLOPT_USERPWD => $user . ':' . $pass,
                CURLOPT_TIMEOUT => 6,
                CURLOPT_CONNECTTIMEOUT => 4,
                CURLOPT_FAILONERROR => false,
                CURLOPT_HTTPHEADER => ['Accept: application/xml, text/xml, */*'],
            ]);
            $raw = curl_exec($ch);
            $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if (is_string($raw) && trim($raw) !== '' && $code < 400) {
                return $raw;
            }
        }

        $ctx = stream_context_create([
            'http' => [
                'timeout' => 6,
                'ignore_errors' => true,
                'header' => "Authorization: Basic " . base64_encode($user . ':' . $pass) . "\r\n" .
                            "Accept: application/xml, text/xml, */*\r\n",
            ]
        ]);

        $raw = @file_get_contents($url, false, $ctx);
        if (is_string($raw) && trim($raw) !== '') {
            return $raw;
        }
    }

    return '';
}
}

if (!function_exists('smurf_parse_icecast_data')) {
function smurf_parse_icecast_data(string $xml): array {
    $result = [
        'global' => [],
        'sources' => [],
    ];

    if (trim($xml) === '') return $result;

    libxml_use_internal_errors(true);
    $sx = @simplexml_load_string($xml);
    if (!$sx) {
        libxml_clear_errors();
        return $result;
    }

    $result['global'] = [
        'listeners' => isset($sx->listeners) ? (int)$sx->listeners : 0,
        'clients' => isset($sx->clients) ? (int)$sx->clients : 0,
        'sources' => isset($sx->sources) ? (int)$sx->sources : 0,
        'host' => trim((string)($sx->host ?? '')),
        'server_id' => trim((string)($sx->server_id ?? '')),
        'server_start' => trim((string)($sx->server_start_iso8601 ?? $sx->server_start ?? '')),
    ];

    if (isset($sx->source)) {
        foreach ($sx->source as $source) {
            $mount = trim((string)$source['mount']);
            $title = trim((string)$source->title);
            if ($title === '' && isset($source->x_icy_title)) {
                $title = trim((string)$source->x_icy_title);
            }

            $listeners = isset($source->listeners) ? (int)$source->listeners : 0;
            $streamStart = trim((string)($source->stream_start_iso8601 ?? $source->stream_start ?? ''));
            $sourceIp = trim((string)($source->source_ip ?? ''));
            $listenUrl = trim((string)($source->listenurl ?? ''));
            $serverName = trim((string)($source->server_name ?? ''));
            $serverDescription = trim((string)($source->server_description ?? ''));

            $isActive = (
                $listeners > 0 ||
                $title !== '' ||
                $sourceIp !== '' ||
                $streamStart !== ''
            );

            $result['sources'][] = [
                'mount' => $mount,
                'title' => html_entity_decode($title, ENT_QUOTES, 'UTF-8'),
                'listeners' => $listeners,
                'stream_start' => $streamStart,
                'source_ip' => $sourceIp,
                'listenurl' => $listenUrl,
                'server_name' => $serverName,
                'server_description' => $serverDescription,
                'is_active' => $isActive,
            ];
        }
    }

    libxml_clear_errors();
    return $result;
}
}

if (!function_exists('smurf_parse_icecast_sources')) {
function smurf_parse_icecast_sources(string $xml): array {
    $parsed = smurf_parse_icecast_data($xml);
    return $parsed['sources'] ?? [];
}
}

if (!function_exists('smurf_get_global_listener_count')) {
function smurf_get_global_listener_count(): int {
    $xml = smurf_fetch_icecast_xml();
    if ($xml === '') return 0;

    $parsed = smurf_parse_icecast_data($xml);
    return (int)($parsed['global']['listeners'] ?? 0);
}
}

if (!function_exists('smurf_find_source_by_mount_from_xml')) {
function smurf_find_source_by_mount_from_xml(string $xml, string $mount): ?array {
    $mount = trim($mount);
    if ($mount === '') return null;

    foreach (smurf_parse_icecast_sources($xml) as $source) {
        if (($source['mount'] ?? '') === $mount) {
            return $source;
        }
    }

    return null;
}
}

if (!function_exists('smurf_pick_preferred_source')) {
function smurf_pick_preferred_source(array $sources): ?array {
    if (!$sources) return null;

    $cfg = smurf_get_stream_config();
    $preferredMounts = [
        trim((string)($cfg['mount_main'] ?? '/stream')),
        trim((string)($cfg['mount_auto'] ?? '/autodj')),
        trim((string)($cfg['mount_backup'] ?? '/autodj2')),
    ];

    foreach ($preferredMounts as $mount) {
        foreach ($sources as $source) {
            if (
                ($source['mount'] ?? '') === $mount &&
                !empty($source['is_active']) &&
                trim((string)($source['title'] ?? '')) !== '' &&
                (int)($source['listeners'] ?? 0) > 0
            ) {
                return $source;
            }
        }
    }

    foreach ($preferredMounts as $mount) {
        foreach ($sources as $source) {
            if (
                ($source['mount'] ?? '') === $mount &&
                !empty($source['is_active']) &&
                trim((string)($source['title'] ?? '')) !== ''
            ) {
                return $source;
            }
        }
    }

    foreach ($preferredMounts as $mount) {
        foreach ($sources as $source) {
            if (($source['mount'] ?? '') === $mount && !empty($source['is_active'])) {
                return $source;
            }
        }
    }

    foreach ($sources as $source) {
        if (trim((string)($source['title'] ?? '')) !== '') {
            return $source;
        }
    }

    return $sources[0] ?? null;
}
}

if (!function_exists('smurf_get_preferred_source')) {
function smurf_get_preferred_source(): ?array {
    $xml = smurf_fetch_icecast_xml();
    if ($xml === '') return null;
    return smurf_pick_preferred_source(smurf_parse_icecast_sources($xml));
}
}

if (!function_exists('smurf_get_nowplaying_title')) {
function smurf_get_nowplaying_title(): string {
    $source = smurf_get_preferred_source();
    return trim((string)($source['title'] ?? ''));
}
}

if (!function_exists('smurf_chart_log_play')) {
function smurf_chart_log_play(string $logFile, string $stateFile): string {
    $title = smurf_get_nowplaying_title();
    if ($title === '') return '';

    $state = [];
    if (is_file($stateFile)) {
        $state = json_decode((string)file_get_contents($stateFile), true);
        if (!is_array($state)) $state = [];
    }

    $last = trim((string)($state['last_title'] ?? ''));
    $now = time();
    $lastTs = (int)($state['last_seen_ts'] ?? 0);

    if ($last !== $title || $lastTs <= 0 || ($now - $lastTs) > 300) {
        $entry = [
            'title' => $title,
            'played_at' => date('Y-m-d H:i:s', $now),
            'ts' => $now,
        ];
        @file_put_contents($logFile, json_encode($entry, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND | LOCK_EX);
        $state['last_title'] = $title;
        $state['last_seen_ts'] = $now;
        @file_put_contents($stateFile, json_encode($state, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));
    }

    return $title;
}
}

if (!function_exists('smurf_chart_rows_from_log')) {
function smurf_chart_rows_from_log(string $logFile, int $weekStartTs = 0): array {
    if (!is_file($logFile)) return [];
    $counts = [];
    $lines = @file($logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    if (!is_array($lines)) return [];

    foreach ($lines as $line) {
        $row = json_decode((string)$line, true);
        if (!is_array($row)) continue;
        $title = trim((string)($row['title'] ?? ''));
        if ($title === '') continue;
        $ts = (int)($row['ts'] ?? 0);
        if ($weekStartTs > 0 && $ts > 0 && $ts < $weekStartTs) continue;
        if (!isset($counts[$title])) {
            $counts[$title] = [
                'title' => $title,
                'count' => 0,
                'first_seen' => $row['played_at'] ?? date('Y-m-d H:i:s', $ts ?: time()),
                'last_seen' => $row['played_at'] ?? date('Y-m-d H:i:s', $ts ?: time()),
            ];
        }
        $counts[$title]['count']++;
        $counts[$title]['last_seen'] = $row['played_at'] ?? $counts[$title]['last_seen'];
    }

    $rows = array_values($counts);
    usort($rows, function($a, $b) {
        $ca = (int)($a['count'] ?? 0);
        $cb = (int)($b['count'] ?? 0);
        if ($ca === $cb) {
            return strcmp((string)($a['title'] ?? ''), (string)($b['title'] ?? ''));
        }
        return $cb <=> $ca;
    });

    return array_slice($rows, 0, 50);
}
}

if (!function_exists('smurf_top50_rebuild')) {
function smurf_top50_rebuild(string $storeFile, string $stateFile, string $logFile): array {
    $state = [];
    if (is_file($stateFile)) {
        $state = json_decode((string)file_get_contents($stateFile), true);
        if (!is_array($state)) $state = [];
    }
    $weekStart = 0;
    if (!empty($state['last_reset_at'])) {
        $weekStart = strtotime((string)$state['last_reset_at']);
        if ($weekStart === false) $weekStart = 0;
    }
    $rows = smurf_chart_rows_from_log($logFile, (int)$weekStart);

    $store = [];
    foreach ($rows as $row) {
        $title = (string)($row['title'] ?? '');
        if ($title === '') continue;
        $store[$title] = $row;
    }
    @file_put_contents($storeFile, json_encode($store, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));
    return $rows;
}
}

if (!function_exists('smurf_top50_touch')) {
function smurf_top50_touch(string $storeFile, string $stateFile): string {
    $title = smurf_get_nowplaying_title();
    if ($title === '') return '';
    $store = [];
    if (file_exists($storeFile)) {
        $store = json_decode((string)file_get_contents($storeFile), true);
        if (!is_array($store)) $store = [];
    }
    $state = [];
    if (file_exists($stateFile)) {
        $state = json_decode((string)file_get_contents($stateFile), true);
        if (!is_array($state)) $state = [];
    }
    $last = trim((string)($state['last_title'] ?? ''));
    if (!isset($store[$title]) || !is_array($store[$title])) {
        $store[$title] = ['title'=>$title,'count'=>0,'first_seen'=>date('Y-m-d H:i:s'),'last_seen'=>date('Y-m-d H:i:s')];
    }
    if ($last !== $title) {
        $store[$title]['count'] = (int)($store[$title]['count'] ?? 0) + 1;
        $store[$title]['last_seen'] = date('Y-m-d H:i:s');
        $state['last_title'] = $title;
        $state['last_seen_ts'] = time();
        @file_put_contents($storeFile, json_encode($store, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));
        @file_put_contents($stateFile, json_encode($state, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));
    }
    return $title;
}
}

if (!function_exists('smurf_top50_sorted')) {
function smurf_top50_sorted(string $storeFile): array {
    $store = [];
    if (file_exists($storeFile)) {
        $store = json_decode((string)file_get_contents($storeFile), true);
        if (!is_array($store)) $store = [];
    }
    $rows = array_values(array_filter($store, 'is_array'));
    usort($rows, function($a,$b){
        $ca = (int)($a['count'] ?? 0);
        $cb = (int)($b['count'] ?? 0);
        if ($ca === $cb) return strcmp((string)($a['title'] ?? ''), (string)($b['title'] ?? ''));
        return $cb <=> $ca;
    });
    return array_slice($rows, 0, 50);
}
}

if (!function_exists('smurf_load_public_settings')) {
function smurf_load_public_settings(): array {
    $settingsFile = dirname(__DIR__) . '/data/settings.json';
    if (!file_exists($settingsFile)) return [];
    $settings = json_decode((string)file_get_contents($settingsFile), true);
    return is_array($settings) ? $settings : [];
}
}

if (!function_exists('smurf_get_player_urls')) {
function smurf_get_player_urls(): array {
    $cfg = smurf_get_stream_config();
    $rawUrl = trim((string)($cfg['listen_url'] ?? ''));
    return [
        'raw' => $rawUrl,
        'proxy' => '/stream-proxy.php',
        'preferred' => $rawUrl,
        'using_proxy' => false,
    ];
}
}

?>
