<?php

declare(strict_types=1);

HookSystem::addAction('routes.registered', function (): void {
    Router::get('/admin/seo', ['HentaiSeoAdmin', 'index']);
    Router::post('/admin/seo', ['HentaiSeoAdmin', 'save']);
    Router::post('/admin/seo/regenerate', ['HentaiSeoAdmin', 'regenerate']);
    Router::post('/admin/seo/upload-og', ['HentaiSeoAdmin', 'uploadOgImage']);
    Router::post('/admin/seo/type-labels', ['HentaiSeoAdmin', 'saveTypeLabels']);
});

HookSystem::addAction('admin.sidebar_menu', function (string $activeMenu): void {
    ?>
    <a href="/admin/seo" class="flex items-center gap-2.5 px-5 py-2.5 text-sm no-underline transition-all duration-150 <?= $activeMenu === 'seo' ? 'text-white bg-primary-600' : 'text-gray-400 hover:text-white hover:bg-gray-800' ?>">
        <svg viewBox="0 0 24 24" class="w-[18px] h-[18px] shrink-0" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"/></svg>
        SEO
    </a>
    <?php
}, 20);

class HentaiSeoAdmin
{
    public static function index(): void
    {
        Auth::requireAdmin();

        $validTabs = ['pages', 'social', 'sitemap', 'indexing', 'robots', 'advanced', 'analytics', 'help'];
        $tab = $_GET['tab'] ?? 'pages';
        if (!in_array($tab, $validTabs, true)) {
            $tab = 'pages';
        }

        $validSubs = ['home', 'video', 'category', 'tag', 'performer', 'channel', 'album', 'album_listing', 'search', 'page'];
        $sub = $_GET['sub'] ?? 'home';
        if (!in_array($sub, $validSubs, true)) {
            $sub = 'home';
        }

        $s = [];
        foreach (SeoManager::DEFAULTS as $key => $default) {
            $s[$key] = Setting::get($key, $default);
        }

        $sitemapDir = APP_ROOT . '/storage/sitemaps';
        $sitemapFiles = is_dir($sitemapDir) ? glob($sitemapDir . '/*.xml.gz') : [];
        $sitemapCount = count($sitemapFiles ?: []);
        $sitemapLastGen = '';
        if ($sitemapCount > 0) {
            $times = array_map('filemtime', $sitemapFiles);
            $sitemapLastGen = date('Y-m-d H:i:s', max($times));
        }

        $siteUrl = SEO::siteUrl();
        $defaultRobots = method_exists('SitemapController', 'defaultRobotsTxt')
            ? SitemapController::defaultRobotsTxt()
            : "User-agent: *\n"
                . "Disallow: /admin/\n"
                . "Disallow: /install/\n"
                . "Disallow: /search\n"
                . "Disallow: /login\n"
                . "Disallow: /register\n"
                . "Disallow: /forgot-password\n"
                . "Disallow: /api/\n"
                . "Disallow: /storage/\n"
                . "Disallow: /*?sort=\n"
                . "Disallow: /*?page=\n"
                . "\n"
                . "Allow: /themes/\n"
                . "Allow: /templates/admin/assets/\n"
                . "\n"
                . "User-agent: AhrefsBot\n"
                . "Crawl-delay: 10\n"
                . "\n"
                . "User-agent: SemrushBot\n"
                . "Crawl-delay: 10\n"
                . "\n"
                . "User-agent: MJ12bot\n"
                . "Crawl-delay: 10\n"
                . "\n"
                . "Sitemap: {$siteUrl}/sitemap.xml\n";

        $ogImageUrl = '';
        if ($s['seo_og_image'] !== '') {
            $ogImageUrl = '/uploads/seo/' . $s['seo_og_image'];
        }

        $favicon = Setting::get('site_favicon', '');
        $faviconUrl = $favicon !== '' ? '/uploads/branding/' . $favicon : '';

        Router::render('admin/layout', [
            'pageTitle'       => 'SEO',
            'activeMenu'      => 'seo',
            'contentPath'     => ThemeManager::themePath() . '/admin/seo.php',
            'tab'             => $tab,
            'sub'             => $sub,
            's'               => $s,
            'saved'           => isset($_GET['saved']),
            'sitemapCount'    => $sitemapCount,
            'sitemapLastGen'  => $sitemapLastGen,
            'defaultRobots'   => $defaultRobots,
            'ogImageUrl'      => $ogImageUrl,
            'ctrActive'       => PluginManager::isActive('ctr'),
            'siteUrl'         => $siteUrl,
            'faviconUrl'      => $faviconUrl,
            'multiType'       => count(Video::availableTypes()) >= 2,
            'typeLabels'      => Video::typeLabels(),
        ]);
    }

    public static function save(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) {
            Router::redirect('/admin/seo');
            return;
        }

        $tab = $_POST['_tab'] ?? 'pages';
        $sub = $_POST['_sub'] ?? '';

        $textFields = [
            'pages' => [
                'home'      => ['seo_home_title', 'seo_home_meta_description', 'seo_pagination_suffix'],
                'video'     => ['seo_pattern_video', 'seo_desc_video'],
                'category'  => ['seo_pattern_category', 'seo_desc_category'],
                'tag'       => ['seo_pattern_tag', 'seo_desc_tag'],
                'performer' => ['seo_pattern_performer', 'seo_desc_performer'],
                'channel'    => ['seo_pattern_channel', 'seo_desc_channel'],
                'album'       => ['seo_pattern_album', 'seo_desc_album'],
                'album_listing' => ['seo_pattern_album_listing', 'seo_desc_album_listing'],
                'search'    => ['seo_pattern_search', 'seo_desc_search'],
                'page'      => ['seo_pattern_page', 'seo_desc_page'],
            ],
            'social'    => ['seo_title_separator', 'seo_twitter_card', 'seo_twitter_handle', 'seo_fb_app_id'],
            'sitemap'   => ['seo_sitemap_max_urls'],
            'indexing'  => [],
            'robots'    => ['seo_robots_txt'],
            'advanced'  => ['seo_google_verify', 'seo_bing_verify', 'seo_pinterest_verify', 'seo_yandex_verify', 'seo_custom_head', 'seo_custom_body'],
            'analytics' => ['seo_ga4_id', 'seo_custom_head', 'seo_custom_body'],
        ];

        $checkboxFields = [
            'pages' => [
                'home' => ['seo_pagination_title'],
            ],
            'social'   => ['seo_og_auto_ctr'],
            'sitemap'  => [
                'seo_sitemap_videos', 'seo_sitemap_categories', 'seo_sitemap_tags',
                'seo_sitemap_performers', 'seo_sitemap_channels', 'seo_sitemap_albums', 'seo_sitemap_pages',
                'seo_sitemap_video_tags', 'seo_sitemap_image_tags', 'seo_sitemap_hreflang',
            ],
            'indexing' => [
                'seo_noindex_tags', 'seo_noindex_categories', 'seo_noindex_performers',
                'seo_noindex_channels', 'seo_noindex_albums', 'seo_noindex_search', 'seo_noindex_paginated',
                'seo_noindex_entire_site',
            ],
        ];

        if ($tab === 'pages') {
            $fields = $textFields['pages'][$sub] ?? [];
            $checks = $checkboxFields['pages'][$sub] ?? [];
        } else {
            $fields = $textFields[$tab] ?? [];
            $checks = $checkboxFields[$tab] ?? [];
        }

        foreach ($fields as $key) {
            Setting::set($key, trim($_POST[$key] ?? ''));
        }

        foreach ($checks as $key) {
            Setting::set($key, isset($_POST[$key]) ? '1' : '0');
        }

        if ($tab === 'indexing' && method_exists('SeoManager', 'saveTaxonomyIndexing')) {
            SeoManager::saveTaxonomyIndexing(
                (int) ($_POST['seo_taxonomy_min_items'] ?? 0),
                isset($_POST['seo_taxonomy_keep_described'])
            );
        }

        if ($tab === 'sitemap') {
            $max = max(1000, min(50000, (int) Setting::get('seo_sitemap_max_urls', '25000')));
            Setting::set('seo_sitemap_max_urls', (string) $max);
        }

        $redirect = '/admin/seo?tab=' . urlencode($tab);
        if ($tab === 'pages' && $sub !== '') {
            $redirect .= '&sub=' . urlencode($sub);
        }
        Router::redirect($redirect . '&saved=1');
    }

    public static function regenerate(): void
    {
        Auth::requireAdmin();
        header('Content-Type: application/json');

        if (!Router::verifyCsrf()) {
            http_response_code(403);
            echo json_encode(['ok' => false, 'error' => 'Invalid CSRF token.']);
            exit;
        }

        SitemapController::markDirty();
        SitemapController::generateAll();

        $dir = APP_ROOT . '/storage/sitemaps';
        $files = is_dir($dir) ? glob($dir . '/*.xml.gz') : [];

        echo json_encode(['ok' => true, 'files' => count($files ?: []), 'time' => date('Y-m-d H:i:s')]);
        exit;
    }

    public static function uploadOgImage(): void
    {
        Auth::requireAdmin();
        header('Content-Type: application/json');

        if (!Router::verifyCsrf()) {
            http_response_code(403);
            echo json_encode(['ok' => false, 'error' => 'Invalid CSRF token.']);
            exit;
        }

        if (empty($_FILES['og_image'])) {
            echo json_encode(['ok' => false, 'error' => 'No file uploaded.']);
            exit;
        }

        $result = FileUpload::image($_FILES['og_image'], 'seo');
        if (!$result['success']) {
            echo json_encode(['ok' => false, 'error' => $result['error']]);
            exit;
        }

        $old = Setting::get('seo_og_image', '');
        if ($old !== '') {
            FileUpload::delete('seo/' . $old);
        }

        Setting::set('seo_og_image', $result['path']);

        echo json_encode(['ok' => true, 'url' => '/uploads/seo/' . $result['path'], 'filename' => $result['path']]);
        exit;
    }

    public static function saveTypeLabels(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { http_response_code(403); header('Content-Type: application/json'); echo json_encode(['ok' => false, 'error' => 'Invalid CSRF token.']); return; }
        header('Content-Type: application/json');

        foreach (Video::VALID_TYPES as $type) {
            $val = trim($_POST[$type] ?? '');
            if ($val !== '') {
                Setting::set('seo_type_label_' . $type, $val);
            }
        }

        $response = ['ok' => true];
        foreach (Video::VALID_TYPES as $type) {
            $response[$type] = Video::typeLabel($type);
        }
        echo json_encode($response);
        exit;
    }
}
