<?php

namespace WPSN\Modules\IndexationRisk\Admin;

use WPSN\Core\Capabilities;
use WPSN\Core\Container;
use WPSN\Core\Logger;
use WPSN\Core\Settings;
use WPSN\Admin\TasksWorkbenchContext;
use WPSN\Core\Queue\QueueInterface;
use WPSN\Core\Queue\QueueRunner;
use WPSN\Modules\IndexationRisk\IndexationRiskInstaller;
use WPSN\Modules\IndexationRisk\IndexationRiskJobs;
use WPSN\Modules\IndexationRisk\IndexationRiskRepository;
use WPSN\Modules\SearchConsole\InternalLinkJobs;
use WPSN\Modules\SearchConsole\SearchConsoleInstaller;

defined('ABSPATH') || exit;

final class IndexationRiskAdmin
{
    private Container $container;
    private Logger $logger;
    private Settings $settings;
    private QueueInterface $queue;
    private QueueRunner $runner;

    public function __construct(Container $container)
    {
        $this->container = $container;
        $this->logger = $container->get('logger');
        $this->settings = $container->get('settings');
        $this->queue = $container->get('queue');
        $this->runner = $container->get('queue_runner');
    }

    public function register(): void
    {
        add_action('admin_menu', [$this, 'addMenu']);
        add_action('admin_post_wpsn_indexation_risk_start_scan', [$this, 'handleStartScan']);
        add_action('admin_post_wpsn_indexation_risk_run_worker', [$this, 'handleRunWorker']);
        add_action('admin_post_wpsn_indexation_risk_clear', [$this, 'handleClear']);
        add_action('admin_post_wpsn_indexation_risk_generate_il', [$this, 'handleGenerateInternalLinks']);
    }

    public function addMenu(): void
    {
        add_management_page(
            __('Indexation Risk', 'wp-seo-next'),
            __('Indexation Risk', 'wp-seo-next'),
            Capabilities::CAP_TOOLS,
            'wpsn-indexation-risk',
            [$this, 'render']
        );
    }

    private function pageUrl(array $args = []): string
    {
        return TasksWorkbenchContext::pageUrl('wpsn-indexation-risk', $args);
    }

    private function redirectNotice(string $msg, string $type = 'success'): void
    {
        $url = $this->pageUrl([
            'wpsn_notice' => rawurlencode($msg),
            'wpsn_notice_type' => $type,
        ]);
        wp_safe_redirect($url);
        exit;
    }

    private function redirectUrlWithNotice(string $url, string $msg, string $type = 'success'): void
    {
        $url = (string) wp_validate_redirect($url, $this->pageUrl());
        $url = (string) add_query_arg([
            'wpsn_notice' => rawurlencode($msg),
            'wpsn_notice_type' => $type,
        ], $url);

        wp_safe_redirect($url);
        exit;
    }

    public function handleStartScan(): void
    {
        if (!Capabilities::canManageTools()) {
            wp_die(esc_html__('Permission denied.', 'wp-seo-next'));
        }

        check_admin_referer('wpsn_indexation_risk_start_scan', 'wpsn_nonce');

        IndexationRiskInstaller::maybeInstall();
        $repo = new IndexationRiskRepository($this->logger);

        // Clear previous results (fresh scan).
        $repo->clearAll();

        $postTypes = $this->defaultPostTypes();
        $total = $this->countPublished($postTypes);

        $scanId = wp_generate_uuid4();

        update_option(IndexationRiskJobs::PROGRESS_OPTION, [
            'status' => 'running',
            'scan_id' => $scanId,
            'post_types' => $postTypes,
            'total' => $total,
            'processed' => 0,
            'started_at' => current_time('mysql', true),
            'updated_at' => current_time('mysql', true),
            'offset' => 0,
            'limit' => 25,
        ], false);

        $this->queue->enqueue(IndexationRiskJobs::JOB_SCAN, [
            'post_types' => $postTypes,
            'offset' => 0,
            'limit' => 25,
            'total' => $total,
            'scan_id' => $scanId,
        ], time() + 1);

        $this->redirectNotice(__('Scan started. Run the queue worker to process jobs.', 'wp-seo-next'), 'success');
    }

    public function handleRunWorker(): void
    {
        if (!Capabilities::canManageTools()) {
            wp_die(esc_html__('Permission denied.', 'wp-seo-next'));
        }

        check_admin_referer('wpsn_indexation_risk_run_worker', 'wpsn_nonce');

        $max = isset($_GET['max']) ? (int) $_GET['max'] : 10;
        $max = max(1, min(50, $max));

        $processed = 0;
        try {
            $processed = $this->runner->run($max);
        } catch (\Throwable $e) {
            $this->logger->error('IndexationRisk run worker failed: ' . $e->getMessage());
        }

        $this->redirectNotice(sprintf(__('Worker ran (%d jobs).', 'wp-seo-next'), (int) $processed), 'info');
    }

    public function handleClear(): void
    {
        if (!Capabilities::canManageTools()) {
            wp_die(esc_html__('Permission denied.', 'wp-seo-next'));
        }

        check_admin_referer('wpsn_indexation_risk_clear', 'wpsn_nonce');

        IndexationRiskInstaller::maybeInstall();
        $repo = new IndexationRiskRepository($this->logger);
        $repo->clearAll();

        delete_option(IndexationRiskJobs::PROGRESS_OPTION);
        delete_option(IndexationRiskJobs::LAST_SCAN_OPTION);

        $this->redirectNotice(__('Cleared risk results.', 'wp-seo-next'), 'success');
    }

    public function handleGenerateInternalLinks(): void
    {
        if (!Capabilities::canManageTools()) {
            wp_die(esc_html__('Permission denied.', 'wp-seo-next'));
        }

        $postId = isset($_GET['post_id']) ? (int) $_GET['post_id'] : 0;
        if ($postId <= 0) {
            $this->redirectNotice(__('Missing post ID.', 'wp-seo-next'), 'error');
        }

        check_admin_referer('wpsn_indexation_risk_generate_il_' . $postId, 'wpsn_nonce');

        $returnTo = isset($_GET['return_to']) ? esc_url_raw((string) wp_unslash($_GET['return_to'])) : '';
        $returnTo = is_string($returnTo) && $returnTo !== '' ? $returnTo : $this->pageUrl();

        if (!Capabilities::canManageGsc()) {
            $this->redirectUrlWithNotice($returnTo, __('You do not have permission to generate internal link suggestions (Search Console).', 'wp-seo-next'), 'error');
        }

        $settings = $this->container->get('settings');
        if (!$settings->moduleEnabled('search_console', false) || !has_filter('wpsn_queue_handle_' . InternalLinkJobs::JOB_GENERATE)) {
            $this->redirectUrlWithNotice($returnTo, __('Search Console module is disabled. Enable it to generate internal link suggestions.', 'wp-seo-next'), 'error');
        }

        $property = (string) $settings->get('search_console.property', '');
        if (trim($property) === '') {
            $this->redirectUrlWithNotice($returnTo, __('Search Console property is not configured. Open Search Console settings and pick a property.', 'wp-seo-next'), 'error');
        }

        $post = get_post($postId);
        if (!$post) {
            $this->redirectUrlWithNotice($returnTo, __('Post not found.', 'wp-seo-next'), 'error');
        }

        // Ensure required tables exist.
        SearchConsoleInstaller::maybeInstall();

        $rangeDays = (int) $settings->get('search_console.range_days', 28);
        $rangeDays = max(1, min(180, $rangeDays));

        $endDate = gmdate('Y-m-d');
        $startDate = gmdate('Y-m-d', time() - ($rangeDays * DAY_IN_SECONDS));

        $payload = [
            'property' => $property,
            'start_date' => $startDate,
            'end_date' => $endDate,
            'target_post_ids' => [$postId],
            'max_targets' => 1,
        ];

        $this->queue->enqueue(InternalLinkJobs::JOB_GENERATE, $payload, time() + 1);

        $this->redirectUrlWithNotice($returnTo, __('Internal link suggestions job queued. Run the queue worker to process jobs.', 'wp-seo-next'), 'success');
    }

    public function render(): void
    {
        if (!Capabilities::canManageTools()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'wp-seo-next'));
        }

        IndexationRiskInstaller::maybeInstall();
        $repo = new IndexationRiskRepository($this->logger);

        $notice = isset($_GET['wpsn_notice']) ? sanitize_text_field((string) wp_unslash($_GET['wpsn_notice'])) : '';
        $noticeType = isset($_GET['wpsn_notice_type']) ? sanitize_key((string) wp_unslash($_GET['wpsn_notice_type'])) : 'success';
        if (!in_array($noticeType, ['success', 'error', 'warning', 'info'], true)) {
            $noticeType = 'success';
        }

        $progress = get_option(IndexationRiskJobs::PROGRESS_OPTION, []);
        $progress = is_array($progress) ? $progress : [];

        $lastScan = get_option(IndexationRiskJobs::LAST_SCAN_OPTION, []);
        $lastScan = is_array($lastScan) ? $lastScan : [];

        $level = isset($_GET['level']) ? sanitize_key((string) wp_unslash($_GET['level'])) : '';
        $orphan = isset($_GET['orphan']) ? (int) $_GET['orphan'] : 0;
        $postType = isset($_GET['post_type']) ? sanitize_key((string) wp_unslash($_GET['post_type'])) : '';
        $search = isset($_GET['s']) ? sanitize_text_field((string) wp_unslash($_GET['s'])) : '';

        $paged = isset($_GET['paged']) ? max(1, (int) $_GET['paged']) : 1;
        $perPage = isset($_GET['per_page']) ? max(10, min(200, (int) $_GET['per_page'])) : 50;
        $offset = ($paged - 1) * $perPage;

        $list = $repo->list([
            'level' => $level,
            'orphan' => $orphan,
            'post_type' => $postType,
            'search' => $search,
            'limit' => $perPage,
            'offset' => $offset,
        ]);
        $rows = $list['rows'] ?? [];
        $total = (int) ($list['total'] ?? 0);
        $totalPages = (int) ceil($total / max(1, $perPage));

        $startUrl = wp_nonce_url(admin_url('admin-post.php?action=wpsn_indexation_risk_start_scan'), 'wpsn_indexation_risk_start_scan', 'wpsn_nonce');
        $workerUrl = wp_nonce_url(admin_url('admin-post.php?action=wpsn_indexation_risk_run_worker&max=10'), 'wpsn_indexation_risk_run_worker', 'wpsn_nonce');
        $clearUrl = wp_nonce_url(admin_url('admin-post.php?action=wpsn_indexation_risk_clear'), 'wpsn_indexation_risk_clear', 'wpsn_nonce');

        $postTypes = $this->defaultPostTypes();

        ?>
        <div class="wrap">
            <h1><?php echo esc_html__('Indexation Risk', 'wp-seo-next'); ?></h1>

            <?php if ($notice !== '') : ?>
                <div class="notice notice-<?php echo esc_attr($noticeType); ?> is-dismissible"><p><?php echo esc_html($notice); ?></p></div>
            <?php endif; ?>

            <p class="description">
                <?php echo esc_html__('Scans published content and highlights pages that may struggle to get indexed: orphans, thin pages, sitemap exclusions.', 'wp-seo-next'); ?>
            </p>

            <div style="margin: 12px 0; display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
                <a class="button button-primary" href="<?php echo esc_url($startUrl); ?>"><?php echo esc_html__('Start scan', 'wp-seo-next'); ?></a>

                <details class="wpsn-advanced" style="margin:0;">
                    <summary><?php echo esc_html__('Advanced', 'wp-seo-next'); ?></summary>
                    <div style="margin-top:8px; display:flex; gap:8px; flex-wrap:wrap; align-items:center;">
                        <a class="button" href="<?php echo esc_url($workerUrl); ?>"><?php echo esc_html__('Run worker (10 jobs)', 'wp-seo-next'); ?></a>
                        <a class="button button-secondary" href="<?php echo esc_url($clearUrl); ?>" onclick="return confirm('<?php echo esc_js(__('Clear stored results?', 'wp-seo-next')); ?>');"><?php echo esc_html__('Clear results', 'wp-seo-next'); ?></a>
                    </div>
                </details>
            </div>

            <?php if (!empty($progress)) : ?>
                <div class="notice notice-info" style="padding: 10px;">
                    <?php
                    $status = isset($progress['status']) ? (string) $progress['status'] : '';
                    $processed = isset($progress['processed']) ? (int) $progress['processed'] : 0;
                    $totalP = isset($progress['total']) ? (int) $progress['total'] : 0;
                    $started = isset($progress['started_at']) ? (string) $progress['started_at'] : '';
                    $finished = isset($progress['finished_at']) ? (string) $progress['finished_at'] : '';
                    ?>
                    <p style="margin:0;">
                        <strong><?php echo esc_html__('Progress', 'wp-seo-next'); ?>:</strong>
                        <?php echo esc_html($status !== '' ? $status : '-'); ?>
                        — <?php echo esc_html($processed); ?> / <?php echo esc_html($totalP); ?>
                        <?php if ($started !== '') : ?>
                            — <span style="opacity:.8;"><?php echo esc_html__('started', 'wp-seo-next'); ?>: <?php echo esc_html($started); ?></span>
                        <?php endif; ?>
                        <?php if ($finished !== '') : ?>
                            — <span style="opacity:.8;"><?php echo esc_html__('finished', 'wp-seo-next'); ?>: <?php echo esc_html($finished); ?></span>
                        <?php endif; ?>
                    </p>
                </div>
            <?php elseif (!empty($lastScan)) : ?>
                <div class="notice notice-success" style="padding: 10px;">
                    <p style="margin:0;">
                        <strong><?php echo esc_html__('Last scan', 'wp-seo-next'); ?>:</strong>
                        <?php echo esc_html((string) ($lastScan['finished_at'] ?? '')); ?>
                        — <?php echo esc_html((int) ($lastScan['processed'] ?? 0)); ?>
                        <?php echo esc_html__('items', 'wp-seo-next'); ?>
                    </p>
                </div>
            <?php endif; ?>

            <form method="get" action="<?php echo esc_url(admin_url('tools.php')); ?>" style="margin: 14px 0;">
                <input type="hidden" name="page" value="wpsn-indexation-risk" />

                <label style="margin-right: 10px;">
                    <?php echo esc_html__('Risk level', 'wp-seo-next'); ?>
                    <select name="level">
                        <option value="" <?php selected($level, ''); ?>><?php echo esc_html__('All', 'wp-seo-next'); ?></option>
                        <option value="high" <?php selected($level, 'high'); ?>><?php echo esc_html__('High', 'wp-seo-next'); ?></option>
                        <option value="medium" <?php selected($level, 'medium'); ?>><?php echo esc_html__('Medium', 'wp-seo-next'); ?></option>
                        <option value="low" <?php selected($level, 'low'); ?>><?php echo esc_html__('Low', 'wp-seo-next'); ?></option>
                    </select>
                </label>

                <label style="margin-right: 10px;">
                    <?php echo esc_html__('Post type', 'wp-seo-next'); ?>
                    <select name="post_type">
                        <option value="" <?php selected($postType, ''); ?>><?php echo esc_html__('All', 'wp-seo-next'); ?></option>
                        <?php foreach ($postTypes as $pt) : ?>
                            <option value="<?php echo esc_attr($pt); ?>" <?php selected($postType, $pt); ?>><?php echo esc_html($pt); ?></option>
                        <?php endforeach; ?>
                    </select>
                </label>

                <label style="margin-right: 10px;">
                    <input type="checkbox" name="orphan" value="1" <?php checked($orphan, 1); ?> />
                    <?php echo esc_html__('Only orphans', 'wp-seo-next'); ?>
                </label>

                <label style="margin-right: 10px;">
                    <?php echo esc_html__('Search', 'wp-seo-next'); ?>
                    <input type="text" name="s" value="<?php echo esc_attr($search); ?>" />
                </label>

                <label style="margin-right: 10px;">
                    <?php echo esc_html__('Per page', 'wp-seo-next'); ?>
                    <input type="number" name="per_page" min="10" max="200" value="<?php echo (int) $perPage; ?>" style="width:90px;" />
                </label>

                <button class="button button-secondary"><?php echo esc_html__('Filter', 'wp-seo-next'); ?></button>
            </form>

            <table class="widefat striped">
                <thead>
                    <tr>
                        <th><?php echo esc_html__('Score', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Post', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Type', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Inbound', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Words', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Sitemap', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Indexable', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Reasons', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Actions', 'wp-seo-next'); ?></th>
                        <th><?php echo esc_html__('Scanned', 'wp-seo-next'); ?></th>
                    </tr>
                </thead>
                <tbody>
                    <?php if (empty($rows)) : ?>
                        <tr><td colspan="10"><?php echo esc_html__('No results yet. Start a scan.', 'wp-seo-next'); ?></td></tr>
                    <?php else : ?>
                        <?php
                        $returnTo = $this->pageUrl([
                            'level' => $level,
                            'orphan' => $orphan,
                            'post_type' => $postType,
                            's' => $search,
                            'per_page' => $perPage,
                            'paged' => $paged,
                        ]);

                        $canGscActions = Capabilities::canManageGsc() && $this->container->get('settings')->moduleEnabled('search_console', false);
                        ?>
                        <?php foreach ($rows as $r) : ?>
                            <?php
                            $score = (int) ($r['score'] ?? 0);
                            $pid = (int) ($r['post_id'] ?? 0);
                            $pt = (string) ($r['post_type'] ?? '');
                            $url = (string) ($r['url'] ?? '');
                            $title = (string) ($r['title'] ?? '');
                            $inbound = (int) ($r['inbound_links'] ?? 0);
                            $wc = (int) ($r['word_count'] ?? 0);
                            $inSitemap = !empty($r['in_sitemap']);
                            $indexable = !empty($r['indexable']);
                            $reasons = $r['reasons_decoded'] ?? null;
                            $scannedAt = (string) ($r['scanned_at'] ?? '');

                            $risk = $this->riskLabel($score, $indexable);
                            $editUrl = $pid > 0 ? get_edit_post_link($pid, '') : '';

                            // Frontend Inspector one-click actions.
                            $inspectUrl = '';
                            $aiSnippetUrl = '';
                            if ($url !== '') {
                                $inspectUrl = (string) add_query_arg(['wpsn_inspector' => '1'], $url);
                                $aiSnippetUrl = (string) add_query_arg([
                                    'wpsn_inspector' => '1',
                                    'wpsn_ai_gen' => 'snippet',
                                    'wpsn_ai_only_empty' => '1',
                                ], $url);
                            }

                            $genIlUrl = '';
                            $viewIlUrl = '';
                            if ($pid > 0) {
                                $genIlUrl = wp_nonce_url(
                                    add_query_arg([
                                        'action' => 'wpsn_indexation_risk_generate_il',
                                        'post_id' => $pid,
                                        'return_to' => $returnTo,
                                    ], admin_url('admin-post.php')),
                                    'wpsn_indexation_risk_generate_il_' . $pid,
                                    'wpsn_nonce'
                                );

                                $viewIlUrl = add_query_arg([
                                    'page' => 'wpsn-search-console',
                                    'view' => 'links',
                                    'target_id' => $pid,
                                ], admin_url('tools.php'));
                            }
                            ?>
                            <tr>
                                <td>
                                    <strong><?php echo esc_html($score); ?></strong>
                                    <div style="font-size:12px; opacity:.8;"><?php echo esc_html($risk); ?></div>
                                </td>
                                <td>
                                    <?php if (is_string($editUrl) && $editUrl !== '') : ?>
                                        <a href="<?php echo esc_url($editUrl); ?>"><?php echo esc_html($title !== '' ? $title : ('#' . $pid)); ?></a>
                                    <?php else : ?>
                                        <?php echo esc_html($title !== '' ? $title : ('#' . $pid)); ?>
                                    <?php endif; ?>
                                    <?php if ($url !== '') : ?>
                                        <div style="font-size:12px; opacity:.8;"><a href="<?php echo esc_url($url); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html($url); ?></a></div>
                                    <?php endif; ?>
                                </td>
                                <td><?php echo esc_html($pt); ?></td>
                                <td><?php echo esc_html($inbound); ?></td>
                                <td><?php echo esc_html($wc); ?></td>
                                <td><?php echo esc_html($this->boolLabel($inSitemap)); ?></td>
                                <td><?php echo esc_html($this->boolLabel($indexable)); ?></td>
                                <td>
                                    <?php
                                    if (is_array($reasons) && !empty($reasons)) {
                                        echo '<ul style="margin:0; padding-left:18px;">';
                                        $i = 0;
                                        foreach ($reasons as $rr) {
                                            if (!is_array($rr)) {
                                                continue;
                                            }
                                            $msg = isset($rr['message']) ? (string) $rr['message'] : '';
                                            if ($msg === '') {
                                                continue;
                                            }
                                            echo '<li>' . esc_html($msg) . '</li>';
                                            $i++;
                                            if ($i >= 4) {
                                                break;
                                            }
                                        }
                                        if (count($reasons) > 4) {
                                            echo '<li>…</li>';
                                        }
                                        echo '</ul>';
                                    } else {
                                        echo '<span style="opacity:.7;">-</span>';
                                    }
                                    ?>
                                </td>
                                <td>
                                    <?php if (is_string($editUrl) && $editUrl !== '') : ?>
                                        <a class="button button-small" href="<?php echo esc_url($editUrl); ?>"><?php echo esc_html__('Edit', 'wp-seo-next'); ?></a>
                                    <?php endif; ?>

                                    <?php if (is_string($inspectUrl) && $inspectUrl !== '') : ?>
                                        <a class="button button-small" style="margin-left:4px;" href="<?php echo esc_url($inspectUrl); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('Edit SEO', 'wp-seo-next'); ?></a>
                                        <?php if (!(bool) $this->settings->get('privacy.hide_ai_ui', false)) : ?>
                                            <a class="button button-small" style="margin-left:4px;" href="<?php echo esc_url($aiSnippetUrl); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('AI Snippet', 'wp-seo-next'); ?></a>
                                        <?php endif; ?>
                                    <?php endif; ?>

                                    <?php if ($pid > 0 && $canGscActions) : ?>
                                        <a class="button button-small" style="margin-left:4px;" href="<?php echo esc_url($genIlUrl); ?>"><?php echo esc_html__('Generate link suggestions', 'wp-seo-next'); ?></a>
                                        <a class="button button-small" style="margin-left:4px;" href="<?php echo esc_url($viewIlUrl); ?>"><?php echo esc_html__('View suggestions', 'wp-seo-next'); ?></a>
                                    <?php else : ?>
                                        <span style="opacity:.7; margin-left:6px;">-</span>
                                    <?php endif; ?>
                                </td>
                                <td><?php echo esc_html($scannedAt); ?></td>
                            </tr>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </tbody>
            </table>

            <?php if ($totalPages > 1) : ?>
                <div class="tablenav" style="margin-top: 10px;">
                    <div class="tablenav-pages">
                        <?php
                        $baseArgs = [
                            'level' => $level,
                            'orphan' => $orphan,
                            'post_type' => $postType,
                            's' => $search,
                            'per_page' => $perPage,
                        ];
                        $prev = max(1, $paged - 1);
                        $next = min($totalPages, $paged + 1);
                        ?>
                        <a class="button" href="<?php echo esc_url($this->pageUrl(array_merge($baseArgs, ['paged' => $prev]))); ?>" <?php echo $paged <= 1 ? 'disabled' : ''; ?>><?php echo esc_html__('Prev', 'wp-seo-next'); ?></a>
                        <span style="margin: 0 8px;">
                            <?php echo esc_html(sprintf(__('Page %d of %d', 'wp-seo-next'), $paged, $totalPages)); ?>
                        </span>
                        <a class="button" href="<?php echo esc_url($this->pageUrl(array_merge($baseArgs, ['paged' => $next]))); ?>" <?php echo $paged >= $totalPages ? 'disabled' : ''; ?>><?php echo esc_html__('Next', 'wp-seo-next'); ?></a>
                    </div>
                </div>
            <?php endif; ?>
        </div>
        <?php
    }

    private function boolLabel(bool $v): string
    {
        return $v ? __('Yes', 'wp-seo-next') : __('No', 'wp-seo-next');
    }

    private function riskLabel(int $score, bool $indexable): string
    {
        if (!$indexable) {
            return __('Noindex', 'wp-seo-next');
        }
        if ($score < 50) {
            return __('High risk', 'wp-seo-next');
        }
        if ($score < 80) {
            return __('Medium risk', 'wp-seo-next');
        }
        return __('Low risk', 'wp-seo-next');
    }

    /**
     * @return string[]
     */
    private function defaultPostTypes(): array
    {
        $pts = get_post_types(['public' => true], 'names');
        $out = [];
        foreach ($pts as $pt) {
            if ($pt === 'attachment') {
                continue;
            }
            $out[] = (string) $pt;
        }
        return $out;
    }

    /**
     * @param string[] $postTypes
     */
    private function countPublished(array $postTypes): int
    {
        $total = 0;
        foreach ($postTypes as $pt) {
            $pt = sanitize_key((string) $pt);
            if ($pt === '') {
                continue;
            }
            $counts = wp_count_posts($pt);
            if (is_object($counts) && isset($counts->publish)) {
                $total += (int) $counts->publish;
            }
        }
        return $total;
    }
}
