<?php

declare(strict_types=1);

class FrontChannelController
{
    public static function routes(): void
    {
        Router::get('/channels', [self::class, 'index']);
        Router::get('/channel/{slug}', [self::class, 'show']);
    }

    public static function index(): void
    {
        $sort = $_GET['sort'] ?? Setting::get('channels_default_sort', 'alphabetical');
        $perPage = (int) Setting::get('channels_per_page', '30');
        $videoType = Video::activeType();
        $total = Channel::count('', $videoType, true);
        $pagination = Pagination::fromRequest($total, $perPage);

        $prefix = ltrim(Router::langPrefix() . Router::typePrefix(), '/');
        $canonicalPath = $prefix !== '' ? $prefix . '/channels' : 'channels';
        $canonicalUrl = SEO::canonical($canonicalPath);
        $alternates = self::buildListAlternates('channels');
        Router::setAlternates($alternates);

        ThemeRenderer::render('channels', [
            'pageTitle' => SEO::title(__('page_title_channels')),
            'metaDescription' => __('page_title_channels'),
            'canonicalUrl' => $canonicalUrl,
            'alternates' => $alternates,
            'channels' => Channel::all('', $perPage, $pagination->offset, $sort, $videoType, true),
            'pagination' => $pagination,
            'sort' => $sort,
        ]);
    }

    public static function show(): void
    {
        $channel = Channel::findBySlug(Router::param('slug'));
        if (!$channel) { http_response_code(404); ThemeRenderer::render('404'); return; }
        Router::enforceCanonicalType($channel['video_type'], 'channel', $channel['slug']);
        $sort = $_GET['sort'] ?? HookSystem::applyFilter('front.default_sort', Setting::get('default_sort', 'newest'), 'channel');
        $perPage = (int) Setting::get('videos_per_page', 24);
        $filters = ['channel_id' => $channel['id'], 'status' => 'published', 'sort' => $sort];
        $total = Video::count($filters);
        $pagination = Pagination::fromRequest($total, $perPage);
        $videos = Video::all($filters, $perPage, $pagination->offset);

         
        if (empty($channel['logo'])) {
            $row = Database::fetchOne(
                "SELECT v.video_folder, v.storage_id FROM videos v
                 JOIN video_channels vs ON v.id = vs.video_id
                 WHERE vs.channel_id = ? AND v.status = 'published'
                   AND v.video_folder IS NOT NULL
                 ORDER BY v.views DESC LIMIT 1",
                [$channel['id']]
            );
            $folder = $row['video_folder'] ?? '';
            $sid = isset($row['storage_id']) ? (int) $row['storage_id'] : null;
            if ($folder !== '') {
                $fallbackUrl = VideoAsset::thumbUrlFromFolder($folder, false, $sid);
                if ($fallbackUrl !== '') {
                    $channel['_fallback_logo'] = $fallbackUrl;
                }
            }
        }

         
        $prefix = ltrim(Router::langPrefix() . Router::typePrefix(), '/');
        $canonicalPath = $prefix !== '' ? $prefix . '/channel/' . $channel['slug'] : 'channel/' . $channel['slug'];
        $canonicalUrl = SEO::canonical($canonicalPath);
        $alternates = self::buildAlternates((int) $channel['id']);
        Router::setAlternates($alternates);

        $description = !empty($channel['description']) ? mb_substr(strip_tags($channel['description']), 0, 160) : $channel['name'];
        $siteUrl = SEO::siteUrl();

         
        $channelListPath = $prefix !== '' ? $prefix . '/channels' : 'channels';
        $breadcrumbJsonLd = SEO::breadcrumbJsonLd([
            ['name' => Setting::get('site_name', 'TubePress'), 'url' => $siteUrl . '/'],
            ['name' => __('page_title_channels'), 'url' => $siteUrl . '/' . $channelListPath],
            ['name' => $channel['name'], 'url' => html_entity_decode($canonicalUrl)],
        ]);
        $ogImage = '';
        if (!empty($channel['logo'])) {
            $ogImage = str_starts_with($channel['logo'], 'http') ? $channel['logo'] : $siteUrl . '/uploads/channels/' . $channel['logo'];
        } elseif (!empty($channel['_fallback_logo'])) {
            $fl = $channel['_fallback_logo'];
            $ogImage = (str_starts_with($fl, 'http://') || str_starts_with($fl, 'https://')) ? $fl : $siteUrl . $fl;
        }

        ThemeRenderer::render('channel', [
            'pageTitle' => SEO::title($channel['name']),
            'metaDescription' => $description,
            'canonicalUrl' => $canonicalUrl,
            'alternates' => $alternates,
            'ogTags' => [
                'og:title' => $channel['name'],
                'og:description' => $description,
                'og:url' => $canonicalUrl,
                'og:image' => $ogImage,
            ],
            'twitterCard' => [
                'twitter:title' => $channel['name'],
                'twitter:description' => $description,
                'twitter:image' => $ogImage,
            ],
            'jsonLd' => $breadcrumbJsonLd,
            'channel' => $channel,
            'videos' => $videos,
            'pagination' => $pagination,
            'sort' => $sort,
        ]);
    }

    private static function buildAlternates(int $channelId): array
    {
        $base = Database::fetchOne('SELECT slug, video_type FROM channels WHERE id = ?', [$channelId]);
        if (!$base) return [];

        $siteUrl = SEO::siteUrl();
        $defaultLang = Translator::getDefaultCode();
        $typePrefix = Router::typePrefixFor($base['video_type']);
        $translations = Channel::translations($channelId);
        $alternates = [];

        $alternates[$defaultLang] = $siteUrl . $typePrefix . '/channel/' . $base['slug'];
        foreach (Translator::available() as $lang) {
            if ($lang['code'] === $defaultLang) continue;
            $slug = $translations[$lang['code']]['slug'] ?? $base['slug'];
            $alternates[$lang['code']] = $siteUrl . '/' . $lang['code'] . $typePrefix . '/channel/' . $slug;
        }
        $alternates['x-default'] = $alternates[$defaultLang];
        return $alternates;
    }

    private static function buildListAlternates(string $route): array
    {
        $siteUrl = SEO::siteUrl();
        $defaultLang = Translator::getDefaultCode();
        $typePrefix = Router::typePrefix();
        $alternates = [];

        $alternates[$defaultLang] = $siteUrl . $typePrefix . '/' . $route;
        foreach (Translator::available() as $lang) {
            if ($lang['code'] === $defaultLang) continue;
            $alternates[$lang['code']] = $siteUrl . '/' . $lang['code'] . $typePrefix . '/' . $route;
        }
        $alternates['x-default'] = $alternates[$defaultLang];
        return $alternates;
    }
}
