<?php

declare(strict_types=1);

class FrontCategoryController
{
    public static function routes(): void
    {
        Router::get('/categories', [self::class, 'index']);
        Router::get('/category/{slug}', [self::class, 'show']);
    }

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

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

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

    public static function show(): void
    {
        $category = Category::findBySlug(Router::param('slug'));
        if (!$category) {
            http_response_code(404);
            ThemeRenderer::render('404');
            return;
        }

        Router::enforceCanonicalType($category['video_type'], 'category', $category['slug']);
        Router::enforceCanonicalSlug('category', $category['slug']);

        $sort = $_GET['sort'] ?? HookSystem::applyFilter('front.default_sort', Setting::get('default_sort', 'newest'), 'category');
        $perPage = (int) Setting::get('videos_per_page', 24);
        $filters = ['category_id' => $category['id'], 'status' => 'published', 'sort' => $sort];
        $total = Video::count($filters);
        $pagination = Pagination::fromRequest($total, $perPage);
        $videos = Video::all($filters, $perPage, $pagination->offset);

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

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

         
        $siteUrl = SEO::siteUrl();
        $catListPath = $prefix !== '' ? $prefix . '/categories' : 'categories';
        $breadcrumbJsonLd = SEO::breadcrumbJsonLd([
            ['name' => Setting::get('site_name', 'TubePress'), 'url' => $siteUrl . '/'],
            ['name' => __('page_title_categories'), 'url' => $siteUrl . '/' . $catListPath],
            ['name' => $category['name'], 'url' => html_entity_decode($canonicalUrl)],
        ]);

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

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

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

        $alternates[$defaultLang] = $siteUrl . $typePrefix . '/category/' . $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 . '/category/' . $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;
    }
}
