<?php
function ugfx_read_json(string $path, $default = []) {
    if (!file_exists($path)) return $default;
    $data = json_decode((string) file_get_contents($path), true);
    return is_array($data) ? $data : $default;
}

function ugfx_write_json(string $path, $data): bool {
    $dir = dirname($path);
    if (!is_dir($dir)) mkdir($dir, 0775, true);
    return (bool) file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}

function ugfx_asset(string $path): string {
    return 'assets/' . ltrim($path, '/');
}

function ugfx_vendor_asset(string $localPath, string $cdnUrl, string $prefix = ''): string {
    $normalized = ltrim($localPath, '/');
    $absolute = dirname(__DIR__) . '/' . $normalized;
    if (file_exists($absolute)) {
        return $prefix . $normalized;
    }
    return $cdnUrl;
}

function ugfx_is_active(string $page, string $current): string {
    return $page === $current ? 'active' : '';
}

function ugfx_slugify(string $text): string {
    $text = strtolower(trim($text));
    $text = preg_replace('/[^a-z0-9]+/', '-', $text);
    return trim($text ?? '', '-') ?: 'page';
}

function ugfx_strlen(string $text): int {
    return function_exists('mb_strlen') ? mb_strlen($text) : strlen($text);
}

function ugfx_substr(string $text, int $start, ?int $length = null): string {
    if (function_exists('mb_substr')) {
        return $length === null ? mb_substr($text, $start) : mb_substr($text, $start, $length);
    }
    return $length === null ? substr($text, $start) : substr($text, $start, $length);
}

function ugfx_excerpt(string $text, int $length = 180): string {
    $text = trim(strip_tags($text));
    return ugfx_strlen($text) > $length ? ugfx_substr($text, 0, $length - 1) . '…' : $text;
}

function ugfx_sort_items_by_date_desc(array $items): array {
    usort($items, function ($a, $b) {
        return strtotime((string)($b['start'] ?? $b['date'] ?? '')) <=> strtotime((string)($a['start'] ?? $a['date'] ?? ''));
    });
    return $items;
}

function ugfx_get_news(int $limit = 6): array {
    global $ugfx;
    $items = ugfx_read_json($ugfx['storage']['news'], []);
    $items = array_values(array_filter($items, function ($item) { return ($item['published'] ?? 0) == 1; }));
    return array_slice($items, 0, $limit);
}

function ugfx_get_events(int $limit = 4): array {
    global $ugfx;
    $items = ugfx_read_json($ugfx['storage']['events'], []);
    $items = array_values(array_filter($items, function ($item) { return ($item['published'] ?? 0) == 1; }));
    $items = ugfx_sort_items_by_date_desc($items);
    return array_slice($items, 0, $limit);
}

function ugfx_get_djs(int $limit = 8): array {
    global $ugfx;
    return array_slice(ugfx_read_json($ugfx['storage']['djs'], []), 0, $limit);
}

function ugfx_get_top50(int $limit = 10): array {
    global $ugfx;
    $items = ugfx_read_json($ugfx['storage']['top50'], []);
    uasort($items, function ($a, $b) { return ($b['count'] ?? 0) <=> ($a['count'] ?? 0); });
    return array_slice($items, 0, $limit, true);
}

function ugfx_get_schedule(): array {
    global $ugfx;
    return ugfx_read_json($ugfx['storage']['schedule'], []);
}

function ugfx_get_friends(int $limit = 12): array {
    global $ugfx;
    return array_slice(ugfx_read_json($ugfx['storage']['friends'], []), 0, $limit);
}

function ugfx_get_pages(bool $publishedOnly = true): array {
    global $ugfx;
    $items = ugfx_read_json($ugfx['storage']['pages'], []);
    if ($publishedOnly) {
        $items = array_values(array_filter($items, function ($item) { return ($item['published'] ?? 0) == 1; }));
    }
    return $items;
}

function ugfx_get_page_by_slug(string $slug): ?array {
    foreach (ugfx_get_pages(false) as $page) {
        if (($page['slug'] ?? '') === $slug) {
            return $page;
        }
    }
    return null;
}

function ugfx_day_name(?int $timestamp = null): string {
    return date('l', $timestamp ?? time());
}

function ugfx_current_show(): array {
    $schedule = ugfx_get_schedule();
    $day = ugfx_day_name();
    $hour = (int) date('G');
    $current = $schedule[$day][$hour] ?? 'Underground FX Live';
    $next = $schedule[$day][($hour + 1) % 24] ?? 'Underground FX Live';
    return ['day' => $day, 'hour' => $hour, 'current' => $current, 'next' => $next];
}

function ugfx_get_stream_config(): array {
    $settings = ugfx_read_json(__DIR__ . '/../data/settings.json', []);
    return [
        'server_ip' => (string)($settings['stats_host'] ?? 'cr2.broadcasturself.com'),
        'server_port' => (string)($settings['stats_port'] ?? '9000'),
        'admin_user' => (string)($settings['stats_user'] ?? 'UndergroundFx'),
        'admin_password' => (string)($settings['stats_password'] ?? 'TxHL7RqdSjQbSB'),
        'mount_main' => (string)($settings['stats_mount_main'] ?? '/stream'),
        'mount_auto' => (string)($settings['stats_mount_auto'] ?? '/autodj'),
        'mount_backup' => (string)($settings['stats_mount_backup'] ?? '/stream2'),
        'public_stream_url' => (string)($settings['public_stream_url'] ?? 'http://radio.undergroundfxradio.com:9000/stream'),
        'stats_url' => (string)($settings['stats_url'] ?? 'http://cr2.broadcasturself.com:9000/admin/stats'),
    ];
}

function ugfx_fetch_icecast_xml(): string {
    $cfg = ugfx_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 '';
    }

    $urls = [];
    if (!empty($cfg['stats_url'])) {
        $urls[] = $cfg['stats_url'];
    }
    $urls[] = "http://{$hostname}:{$port}/admin/stats";
    $urls[] = "http://{$hostname}:{$port}/admin/stats.xml";
    $urls = array_values(array_unique($urls));

    foreach ($urls 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 '';
}

function ugfx_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,
        'listener_connections' => isset($sx->listener_connections) ? (int)$sx->listener_connections : 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);
            }
            if ($title === '' && isset($source->metadata->x_icy_title)) {
                $title = trim((string)$source->metadata->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;
}

function ugfx_pick_preferred_source(array $sources): ?array {
    if (!$sources) return null;

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

    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;
}

function ugfx_get_player_urls(): array {
    $cfg = ugfx_get_stream_config();
    $rawUrl = trim((string)($cfg['public_stream_url'] ?? ''));
    return [
        'raw' => $rawUrl,
        'proxy' => '/stream-proxy.php',
        'preferred' => '/stream-proxy.php',
        'using_proxy' => true,
    ];
}

function ugfx_icecast_status(): array {
    static $cached = null;
    if ($cached !== null) return $cached;

    $cfg = ugfx_get_stream_config();
    $playerUrls = ugfx_get_player_urls();
    $fallback = [
        'server_listeners' => 0,
        'current_listeners' => 0,
        'title' => 'Underground FX Live',
        'artist' => 'AutoDJ',
        'mount' => $cfg['mount_auto'] ?? '/autodj',
        'stream_url' => $playerUrls['preferred'],
        'public_stream_url' => $playerUrls['raw'],
        'status' => 'LIVE',
    ];

    $cacheFile = __DIR__ . '/../data/icecast_stats_cache.json';
    $cacheTtl = 15;
    if (is_file($cacheFile) && (time() - (int)filemtime($cacheFile) <= $cacheTtl)) {
        $cachedData = json_decode((string)@file_get_contents($cacheFile), true);
        if (is_array($cachedData) && !empty($cachedData['mount'])) {
            return $cached = $cachedData;
        }
    }

    $xml = ugfx_fetch_icecast_xml();
    if ($xml === '') {
        if (is_file($cacheFile)) {
            $stale = json_decode((string)@file_get_contents($cacheFile), true);
            if (is_array($stale)) return $cached = $stale;
        }
        return $cached = $fallback;
    }

    $parsed = ugfx_parse_icecast_data($xml);
    $source = ugfx_pick_preferred_source($parsed['sources'] ?? []);
    if (!$source) {
        return $cached = $fallback;
    }

    $rawTitle = trim((string)($source['title'] ?? ''));
    $artist = trim((string)($source['server_name'] ?? 'Underground FX Radio Auto'));
    $title = $rawTitle !== '' ? $rawTitle : 'Underground FX Live';
    if (strpos($title, ' - ') !== false) {
        list($artistFromTitle, $titleOnly) = array_map('trim', explode(' - ', $title, 2));
        if ($artistFromTitle !== '') $artist = $artistFromTitle;
        if ($titleOnly !== '') $title = $titleOnly;
    }

    $data = [
        'server_listeners' => (int)($parsed['global']['listener_connections'] ?? ($parsed['global']['listeners'] ?? 0)),
        'current_listeners' => (int)($source['listeners'] ?? 0),
        'title' => $title,
        'artist' => $artist,
        'mount' => (string)($source['mount'] ?? ($cfg['mount_auto'] ?? '/autodj')),
        'stream_url' => $playerUrls['preferred'],
        'public_stream_url' => $playerUrls['raw'],
        'status' => 'LIVE',
    ];

    @file_put_contents($cacheFile, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), LOCK_EX);
    return $cached = $data;
}

function ugfx_now_playing(): array {
    $show = ugfx_current_show();
    $icecast = ugfx_icecast_status();
    return [
        'title' => $icecast['title'] ?: 'Underground FX Live',
        'artist' => $icecast['artist'] ?: $show['current'],
        'album' => 'Underground FX Radio',
        'art' => ugfx_asset('img/brand/ugfx-hero.png'),
        'listeners' => $icecast['server_listeners'],
        'current_listeners' => $icecast['current_listeners'],
        'status' => $icecast['status'],
        'mount' => $icecast['mount'],
        'stream_url' => $icecast['stream_url'],
        'public_stream_url' => $icecast['public_stream_url']
    ];
}

function ugfx_primary_nav(): array {
    return [
        ['label' => 'Listen Live', 'href' => 'listen-live.php'],
        ['label' => 'Schedule', 'href' => 'schedule.php'],
        ['label' => 'Requests', 'href' => 'requests.php'],
        ['label' => 'News', 'href' => 'news.php'],
        ['label' => 'Events', 'href' => 'events.php'],
        ['label' => 'Team', 'href' => 'team.php'],
        ['label' => 'Join', 'href' => 'join.php'],
        ['label' => 'Chat', 'href' => 'chat.php']
    ];
}
