<?php

declare(strict_types=1);



class FrontAlbumTaxonomyController
{
    public static function routes(): void
    {
        Router::get('/album-category/{slug}', [self::class, 'showCategory']);
        Router::get('/album-tag/{slug}', [self::class, 'showTag']);
        Router::get('/album-pornstar/{slug}', [self::class, 'showPerformer']);
        Router::get('/album-channel/{slug}', [self::class, 'showChannel']);
    }

     
    private static function ensureEnabled(): bool
    {
        if (Album::featureEnabled()) {
            return true;
        }
        http_response_code(410);
        ThemeRenderer::render('404');
        return false;
    }

    public static function showCategory(): void
    {
        if (!self::ensureEnabled()) { return; }
        $category = AlbumCategory::findBySlug(Router::param('slug'));
        if (!$category) { http_response_code(404); ThemeRenderer::render('404'); return; }
        Router::enforceCanonicalType($category['video_type'], 'album-category', $category['slug']);

        $perPage = (int) Setting::get('albums_per_page', '24');
        $sort = (isset($_GET['sort']) && is_string($_GET['sort'])) ? $_GET['sort'] : Setting::get('albums_default_sort', 'newest');
        $filters = ['category_id' => (int) $category['id'], 'status' => 'published', 'sort' => $sort];
        $pagination = Pagination::fromRequest(Album::count($filters), $perPage);
        $albums = Album::all($filters, $perPage, $pagination->offset);

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

        self::emit('album-category', AlbumCategory::class, 'category', 'album-category', $category, $albums, $pagination, $sort, $description);
    }

    public static function showTag(): void
    {
        if (!self::ensureEnabled()) { return; }
        $tag = AlbumTag::findBySlug(Router::param('slug'));
        if (!$tag) { http_response_code(404); ThemeRenderer::render('404'); return; }
        Router::enforceCanonicalType($tag['video_type'], 'album-tag', $tag['slug']);

        $perPage = (int) Setting::get('albums_per_page', '24');
        $sort = (isset($_GET['sort']) && is_string($_GET['sort'])) ? $_GET['sort'] : Setting::get('albums_default_sort', 'newest');
        $filters = ['tag_id' => (int) $tag['id'], 'status' => 'published', 'sort' => $sort];
        $pagination = Pagination::fromRequest(Album::count($filters), $perPage);
        $albums = Album::all($filters, $perPage, $pagination->offset);

        self::emit('album-tag', AlbumTag::class, 'tag', 'album-tag', $tag, $albums, $pagination, $sort, $tag['name']);
    }

    public static function showPerformer(): void
    {
        if (!self::ensureEnabled()) { return; }
        $performer = AlbumPerformer::findBySlug(Router::param('slug'));
        if (!$performer) { http_response_code(404); ThemeRenderer::render('404'); return; }
        Router::enforceCanonicalType($performer['video_type'], 'album-pornstar', $performer['slug']);

        $perPage = (int) Setting::get('albums_per_page', '24');
        $sort = (isset($_GET['sort']) && is_string($_GET['sort'])) ? $_GET['sort'] : Setting::get('albums_default_sort', 'newest');
        $filters = ['performer_id' => (int) $performer['id'], 'status' => 'published', 'sort' => $sort];
        $pagination = Pagination::fromRequest(Album::count($filters), $perPage);
        $albums = Album::all($filters, $perPage, $pagination->offset);

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

        $ogImage = '';
        if (!empty($performer['photo'])) {
            $ogImage = str_starts_with($performer['photo'], 'http')
                ? $performer['photo']
                : SEO::siteUrl() . '/uploads/performers/' . $performer['photo'];
        }

        self::emit('album-pornstar', AlbumPerformer::class, 'performer', 'album-pornstar', $performer, $albums, $pagination, $sort, $description, $ogImage);
    }

    public static function showChannel(): void
    {
        if (!self::ensureEnabled()) { return; }
        $channel = AlbumChannel::findBySlug(Router::param('slug'));
        if (!$channel) { http_response_code(404); ThemeRenderer::render('404'); return; }
        Router::enforceCanonicalType($channel['video_type'], 'album-channel', $channel['slug']);

        $perPage = (int) Setting::get('albums_per_page', '24');
        $sort = (isset($_GET['sort']) && is_string($_GET['sort'])) ? $_GET['sort'] : Setting::get('albums_default_sort', 'newest');
        $filters = ['channel_id' => (int) $channel['id'], 'status' => 'published', 'sort' => $sort];
        $pagination = Pagination::fromRequest(Album::count($filters), $perPage);
        $albums = Album::all($filters, $perPage, $pagination->offset);

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

        $ogImage = '';
        if (!empty($channel['logo'])) {
            $ogImage = str_starts_with($channel['logo'], 'http')
                ? $channel['logo']
                : SEO::siteUrl() . '/uploads/channels/' . $channel['logo'];
        }

        self::emit('album-channel', AlbumChannel::class, 'channel', 'album-channel', $channel, $albums, $pagination, $sort, $description, $ogImage);
    }

    

    private static function emit(
        string $route,
        string $model,
        string $entityKey,
        string $template,
        array $entity,
        array $albums,
        Pagination $pagination,
        string $sort,
        string $description,
        string $ogImage = ''
    ): void {
        $prefix = ltrim(Router::langPrefix() . Router::typePrefix(), '/');
        $canonicalPath = $prefix !== '' ? $prefix . '/' . $route . '/' . $entity['slug'] : $route . '/' . $entity['slug'];
        $canonicalUrl = SEO::canonical($canonicalPath);
        $alternates = self::buildAlternates($route, $model, (int) $entity['id']);
        Router::setAlternates($alternates);

        $siteUrl = SEO::siteUrl();
        $albumListPath = $prefix !== '' ? $prefix . '/albums' : 'albums';
        $breadcrumbJsonLd = SEO::breadcrumbJsonLd([
            ['name' => Setting::get('site_name', 'TubePress'), 'url' => $siteUrl . '/'],
            ['name' => __('page_title_albums'), 'url' => $siteUrl . '/' . $albumListPath],
            ['name' => $entity['name'], 'url' => html_entity_decode($canonicalUrl)],
        ]);

        $ogTags = [
            'og:title' => $entity['name'],
            'og:description' => $description,
            'og:url' => $canonicalUrl,
        ];
        $twitterCard = [
            'twitter:title' => $entity['name'],
            'twitter:description' => $description,
        ];
        if ($ogImage !== '') {
            $ogTags['og:image'] = $ogImage;
            $twitterCard['twitter:image'] = $ogImage;
        }

         
         
         
        if (empty($entity['photo'])) {
            $fallback = HookSystem::applyFilter('album.entity.thumbnail', null, $entityKey, (int) $entity['id'], (string) ($entity['video_type'] ?? ''));
            if ($fallback === null) {
                $mapTable = ['category' => 'album_category_map', 'performer' => 'album_performer_map', 'channel' => 'album_channel_map', 'tag' => 'album_tag_map'][$entityKey] ?? '';
                $fk = ['category' => 'category_id', 'performer' => 'performer_id', 'channel' => 'channel_id', 'tag' => 'tag_id'][$entityKey] ?? '';
                if ($mapTable !== '') {
                    $row = Database::fetchOne(
                        "SELECT a.cover_file, a.album_folder, a.storage_id, a.images FROM albums a
                         JOIN {$mapTable} m ON m.album_id = a.id
                         WHERE m.{$fk} = ? AND a.status = 'published'
                         ORDER BY a.views DESC LIMIT 1",
                        [(int) $entity['id']]
                    );
                    if ($row) { $c = AlbumAsset::coverUrl($row); if ($c !== '') $fallback = $c; }
                }
            }
            if ($fallback) { $entity['_fallback_photo'] = $fallback; }
        }

        ThemeRenderer::render($template, [
            'pageTitle' => SEO::title($entity['name']),
            'metaDescription' => $description,
            'canonicalUrl' => $canonicalUrl,
            'alternates' => $alternates,
            'ogTags' => $ogTags,
            'twitterCard' => $twitterCard,
            'jsonLd' => $breadcrumbJsonLd,
            $entityKey => $entity,
            'albums' => $albums,
            'pagination' => $pagination,
            'sort' => $sort,
        ]);
    }

    

    private static function buildAlternates(string $route, string $model, int $id): array
    {
        $base = $model::find($id);
        if (!$base) return [];

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

        $alternates[$defaultLang] = $siteUrl . $typePrefix . '/' . $route . '/' . $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 . '/' . $route . '/' . $slug;
        }
        $alternates['x-default'] = $alternates[$defaultLang];
        return $alternates;
    }
}
