<?php
/**
 * Dashboard view: KPI cards + visits chart + top pages + top sources.
 *
 * @package Brainwerk SEO Suite
 */
if ( ! defined( 'ABSPATH' ) ) { exit; }

$range_hours = isset( $_GET['range'] ) ? max( 24, (int) $_GET['range'] ) : 24 * 7; // phpcs:ignore WordPress.Security.NonceVerification
$scope       = Seoforge_Utils::stats_scope();          // int blog_id, or null = whole network.
$is_network  = ( null === $scope ) && is_multisite();  // network-wide aggregate view.
$summary     = Seoforge_Stats::summary( $range_hours, $scope );
$health      = Seoforge_Health::check();
$competitor  = Seoforge_Compat::competitor_label();
$has_visits  = $summary['visits'] > 0;
$score_class = $health['score'] >= 80 ? 'good' : ( $health['score'] >= 50 ? 'ok' : 'bad' );
$daily       = Seoforge_Stats::visits_daily( max( 7, (int) ceil( $range_hours / 24 ) ), $scope );
$top_pages   = Seoforge_Stats::top_pages( $range_hours, 10, $scope );
$top_sources = Seoforge_Stats::top_sources( $range_hours, 10, $scope );
$device      = Seoforge_Stats::device_breakdown( $range_hours, $scope );
$by_blog     = $is_network ? Seoforge_Stats::summary_by_blog( $range_hours ) : array();

// === SEO network payoff: benchmark comparisons + bot-reputation panel =====
// All of this is opt-in telemetry the site itself contributed (see
// Seoforge_Intel); when the hub hasn't sent anything back yet (feed absent,
// not enough peers, not registered) every one of these stays null/empty and
// the page below renders exactly like it did before this feature existed.
$bench_n     = class_exists( 'Seoforge_Benchmark' ) ? Seoforge_Benchmark::cell_n() : 0;
$kpi_bench   = array();
if ( $bench_n > 0 ) {
    $bounce_cmp = Seoforge_Benchmark::comparison( 'bounce_pct', $summary['bounce_rate'] );
    if ( $bounce_cmp ) {
        $kpi_bench['bounce_rate'] = array( __( 'Bounce rate', 'brainwerk-seo-suite' ), $bounce_cmp );
    }
    $avg_cmp = Seoforge_Benchmark::comparison( 'avg_session_sec', $summary['avg_duration'] );
    if ( $avg_cmp ) {
        $kpi_bench['avg_duration'] = array( __( 'Avg session', 'brainwerk-seo-suite' ), $avg_cmp );
    }
}
// Nothing to compare yet for this site's cell: an honest, factual line about
// network participation instead of the KPI list — never a blank/placeholder.
$network_progress_msg = empty( $kpi_bench ) && class_exists( 'Seoforge_Benchmark' )
    ? Seoforge_Benchmark::network_progress_message()
    : null;
$position_labels = array(
    'below_p25' => __( 'below industry average', 'brainwerk-seo-suite' ),
    'mid'       => __( 'in line with industry average', 'brainwerk-seo-suite' ),
    'above_p75' => __( 'above industry average', 'brainwerk-seo-suite' ),
);

// Labels shared by the industry-benchmark comparison above and the local
// self-comparison ("Eigenvergleich") trend widget below.
$analyzer_labels = array(
    'title_length'     => __( 'Title length', 'brainwerk-seo-suite' ),
    'meta_description' => __( 'Meta description', 'brainwerk-seo-suite' ),
    'focus_in_title'   => __( 'Focus keyword in title', 'brainwerk-seo-suite' ),
    'focus_in_slug'    => __( 'Focus keyword in slug', 'brainwerk-seo-suite' ),
    'focus_in_intro'   => __( 'Focus keyword in intro', 'brainwerk-seo-suite' ),
    'internal_links'   => __( 'Internal links', 'brainwerk-seo-suite' ),
    'image_alt'        => __( 'Image alt text', 'brainwerk-seo-suite' ),
    'word_count'       => __( 'Word count', 'brainwerk-seo-suite' ),
    'readability'      => __( 'Readability', 'brainwerk-seo-suite' ),
);

// Bot mix + analyzer-vs-industry comparison need a single concrete site — skip
// on the network-aggregate view (same free/Pro boundary as the by-site table above).
$bots            = null;
$bot_reputation  = false;
$analyzer_own    = null;
$analyzer_bench  = array();
if ( ! $is_network ) {
    $bots_blog_id   = null === $scope ? Seoforge_Utils::current_blog_id() : $scope;
    $bot_reputation = class_exists( 'Seoforge_Bot_Reputation' ) && Seoforge_Bot_Reputation::available();
    if ( class_exists( 'Seoforge_Intel' ) ) {
        $bot_start = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS * $range_hours );
        $bot_end   = gmdate( 'Y-m-d H:i:s' );
        $bots      = Seoforge_Intel::build_bots_group( $bots_blog_id, $bot_start, $bot_end );

        $analyzer_own = Seoforge_Intel::build_analyzer_group( $bots_blog_id );
        if ( $analyzer_own && $bench_n > 0 ) {
            foreach ( $analyzer_own['check_fail_pct'] as $check_key => $own_fail_pct ) {
                $cmp = Seoforge_Benchmark::analyzer_comparison( $check_key, $own_fail_pct );
                if ( $cmp ) {
                    $cmp['label']              = isset( $analyzer_labels[ $check_key ] ) ? $analyzer_labels[ $check_key ] : $check_key;
                    $analyzer_bench[ $check_key ] = $cmp;
                }
            }
        }
    }
}

// === Eigenvergleich: local self-comparison, network-free, opt-in-free =====
// See Seoforge_History (WP4a) — one aggregate row/day, stored locally. Skip
// on the network-aggregate view, same as the bot/analyzer panels above (no
// single concrete blog to read history for).
$eigen_window   = 30; // days per comparison side ("this month vs last month")
$eigen_status   = 'empty';
$eigen_analyzer = array();
$eigen_score    = array();
$eigen_hours    = array();
$eigen_weekdays = array();
$eigen_ai_families = array();
$eigen_ai_ratio = null;
$eigen_headline = array();
if ( ! $is_network && class_exists( 'Seoforge_History' ) ) {
    $eh_blog_id  = $bots_blog_id;
    $eh_counts   = Seoforge_History::capture_counts( $eigen_window, $eh_blog_id );
    $eigen_status = Seoforge_History_Widgets::comparison_status( $eh_counts['current'], $eh_counts['previous'], $eigen_window );

    if ( 'empty' !== $eigen_status ) {
        // 1) Analyzer trend: per-check fail rate now vs the comparison window, sorted
        //    so the biggest problems and the biggest improvements surface first.
        foreach ( Seoforge_Intel::ANALYZER_CHECK_KEYS as $check_key ) {
            $cmp = Seoforge_History::compare( 'check_fail_pct.' . $check_key, $eigen_window, $eh_blog_id );
            $eigen_analyzer[] = array(
                'key'        => $check_key,
                'label'      => isset( $analyzer_labels[ $check_key ] ) ? $analyzer_labels[ $check_key ] : $check_key,
                'current'    => $cmp['current'],
                'previous'   => $cmp['previous'],
                'delta'      => $cmp['delta'], // raw numeric delta — sort_analyzer_trend() sorts on this
                'delta_fmt'  => Seoforge_History_Widgets::format_delta( $cmp['current'], $cmp['previous'], true ), // fail rate: lower is better
            );
        }
        $eigen_analyzer = Seoforge_History_Widgets::sort_analyzer_trend( $eigen_analyzer );

        // Overall score distribution, now vs then.
        $score_buckets = array(
            '81_100' => __( 'Score 81–100', 'brainwerk-seo-suite' ),
            '61_80'  => __( 'Score 61–80', 'brainwerk-seo-suite' ),
            '41_60'  => __( 'Score 41–60', 'brainwerk-seo-suite' ),
            '0_40'   => __( 'Score 0–40', 'brainwerk-seo-suite' ),
        );
        foreach ( $score_buckets as $bucket_key => $bucket_label ) {
            $cmp = Seoforge_History::compare( 'score_dist.' . $bucket_key, $eigen_window, $eh_blog_id );
            $eigen_score[] = array(
                'key'      => $bucket_key,
                'label'    => $bucket_label,
                'current'  => $cmp['current'],
                'previous' => $cmp['previous'],
            );
        }

        // 2) Traffic shape: 24h + weekday profile, most recent captured day.
        $hours_series    = Seoforge_History::series( 'hours_profile', $eigen_window, $eh_blog_id );
        $weekdays_series = Seoforge_History::series( 'weekdays_profile', $eigen_window, $eh_blog_id );
        $latest_hours    = Seoforge_History_Widgets::last_value( $hours_series );
        $latest_weekdays = Seoforge_History_Widgets::last_value( $weekdays_series );
        if ( is_array( $latest_hours ) ) {
            foreach ( $latest_hours as $h => $pct ) {
                $eigen_hours[] = array( 'label' => sprintf( '%02d', $h ), 'value' => (int) $pct );
            }
        }
        $weekday_labels = array(
            __( 'Mon', 'brainwerk-seo-suite' ), __( 'Tue', 'brainwerk-seo-suite' ), __( 'Wed', 'brainwerk-seo-suite' ),
            __( 'Thu', 'brainwerk-seo-suite' ), __( 'Fri', 'brainwerk-seo-suite' ), __( 'Sat', 'brainwerk-seo-suite' ),
            __( 'Sun', 'brainwerk-seo-suite' ),
        );
        if ( is_array( $latest_weekdays ) ) {
            foreach ( $latest_weekdays as $wd => $pct ) {
                $eigen_weekdays[] = array( 'label' => isset( $weekday_labels[ $wd ] ) ? $weekday_labels[ $wd ] : $wd, 'value' => (int) $pct );
            }
        }

        // 3) AI-crawler development: per-family sparkline (top families by total
        //    volume across both windows) + the crawl-to-referral ratio.
        $ai_known = class_exists( 'Seoforge_Robots' ) ? Seoforge_Robots::ai_bots() : array();
        $ai_totals = array();
        foreach ( $ai_known as $token => $ai_label ) {
            $cmp = Seoforge_History::compare( 'ai_crawl_counts.' . $token, $eigen_window, $eh_blog_id );
            $total = (float) ( $cmp['current'] ?: 0 ) + (float) ( $cmp['previous'] ?: 0 );
            if ( $total > 0 ) {
                $ai_totals[ $token ] = array( 'label' => $ai_label, 'total' => $total, 'cmp' => $cmp );
            }
        }
        uasort( $ai_totals, function ( $a, $b ) { return $b['total'] <=> $a['total']; } );
        $ai_totals = array_slice( $ai_totals, 0, 6, true );
        foreach ( $ai_totals as $token => $info ) {
            $series = Seoforge_History::series( 'ai_crawl_counts.' . $token, $eigen_window * 2, $eh_blog_id );
            $eigen_ai_families[] = array(
                'label'  => $info['label'],
                'values' => array_column( $series, 'value' ),
                'delta'  => Seoforge_History_Widgets::format_delta( $info['cmp']['current'], $info['cmp']['previous'], false ),
            );
        }
        $ratio_cmp      = Seoforge_History::compare( 'ai_crawl_to_referral', $eigen_window, $eh_blog_id );
        $eigen_ai_ratio = Seoforge_History_Widgets::format_delta( $ratio_cmp['current'], $ratio_cmp['previous'], true );

        // 4) Headline deltas: pageviews / sessions / bounce / engaged.
        $headline_metrics = array(
            'pageviews'   => array( __( 'Pageviews', 'brainwerk-seo-suite' ), false, 0, '' ),
            'sessions'    => array( __( 'Sessions', 'brainwerk-seo-suite' ), false, 0, '' ),
            'bounce_pct'  => array( __( 'Bounce rate', 'brainwerk-seo-suite' ), true, 1, '%' ),
            'engaged_pct' => array( __( 'Engaged sessions', 'brainwerk-seo-suite' ), false, 1, '%' ),
        );
        foreach ( $headline_metrics as $metric_key => $meta ) {
            list( $metric_label, $lower_is_better, $decimals, $unit_suffix ) = $meta;
            $c = Seoforge_History::compare( $metric_key, $eigen_window, $eh_blog_id );
            $eigen_headline[ $metric_key ] = array(
                'label'    => $metric_label,
                'decimals' => $decimals,
                'suffix'   => $unit_suffix,
                'delta'    => Seoforge_History_Widgets::format_delta( $c['current'], $c['previous'], $lower_is_better ),
            );
        }
    }
}

$ranges = array(
    24       => __( '24 hours', 'brainwerk-seo-suite' ),
    24 * 7   => __( '7 days', 'brainwerk-seo-suite' ),
    24 * 30  => __( '30 days', 'brainwerk-seo-suite' ),
    24 * 90  => __( '90 days', 'brainwerk-seo-suite' ),
);
$live = Seoforge_Stats::live_visitors( $scope );
?>

<?php
// === Hero status banner (CI parity with ShieldForge) ===
// Map the 0-100 health score to a calm/elevated/high/critical state.
$score = (int) $health['score'];
if ( $score >= 90 ) {
    $hero_state    = 'is-calm';
    $hero_emoji    = '🛡️';
    $hero_headline = __( 'Your SEO setup looks solid.', 'brainwerk-seo-suite' );
    $hero_sub      = __( 'Tracking + sitemap + schema all healthy. Sit back and watch the numbers.', 'brainwerk-seo-suite' );
} elseif ( $score >= 70 ) {
    $hero_state    = 'is-elevated';
    $hero_emoji    = '✨';
    $hero_headline = __( 'Good shape — a few details left.', 'brainwerk-seo-suite' );
    $hero_sub      = __( 'Most of Brainwerk SEO Suite is configured. Tick off the remaining items below to reach 100.', 'brainwerk-seo-suite' );
} elseif ( $score >= 40 ) {
    $hero_state    = 'is-high';
    $hero_emoji    = '⚠️';
    $hero_headline = __( 'Important pieces are still missing.', 'brainwerk-seo-suite' );
    $hero_sub      = __( 'A few key settings need your attention before Brainwerk SEO Suite can do its full job.', 'brainwerk-seo-suite' );
} else {
    $hero_state    = 'is-critical';
    $hero_emoji    = '🚧';
    $hero_headline = __( 'Setup is incomplete.', 'brainwerk-seo-suite' );
    $hero_sub      = __( 'Walk through the action items below to get tracking and SEO into a usable state.', 'brainwerk-seo-suite' );
}
$open_tasks = array_values( array_filter( (array) $health['tasks'], function ( $t ) { return empty( $t['done'] ); } ) );
?>

<?php Seoforge_Admin::scope_picker(); ?>

<?php if ( $is_network ) : ?>
<div class="seoforge-network-note">
    <?php esc_html_e( 'Showing aggregated data for the entire network. Use the selector above to focus on a single site.', 'brainwerk-seo-suite' ); ?>
</div>
<?php endif; ?>

<div class="seoforge-hero <?php echo esc_attr( $hero_state ); ?>">
    <div class="seoforge-hero-score">
        <span class="seoforge-hero-score-num"><?php echo (int) $score; ?></span>
        <span class="seoforge-hero-score-max">/ 100</span>
    </div>
    <div class="seoforge-hero-text">
        <div class="seoforge-hero-headline">
            <span class="seoforge-hero-emoji" aria-hidden="true"><?php echo esc_html( $hero_emoji ); ?></span>
            <?php echo esc_html( $hero_headline ); ?>
        </div>
        <div class="seoforge-hero-sub"><?php echo esc_html( $hero_sub ); ?></div>
    </div>
    <div class="seoforge-hero-bar"><span style="width:<?php echo (int) $score; ?>%"></span></div>
</div>

<?php if ( ! empty( $open_tasks ) ) : ?>
<div class="seoforge-action-items">
    <h2 class="seoforge-action-items-title"><?php
        printf(
            /* translators: %d open task count */
            esc_html( _n( '%d action item', '%d action items', count( $open_tasks ), 'brainwerk-seo-suite' ) ),
            count( $open_tasks )
        );
    ?></h2>
    <div class="seoforge-action-grid">
        <?php
        // Add a "Visit your site" task as critical if there are no visits yet.
        if ( ! $has_visits ) :
            $sev = 'is-critical';
            ?>
            <a class="seoforge-action-card <?php echo esc_attr( $sev ); ?>" href="<?php echo esc_url( home_url( '/' ) ); ?>" target="_blank" rel="noopener">
                <span class="seoforge-action-icon" aria-hidden="true">📊</span>
                <span class="seoforge-action-text">
                    <strong><?php esc_html_e( 'No data yet — open your site once to record the first visit.', 'brainwerk-seo-suite' ); ?></strong>
                </span>
                <span class="seoforge-action-arrow">→</span>
            </a>
        <?php endif; ?>

        <?php if ( ! $has_visits && $competitor ) : ?>
            <a class="seoforge-action-card is-info" href="<?php echo esc_url( admin_url( 'admin.php?page=brainwerk-seo-suite&tab=import' ) ); ?>">
                <span class="seoforge-action-icon" aria-hidden="true">⬇️</span>
                <span class="seoforge-action-text">
                    <strong><?php
                    printf(
                        /* translators: %s competitor plugin name */
                        esc_html__( 'Import settings from %s', 'brainwerk-seo-suite' ),
                        esc_html( $competitor )
                    );
                    ?></strong>
                </span>
                <span class="seoforge-action-arrow">→</span>
            </a>
        <?php endif; ?>

        <?php foreach ( $open_tasks as $t ) :
            // Severity heuristic: tracking-enabled + IP-anon are critical;
            // sitemap/schema/org-data are warnings; the rest are info.
            $crit_keywords = array( 'tracking', 'IPs', 'GDPR', 'cookie' );
            $is_crit       = false;
            foreach ( $crit_keywords as $kw ) {
                if ( false !== stripos( $t['label'], $kw ) ) { $is_crit = true; break; }
            }
            $sev = $is_crit ? 'is-critical' : ( ( false !== stripos( $t['label'], 'enabled' ) || false !== stripos( $t['label'], 'on' ) ) ? 'is-warning' : 'is-info' );
            ?>
            <a class="seoforge-action-card <?php echo esc_attr( $sev ); ?>" href="<?php echo esc_url( $t['action_url'] ); ?>">
                <span class="seoforge-action-icon" aria-hidden="true"><?php echo $is_crit ? '⚠️' : ( 'is-warning' === $sev ? '⚙️' : 'ℹ️' ); ?></span>
                <span class="seoforge-action-text">
                    <strong><?php echo esc_html( $t['label'] ); ?></strong>
                    <?php if ( ! empty( $t['hint'] ) ) : ?>
                        <br><small><?php echo esc_html( $t['hint'] ); ?></small>
                    <?php endif; ?>
                </span>
                <span class="seoforge-action-arrow">→</span>
            </a>
        <?php endforeach; ?>
    </div>
</div>
<?php else : ?>
<div class="seoforge-action-items">
    <div class="seoforge-action-items-empty">
        ✓ <?php esc_html_e( 'No open action items — your setup is complete.', 'brainwerk-seo-suite' ); ?>
    </div>
</div>
<?php endif; ?>

<div class="seoforge-card seoforge-live-card">
    <div class="seoforge-row-spread">
        <h2><span class="seoforge-pulse"></span> <?php esc_html_e( 'Right now', 'brainwerk-seo-suite' ); ?></h2>
        <small class="description" id="seoforge-live-tick"><?php esc_html_e( 'updates every 15s', 'brainwerk-seo-suite' ); ?></small>
    </div>
    <p style="font-size:32px;margin:6px 0 4px;font-weight:700">
        <span id="seoforge-live-count"><?php echo (int) $live['visitors']; ?></span>
        <small style="font-size:14px;font-weight:400;color:#6b7280;">
            <?php esc_html_e( 'active visitors (last 5 min)', 'brainwerk-seo-suite' ); ?>
        </small>
    </p>
    <ol id="seoforge-live-pages" style="margin:6px 0 0;padding-left:20px;font-size:14px;line-height:1.7;">
        <?php foreach ( (array) $live['pages'] as $p ) : ?>
            <li>
                <a href="<?php echo esc_url( home_url( $p['url_path'] ) ); ?>" target="_blank">
                    <?php echo esc_html( $p['title'] ?: $p['url_path'] ); ?>
                </a>
                — <?php echo esc_html( number_format_i18n( $p['hits'] ) ); ?>
            </li>
        <?php endforeach; ?>
    </ol>
</div>
<div class="seoforge-row-spread">
    <h2><?php esc_html_e( 'Overview', 'brainwerk-seo-suite' ); ?></h2>
    <div class="seoforge-range-picker">
        <?php foreach ( $ranges as $h => $label ) : ?>
            <a class="<?php echo $h === $range_hours ? 'is-active' : ''; ?>"
               href="<?php echo esc_url( add_query_arg( array( 'page' => 'brainwerk-seo-suite', 'range' => $h ) ) ); ?>">
                <?php echo esc_html( $label ); ?>
            </a>
        <?php endforeach; ?>
    </div>
</div>

<div id="seoforge-dash-content" class="seoforge-dash-content">

<div class="seoforge-card">
    <ul class="seoforge-stats-grid">
        <li><strong><?php echo esc_html( number_format_i18n( $summary['visits'] ) ); ?></strong>
            <span><?php esc_html_e( 'Pageviews', 'brainwerk-seo-suite' ); ?></span></li>
        <li><strong><?php echo esc_html( number_format_i18n( $summary['unique_visitors'] ) ); ?></strong>
            <span><?php esc_html_e( 'Unique visitors', 'brainwerk-seo-suite' ); ?></span></li>
        <li><strong><?php echo esc_html( number_format_i18n( $summary['sessions'] ) ); ?></strong>
            <span><?php esc_html_e( 'Sessions', 'brainwerk-seo-suite' ); ?></span></li>
        <li><strong><?php echo esc_html( $summary['bounce_rate'] ); ?>%</strong>
            <span><?php esc_html_e( 'Bounce rate', 'brainwerk-seo-suite' ); ?></span></li>
        <li><strong><?php echo esc_html( gmdate( 'i:s', max( 0, (int) $summary['avg_duration'] ) ) ); ?></strong>
            <span><?php esc_html_e( 'Avg session', 'brainwerk-seo-suite' ); ?></span></li>
    </ul>
    <?php if ( ! empty( $kpi_bench ) ) : ?>
        <ul class="seoforge-bar-list seoforge-benchmark-list">
            <?php foreach ( $kpi_bench as $row ) :
                list( $label, $cmp ) = $row; ?>
                <li>
                    <span class="seoforge-bar-list-label"><?php echo esc_html( $label ); ?></span>
                    <span class="seoforge-bar-list-value"><?php echo esc_html( $position_labels[ $cmp['position'] ] ); ?></span>
                </li>
            <?php endforeach; ?>
        </ul>
        <p class="description"><?php
            printf(
                /* translators: %d: number of peer sites in the same industry cell */
                esc_html__( 'Compared with %d sites in your industry, via the SEO network.', 'brainwerk-seo-suite' ),
                (int) $bench_n
            );
        ?></p>
    <?php elseif ( $network_progress_msg ) : ?>
        <p class="description seoforge-network-progress"><?php echo esc_html( $network_progress_msg ); ?></p>
    <?php endif; ?>
</div>

<?php if ( $is_network ) : ?>
<?php if ( class_exists( 'Seoforge_License' ) && Seoforge_License::is_pro() ) : ?>
<div class="seoforge-card">
    <h2><?php esc_html_e( 'By site', 'brainwerk-seo-suite' ); ?> <?php echo Seoforge_License::pro_badge(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></h2>
    <table class="widefat striped">
        <thead><tr>
            <th><?php esc_html_e( 'Site', 'brainwerk-seo-suite' ); ?></th>
            <th><?php esc_html_e( 'Pageviews', 'brainwerk-seo-suite' ); ?></th>
            <th><?php esc_html_e( 'Unique visitors', 'brainwerk-seo-suite' ); ?></th>
            <th><?php esc_html_e( 'Sessions', 'brainwerk-seo-suite' ); ?></th>
            <th></th>
        </tr></thead>
        <tbody>
        <?php if ( empty( $by_blog ) ) : ?>
            <tr><td colspan="5"><?php esc_html_e( 'No data yet.', 'brainwerk-seo-suite' ); ?></td></tr>
        <?php else : foreach ( $by_blog as $b ) :
            $details   = get_blog_details( (int) $b['blog_id'] );
            $site_name = ( $details && $details->blogname ) ? $details->blogname : ( '#' . (int) $b['blog_id'] );
            $focus_url = add_query_arg(
                array( 'page' => 'brainwerk-seo-suite', 'tab' => 'dashboard', 'seoforge_site' => (int) $b['blog_id'] )
            );
            ?>
            <tr>
                <td><?php echo esc_html( $site_name ); ?></td>
                <td><?php echo esc_html( number_format_i18n( (int) $b['visits'] ) ); ?></td>
                <td><?php echo esc_html( number_format_i18n( (int) $b['unique_visitors'] ) ); ?></td>
                <td><?php echo esc_html( number_format_i18n( (int) $b['sessions'] ) ); ?></td>
                <td><a href="<?php echo esc_url( $focus_url ); ?>"><?php esc_html_e( 'View', 'brainwerk-seo-suite' ); ?> →</a></td>
            </tr>
        <?php endforeach; endif; ?>
        </tbody>
    </table>
</div>
<?php else : ?>
<?php echo Seoforge_Pro::upsell( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    __( 'Network-wide aggregate dashboard', 'brainwerk-seo-suite' ),
    __( 'See pageviews, unique visitors and sessions broken down by site across your whole network, with a one-click jump into each site. Single-site and per-site views stay free.', 'brainwerk-seo-suite' )
); ?>
<?php endif; ?>
<?php endif; ?>

<div class="seoforge-card">
    <h2><?php esc_html_e( 'Visits over time', 'brainwerk-seo-suite' ); ?></h2>
    <?php if ( empty( $daily ) ) : ?>
        <p class="seoforge-empty"><?php esc_html_e( 'No visits recorded yet.', 'brainwerk-seo-suite' ); ?></p>
    <?php else :
        $chart_points = array();
        foreach ( $daily as $d ) {
            $chart_points[] = array(
                'label' => substr( $d['bucket'], 5 ),                    // MM-DD
                'value' => (int) $d['visits'],
                /* translators: 1: date bucket, 2: visit count */
                'tip'   => sprintf( __( '%1$s · %2$s pageviews', 'brainwerk-seo-suite' ), $d['bucket'], number_format_i18n( (int) $d['visits'] ) ),
            );
        }
        // Inline SVG area chart. The markup is fully controlled here and every
        // dynamic value (labels, tooltips, coordinates) is esc_html'd / numeric
        // at build time, so the assembled string is output-safe. wp_kses is not
        // used because it lowercases camelCase SVG attributes (viewBox), which
        // breaks responsive scaling.
        echo '<div class="seoforge-chart-wrap">';
        echo Seoforge_Charts::area( $chart_points ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        echo '</div>';
    endif; ?>
</div>

<div class="seoforge-card-grid">
    <div class="seoforge-card">
        <h2><?php esc_html_e( 'Top pages', 'brainwerk-seo-suite' ); ?></h2>
        <table class="widefat striped">
            <thead><tr><th><?php esc_html_e( 'Page', 'brainwerk-seo-suite' ); ?></th><th><?php esc_html_e( 'Hits', 'brainwerk-seo-suite' ); ?></th><th><?php esc_html_e( 'Visitors', 'brainwerk-seo-suite' ); ?></th></tr></thead>
            <tbody>
            <?php if ( empty( $top_pages ) ) : ?>
                <tr><td colspan="3"><?php esc_html_e( 'No data yet.', 'brainwerk-seo-suite' ); ?></td></tr>
            <?php else : foreach ( $top_pages as $p ) : ?>
                <tr>
                    <td><a href="<?php echo esc_url( home_url( $p['url_path'] ) ); ?>" target="_blank">
                        <?php echo esc_html( $p['title'] ?: $p['url_path'] ); ?></a></td>
                    <td><?php echo esc_html( number_format_i18n( $p['hits'] ) ); ?></td>
                    <td><?php echo esc_html( number_format_i18n( $p['uniques'] ) ); ?></td>
                </tr>
            <?php endforeach; endif; ?>
            </tbody>
        </table>
    </div>

    <div class="seoforge-card">
        <h2><?php esc_html_e( 'Top sources', 'brainwerk-seo-suite' ); ?></h2>
        <table class="widefat striped">
            <thead><tr><th><?php esc_html_e( 'Type', 'brainwerk-seo-suite' ); ?></th><th><?php esc_html_e( 'Source', 'brainwerk-seo-suite' ); ?></th><th><?php esc_html_e( 'Hits', 'brainwerk-seo-suite' ); ?></th></tr></thead>
            <tbody>
            <?php if ( empty( $top_sources ) ) : ?>
                <tr><td colspan="3"><?php esc_html_e( 'No data yet.', 'brainwerk-seo-suite' ); ?></td></tr>
            <?php else : foreach ( $top_sources as $s ) :
                $sf_type_meta = Seoforge_Utils::source_type_meta( $s['source_type'] ); ?>
                <tr>
                    <td><span class="seoforge-pill seoforge-pill-<?php echo esc_attr( $s['source_type'] ); ?>">
                        <?php echo esc_html( $s['source_type'] ); ?></span>
                        <?php if ( $sf_type_meta['tip'] ) : ?>
                            <span class="seoforge-tip" tabindex="0" data-seoforge-tip="<?php echo esc_attr( $sf_type_meta['tip'] ); ?>">?</span>
                        <?php endif; ?>
                    </td>
                    <td><?php echo esc_html( $s['source_name'] ?: '—' ); ?></td>
                    <td><?php echo esc_html( number_format_i18n( $s['hits'] ) ); ?></td>
                </tr>
            <?php endforeach; endif; ?>
            </tbody>
        </table>
    </div>
</div>

<div class="seoforge-card">
    <h2><?php esc_html_e( 'Devices', 'brainwerk-seo-suite' ); ?></h2>
    <?php if ( empty( $device ) ) : ?>
        <p class="seoforge-empty"><?php esc_html_e( 'No data yet.', 'brainwerk-seo-suite' ); ?></p>
    <?php else :
        $total_dev = array_sum( array_column( $device, 'hits' ) ) ?: 1;
        ?>
        <ul class="seoforge-bar-list">
            <?php foreach ( $device as $d ) :
                $pct = round( ( (int) $d['hits'] / $total_dev ) * 100, 1 );
                ?>
                <li>
                    <span class="seoforge-bar-list-label"><?php echo esc_html( $d['label'] ?: __( 'unknown', 'brainwerk-seo-suite' ) ); ?></span>
                    <span class="seoforge-bar-list-track"><span style="width:<?php echo esc_attr( $pct ); ?>%"></span></span>
                    <span class="seoforge-bar-list-value"><?php echo esc_html( $pct ); ?>%</span>
                </li>
            <?php endforeach; ?>
        </ul>
    <?php endif; ?>
</div>

<?php if ( null !== $bots ) : ?>
<div class="seoforge-card">
    <h2><?php esc_html_e( 'Bot & AI-crawler traffic', 'brainwerk-seo-suite' ); ?></h2>
    <ul class="seoforge-bar-list">
        <li>
            <span class="seoforge-bar-list-label"><?php esc_html_e( 'Declared (known crawler)', 'brainwerk-seo-suite' ); ?></span>
            <span class="seoforge-bar-list-track"><span style="width:<?php echo (int) $bots['declared_pct']; ?>%"></span></span>
            <span class="seoforge-bar-list-value"><?php echo (int) $bots['declared_pct']; ?>%</span>
        </li>
        <li>
            <span class="seoforge-bar-list-label"><?php esc_html_e( 'Suspect (unidentified UA)', 'brainwerk-seo-suite' ); ?></span>
            <span class="seoforge-bar-list-track"><span style="width:<?php echo (int) $bots['suspect_pct']; ?>%"></span></span>
            <span class="seoforge-bar-list-value"><?php echo (int) $bots['suspect_pct']; ?>%</span>
        </li>
        <li>
            <span class="seoforge-bar-list-label"><?php esc_html_e( 'Cloaked (claims a family, behaves oddly)', 'brainwerk-seo-suite' ); ?></span>
            <span class="seoforge-bar-list-track"><span style="width:<?php echo (int) $bots['cloaked_pct']; ?>%"></span></span>
            <span class="seoforge-bar-list-value"><?php echo (int) $bots['cloaked_pct']; ?>%</span>
        </li>
    </ul>
    <?php if ( $bot_reputation ) : ?>
        <p class="description"><?php
            printf(
                /* translators: %d: percentage of bot hits that claim a known AI-crawler identity but don't behave like one, per the SEO network's pooled reputation data */
                esc_html__( '%d%% of visits claim to be a known AI crawler but don\'t behave like one, per the SEO network.', 'brainwerk-seo-suite' ),
                (int) $bots['cloaked_pct']
            );
        ?></p>
    <?php endif; ?>
</div>
<?php endif; ?>

<?php if ( ! empty( $analyzer_bench ) ) : ?>
<div class="seoforge-card">
    <h2><?php esc_html_e( 'Compared with your industry', 'brainwerk-seo-suite' ); ?></h2>
    <p class="description"><?php
        printf(
            /* translators: %d: number of peer sites in the same industry cell */
            esc_html__( 'Analyzer checks across %d sites in your industry, via the SEO network.', 'brainwerk-seo-suite' ),
            (int) $bench_n
        );
    ?></p>
    <ul class="seoforge-bar-list">
        <?php foreach ( $analyzer_bench as $cmp ) : ?>
            <li>
                <span class="seoforge-bar-list-label"><?php echo esc_html( $cmp['label'] ); ?></span>
                <span class="seoforge-bar-list-value"><?php
                    printf(
                        /* translators: 1: percentage of peer sites failing this check, 2: percentage this site fails it */
                        esc_html__( '%1$d%% of peer sites miss this — you\'re at %2$d%%.', 'brainwerk-seo-suite' ),
                        (int) round( $cmp['industry_fail_pct'] ),
                        (int) round( $cmp['own_fail_pct'] )
                    );
                ?></span>
            </li>
        <?php endforeach; ?>
    </ul>
</div>
<?php endif; ?>

<?php if ( ! $is_network && class_exists( 'Seoforge_History' ) ) : ?>
<h2 class="seoforge-eigen-heading"><?php esc_html_e( 'Compared with yourself', 'brainwerk-seo-suite' ); ?></h2>

<?php if ( 'empty' === $eigen_status ) : ?>
<div class="seoforge-card">
    <p class="description"><?php esc_html_e( 'The self-comparison starts once a few days of history exist — check back soon.', 'brainwerk-seo-suite' ); ?></p>
</div>
<?php else : ?>
<?php if ( 'partial' === $eigen_status ) : ?>
<p class="description seoforge-eigen-partial"><?php
    printf(
        /* translators: %d: comparison window size in days */
        esc_html__( 'Still filling up — comparing against a full %d-day window will become possible with more history.', 'brainwerk-seo-suite' ),
        (int) $eigen_window
    );
?></p>
<?php endif; ?>

<div class="seoforge-card">
    <h2><?php esc_html_e( 'Headline numbers, this month vs last', 'brainwerk-seo-suite' ); ?></h2>
    <ul class="seoforge-stats-grid seoforge-stats-grid-delta">
        <?php foreach ( $eigen_headline as $row ) : ?>
            <li>
                <strong><?php echo null !== $row['delta']['current']
                    ? esc_html( number_format_i18n( $row['delta']['current'], $row['decimals'] ) . $row['suffix'] )
                    : '—'; ?></strong>
                <span><?php echo esc_html( $row['label'] ); ?></span>
                <?php echo Seoforge_Charts::delta_badge( $row['delta'], array( 'suffix' => $row['suffix'] ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
            </li>
        <?php endforeach; ?>
    </ul>
</div>

<div class="seoforge-card">
    <h2><?php esc_html_e( 'Analyzer trend', 'brainwerk-seo-suite' ); ?></h2>
    <p class="description"><?php
        printf(
            /* translators: %d: comparison window size in days */
            esc_html__( 'Fail rate per check, now vs the %d days before — biggest problems and biggest improvements first.', 'brainwerk-seo-suite' ),
            (int) $eigen_window
        );
    ?></p>
    <ul class="seoforge-bar-list seoforge-eigen-analyzer">
        <?php foreach ( $eigen_analyzer as $row ) :
            $badge = Seoforge_Charts::delta_badge( $row['delta_fmt'], array( 'suffix' => 'pp' ) );
            ?>
            <li>
                <span class="seoforge-bar-list-label"><?php echo esc_html( $row['label'] ); ?></span>
                <span class="seoforge-bar-list-track"><span style="width:<?php echo esc_attr( null !== $row['current'] ? round( $row['current'] ) : 0 ); ?>%"></span></span>
                <span class="seoforge-bar-list-value">
                    <?php echo null !== $row['current'] ? esc_html( round( $row['current'] ) . '%' ) : '—'; ?>
                    <?php echo $badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
                </span>
            </li>
        <?php endforeach; ?>
    </ul>

    <h3 class="seoforge-eigen-subhead"><?php esc_html_e( 'Score distribution, now vs then', 'brainwerk-seo-suite' ); ?></h3>
    <div class="seoforge-legend">
        <span class="seoforge-legend-item"><span class="seoforge-legend-swatch is-now"></span><?php esc_html_e( 'Now', 'brainwerk-seo-suite' ); ?></span>
        <span class="seoforge-legend-item"><span class="seoforge-legend-swatch is-then"></span><?php
            printf(
                /* translators: %d: comparison window size in days */
                esc_html__( '%d days ago', 'brainwerk-seo-suite' ),
                (int) $eigen_window
            );
        ?></span>
    </div>
    <ul class="seoforge-bar-list seoforge-eigen-score-dist">
        <?php foreach ( $eigen_score as $row ) : ?>
            <li>
                <span class="seoforge-bar-list-label"><?php echo esc_html( $row['label'] ); ?></span>
                <span class="seoforge-bar-list-track seoforge-bar-list-track-double">
                    <span class="is-now" style="width:<?php echo esc_attr( null !== $row['current'] ? round( $row['current'] ) : 0 ); ?>%"></span>
                    <span class="is-then" style="width:<?php echo esc_attr( null !== $row['previous'] ? round( $row['previous'] ) : 0 ); ?>%"></span>
                </span>
                <span class="seoforge-bar-list-value"><?php echo null !== $row['current'] ? esc_html( round( $row['current'] ) . '%' ) : '—'; ?></span>
            </li>
        <?php endforeach; ?>
    </ul>
</div>

<div class="seoforge-card-grid">
    <div class="seoforge-card">
        <h2><?php esc_html_e( 'Traffic shape — hour of day', 'brainwerk-seo-suite' ); ?></h2>
        <?php if ( empty( $eigen_hours ) ) : ?>
            <p class="seoforge-empty"><?php esc_html_e( 'No traffic recorded yet.', 'brainwerk-seo-suite' ); ?></p>
        <?php else : ?>
            <div class="seoforge-chart-wrap">
                <?php echo Seoforge_Charts::bars( $eigen_hours, array( 'height' => 160 ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
            </div>
        <?php endif; ?>
    </div>
    <div class="seoforge-card">
        <h2><?php esc_html_e( 'Traffic shape — day of week', 'brainwerk-seo-suite' ); ?></h2>
        <?php if ( empty( $eigen_weekdays ) ) : ?>
            <p class="seoforge-empty"><?php esc_html_e( 'No traffic recorded yet.', 'brainwerk-seo-suite' ); ?></p>
        <?php else : ?>
            <div class="seoforge-chart-wrap">
                <?php echo Seoforge_Charts::bars( $eigen_weekdays, array( 'height' => 160 ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
            </div>
        <?php endif; ?>
    </div>
</div>

<div class="seoforge-card">
    <h2><?php esc_html_e( 'AI-crawler development', 'brainwerk-seo-suite' ); ?></h2>
    <?php if ( empty( $eigen_ai_families ) ) : ?>
        <p class="seoforge-empty"><?php esc_html_e( 'No AI-crawler traffic recorded yet.', 'brainwerk-seo-suite' ); ?></p>
    <?php else : ?>
        <ul class="seoforge-sparkline-list">
            <?php foreach ( $eigen_ai_families as $fam ) : ?>
                <li>
                    <span class="seoforge-sparkline-label"><?php echo esc_html( $fam['label'] ); ?></span>
                    <span class="seoforge-sparkline-chart"><?php echo Seoforge_Charts::sparkline( $fam['values'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
                    <span class="seoforge-sparkline-value"><?php echo Seoforge_Charts::delta_badge( $fam['delta'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
                </li>
            <?php endforeach; ?>
        </ul>
        <p class="description">
            <?php esc_html_e( 'Crawl-to-referral ratio (crawler hits per AI-referred visit), this month vs last:', 'brainwerk-seo-suite' ); ?>
            <?php echo Seoforge_Charts::delta_badge( $eigen_ai_ratio ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
        </p>
    <?php endif; ?>
</div>
<?php endif; ?>
<?php endif; ?>

</div><!-- #seoforge-dash-content -->
