<?php
declare(strict_types=1);

/** @var array{ok:?string,err:?string} $flash */
/** @var null|array{id:int,site_url:string,last_sync_at:?string} $activeProp */
/** @var null|array{clicks:int,impressions:int,ctr:float,position:float} $kpi */
/** @var null|array{clicks:int,impressions:int,ctr:float,position:float} $kpiPrev */
/** @var null|string $kpiStart */
/** @var null|string $kpiEnd */
/** @var null|string $kpiPrevStart */
/** @var null|string $kpiPrevEnd */
/** @var list<array{date:string,clicks:int,impressions:int,ctr:float,position:float}> $dailySeries */
/** @var null|string $dataAvailableThrough */
/** @var array{volatility_score:int,trend:string,moved_up:int,moved_down:int} $rankTrend */
/** @var bool $widgetsDeferred */
/** @var bool $trendDeferred */
/** @var bool $trafficDeferred */
/** @var null|array{min:string,max:string} $importedRange */
/** @var int $dashboardTrackedPreviewLimit */
/** @var bool $dashboardTrackedCompare */
/** @var list<array{query:string,clicks:int,impressions:int,prev_clicks:int,prev_impressions:int}> $dashboardTrackedKeywordsRows */
/** @var list<array{page:string,clicks:int,impressions:int,prev_clicks:int,prev_impressions:int}> $dashboardTrackedPagesRows */
/** @var array{ready:bool,seo_health:string,health_penalty_score:float,payload:array<string,mixed>} $seoAiAssistantInsight */
/** @var bool $seoAiAssistantAiReady */
/** @var bool $seoAiAssistantHasCachedInsight */
/** @var null|array{executive_summary:string,seo_interpretation:string,priority_recommendation:string,seo_health:string} $seoAiAssistantCachedBody */
/** @var bool $seoAiInsightsEnabled */
/** @var string $seoAiAssistantCsrf */

if (!isset($dashboardTrackedPreviewLimit) || !is_int($dashboardTrackedPreviewLimit)) {
    $dashboardTrackedPreviewLimit = 10;
}
if (!isset($dashboardTrackedCompare) || !is_bool($dashboardTrackedCompare)) {
    $dashboardTrackedCompare = false;
}
if (!isset($dashboardTrackedKeywordsRows) || !is_array($dashboardTrackedKeywordsRows)) {
    $dashboardTrackedKeywordsRows = [];
}
if (!isset($dashboardTrackedPagesRows) || !is_array($dashboardTrackedPagesRows)) {
    $dashboardTrackedPagesRows = [];
}
if (!isset($seoAiAssistantInsight) || !is_array($seoAiAssistantInsight)) {
    $seoAiAssistantInsight = [
        'ready' => false,
        'seo_health' => \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_WARNING,
        'health_penalty_score' => 0.0,
        'payload' => [
            'schema_version' => \SeoScope\Services\SeoAiAssistantPayloadService::SCHEMA_VERSION,
            'analytics_ready' => false,
            'seo_health_deterministic' => \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_WARNING,
        ],
    ];
}
if (!isset($seoAiAssistantAiReady) || !is_bool($seoAiAssistantAiReady)) {
    $seoAiAssistantAiReady = false;
}
if (!isset($seoAiAssistantHasCachedInsight) || !is_bool($seoAiAssistantHasCachedInsight)) {
    $seoAiAssistantHasCachedInsight = false;
}
if (!isset($seoAiInsightsEnabled) || !is_bool($seoAiInsightsEnabled)) {
    $seoAiInsightsEnabled = false;
}
if (!isset($seoAiAssistantCsrf) || !is_string($seoAiAssistantCsrf) || $seoAiAssistantCsrf === '') {
    $seoAiAssistantCsrf = \SeoScope\Auth\AdminCsrf::token();
}
if (!isset($seoAiAssistantCachedBody) || !is_array($seoAiAssistantCachedBody)) {
    $seoAiAssistantCachedBody = null;
}

$pageTitle = __('dashboard.page_title');
$pageHeading = __('dashboard.heading');
$activeNav = 'dashboard';
$u = \SeoScope\Auth\SessionAuth::user();
$name = is_array($u) ? trim((string) ($u['name'] ?? '')) : '';
if ($name === '' && is_array($u)) {
    $email = (string) ($u['email'] ?? '');
    $name = $email !== '' ? strtok($email, '@') : '';
}
$heroTitle = $name !== ''
    ? __('dashboard.hero.welcome_named', ['name' => $name])
    : __('dashboard.hero.welcome_guest');
$heroSubtitle = __('dashboard.hero.subtitle');
if (is_string($kpiStart) && $kpiStart !== '' && is_string($kpiEnd) && $kpiEnd !== '') {
    $heroMetaData = [
        'start' => $kpiStart,
        'end' => $kpiEnd,
        'prev_start' => null,
        'prev_end' => null,
    ];
    if (is_string($kpiPrevStart) && $kpiPrevStart !== '' && is_string($kpiPrevEnd) && $kpiPrevEnd !== '') {
        $heroMetaData['prev_start'] = $kpiPrevStart;
        $heroMetaData['prev_end'] = $kpiPrevEnd;
    }
}

$preset = is_array($globalFilters ?? null) ? (string) ($globalFilters['preset'] ?? 'last_28_days') : 'last_28_days';
$widgetsDeferred = isset($widgetsDeferred) ? (bool) $widgetsDeferred : false;
$trendDeferred = isset($trendDeferred) ? (bool) $trendDeferred : $widgetsDeferred;
$trafficDeferred = isset($trafficDeferred) ? (bool) $trafficDeferred : $widgetsDeferred;
$rangeLabel = match ($preset) {
    'last_7_days' => __('global.range_last_7'),
    'last_28_days' => __('global.range_last_28'),
    'last_3_months' => __('global.range_last_3'),
    'last_6_months' => __('global.range_last_6'),
    'last_12_months' => __('global.range_last_12'),
    'last_16_months' => __('global.range_last_16'),
    default => __('global.range_last_28'),
};
ob_start();
?>
<section class="mb-4">
    <div class="row g-4">
        <?php
        $kpis = [
            ['k' => 'clicks', 'icon' => 'fa-solid fa-mouse-pointer'],
            ['k' => 'impressions', 'icon' => 'fa-regular fa-eye'],
            ['k' => 'ctr', 'icon' => 'fa-solid fa-arrow-trend-up'],
            ['k' => 'position', 'icon' => 'fa-solid fa-location-dot'],
        ];
        $formatInt = static fn (int $n): string => number_format($n, 0, '.', ',');
        $formatCtr = static fn (float $n): string => number_format($n * 100, 2) . '%';
        $formatPos = static fn (float $n): string => number_format($n, 2);
        $formatDeltaPct = static fn (float $n): string => ($n >= 0 ? '+' : '') . number_format($n * 100, 1) . '%';
        $formatDeltaPos = static fn (float $n): string => ($n >= 0 ? '+' : '') . number_format($n, 2);
        foreach ($kpis as $it):
            $val = '—';
            $sub = __('dashboard.kpi_placeholder');
            $trendText = null;
            $trendClass = null;
            $showSubtext = true;
            if (is_array($kpi)) {
                if ($it['k'] === 'clicks') {
                    $val = $formatInt((int) $kpi['clicks']);
                } elseif ($it['k'] === 'impressions') {
                    $val = $formatInt((int) $kpi['impressions']);
                } elseif ($it['k'] === 'ctr') {
                    $val = $formatCtr((float) $kpi['ctr']);
                } elseif ($it['k'] === 'position') {
                    $val = $formatPos((float) $kpi['position']);
                }
                // Always show the selected preset label (Last 7 days, etc.).
                $sub = $rangeLabel;

                if (is_array($kpiPrev)) {
                    // When compare is enabled, show only the delta on the card.
                    $showSubtext = false;
                    $delta = 0.0;
                    $deltaIsPositive = true;
                    if ($it['k'] === 'clicks') {
                        $prev = (float) ($kpiPrev['clicks'] ?? 0);
                        $cur = (float) ($kpi['clicks'] ?? 0);
                        $delta = $prev > 0 ? (($cur - $prev) / $prev) : ($cur > 0 ? 1.0 : 0.0);
                        $deltaIsPositive = $delta >= 0;
                        $trendText = $formatDeltaPct($delta);
                    } elseif ($it['k'] === 'impressions') {
                        $prev = (float) ($kpiPrev['impressions'] ?? 0);
                        $cur = (float) ($kpi['impressions'] ?? 0);
                        $delta = $prev > 0 ? (($cur - $prev) / $prev) : ($cur > 0 ? 1.0 : 0.0);
                        $deltaIsPositive = $delta >= 0;
                        $trendText = $formatDeltaPct($delta);
                    } elseif ($it['k'] === 'ctr') {
                        $prev = (float) ($kpiPrev['ctr'] ?? 0);
                        $cur = (float) ($kpi['ctr'] ?? 0);
                        $delta = $prev > 0 ? (($cur - $prev) / $prev) : ($cur > 0 ? 1.0 : 0.0);
                        $deltaIsPositive = $delta >= 0;
                        $trendText = $formatDeltaPct($delta);
                    } elseif ($it['k'] === 'position') {
                        $prev = (float) ($kpiPrev['position'] ?? 0);
                        $cur = (float) ($kpi['position'] ?? 0);
                        $delta = $cur - $prev;
                        // For position: lower is better.
                        $deltaIsPositive = $delta <= 0;
                        $trendText = $formatDeltaPos($delta);
                    }
                    $trendClass = $deltaIsPositive ? 'positive' : 'negative';
                }
            }
        ?>
        <div class="col-12 col-md-6 col-xl-3">
            <div class="dashboard-card metric-card">
                <div class="d-flex justify-content-between align-items-start gap-3">
                    <div>
                        <div class="metric-label"><?= seoscope_h(__('dashboard.kpi.' . $it['k'])) ?></div>
                        <div class="metric-value"><?= seoscope_h($val) ?></div>
                        <div class="metric-footer">
                            <?php if ($showSubtext): ?>
                                <div class="metric-subtext">
                                    <?= seoscope_h($sub) ?>
                                </div>
                            <?php endif; ?>
                            <?php if (is_string($trendText) && $trendClass !== null): ?>
                                <?php $arrow = ($trendClass === 'positive') ? '↑' : '↓'; ?>
                                <div class="metric-trend <?= seoscope_h($trendClass) ?>"><?= seoscope_h($arrow . ' ' . $trendText) ?></div>
                            <?php endif; ?>
                        </div>
                    </div>
                    <div class="metric-icon"><i class="<?= seoscope_h($it['icon']) ?>"></i></div>
                </div>
            </div>
        </div>
        <?php endforeach; ?>
    </div>
</section>

<section>
    <?php
    $showChartTruncNote = is_array($activeProp) && !empty($dailySeries)
        && is_string($dataAvailableThrough ?? null) && $dataAvailableThrough !== ''
        && is_string($kpiEnd ?? null) && $kpiEnd !== '' && $kpiEnd > $dataAvailableThrough;
    $perfLastDayForTooltip = $showChartTruncNote
        ? seoscope_format_ui_long_date((string) $dataAvailableThrough)
        : '';
    ?>
    <div class="dashboard-card section-card">
        <div class="d-flex align-items-center justify-content-between flex-wrap gap-3 mb-2">
            <div>
                <div class="section-title mb-1 d-flex align-items-center flex-wrap gap-2">
                    <span><?= seoscope_h(__('dashboard.performance.title')) ?></span>
                    <?php if ($showChartTruncNote): ?>
                        <span
                            class="text-muted"
                            data-bs-toggle="tooltip"
                            data-bs-placement="top"
                            title="<?= seoscope_h(__('dashboard.chart.truncation_note', ['date' => $perfLastDayForTooltip])) ?>"
                        ><i class="fa-regular fa-circle-question" aria-hidden="true"></i></span>
                    <?php endif; ?>
                </div>
                <div class="section-subtitle mb-0">
                    <?php
                        $to = (is_string($dataAvailableThrough) && $dataAvailableThrough !== '') ? $dataAvailableThrough : (is_string($kpiEnd) ? $kpiEnd : '');
                        $from = is_string($kpiStart) ? $kpiStart : '';
                        $label = $rangeLabel;
                        if ($from !== '' && $to !== '') {
                            $label .= __('dashboard.performance.range_suffix', ['from' => $from, 'to' => $to]);
                        }
                    ?>
                    <?= seoscope_h($label) ?>
                </div>
            </div>
            <div class="ss-performance-controls" aria-label="<?= seoscope_h(__('dashboard.metrics_group_aria')) ?>">
                <div class="btn-group btn-group-sm" role="group">
                    <button type="button" class="btn btn-export-csv ss-metric-toggle active" data-metric="clicks"><?= seoscope_h(__('dashboard.kpi.clicks')) ?></button>
                    <button type="button" class="btn btn-export-csv ss-metric-toggle active" data-metric="impressions"><?= seoscope_h(__('dashboard.kpi.impressions')) ?></button>
                    <button type="button" class="btn btn-export-csv ss-metric-toggle" data-metric="ctr"><?= seoscope_h(__('dashboard.kpi.ctr')) ?></button>
                    <button type="button" class="btn btn-export-csv ss-metric-toggle" data-metric="position"><?= seoscope_h(__('dashboard.kpi.position')) ?></button>
                </div>
            </div>
        </div>

        <?php if (!is_array($activeProp)): ?>
            <div class="section-subtitle"><?= seoscope_h(__('dashboard.coming_soon')) ?></div>
        <?php elseif (empty($dailySeries)): ?>
            <div class="section-subtitle"><?= seoscope_h(__('dashboard.coming_soon')) ?></div>
        <?php else: ?>
            <div class="chart-area ss-performance-area" style="height: 320px;">
                <div class="chart-grid ss-performance-grid" aria-hidden="true">
                    <span></span><span></span><span></span><span></span><span></span>
                </div>
                <canvas id="ss-performance-chart" height="260" aria-label="<?= seoscope_h(__('dashboard.chart.aria')) ?>"></canvas>
            </div>
        <?php endif; ?>
    </div>
</section>

<?php if (!empty($seoAiInsightsEnabled)): ?>
<?php
$ssAiNoProperty = !is_array($activeProp) || empty($activeProp['id']);
$ssAiDaily = isset($dailySeries) && is_array($dailySeries) ? $dailySeries : [];
$ssAiNoSeries = !$ssAiNoProperty && $ssAiDaily === [];
$ssAiInsightReady = !empty($seoAiAssistantInsight['ready']);
$ssAiNotReady = !$ssAiNoProperty && !$ssAiNoSeries && !$ssAiInsightReady;
$ssAiConfigure = !$ssAiNoProperty && !$ssAiNoSeries && $ssAiInsightReady && !$seoAiAssistantAiReady;
$ssAiIdle = !$ssAiNoProperty && !$ssAiNoSeries && $ssAiInsightReady && $seoAiAssistantAiReady;
$ssAiSettingsAiUrl = seoscope_url('/settings?' . http_build_query(['tab' => 'ai']));
$ssAiShowCachedSuccess = $ssAiIdle && $seoAiAssistantCachedBody !== null;
$ssAiNl = static fn (string $s): string => nl2br(seoscope_h($s), false);
$ssAiHealthRaw = '';
if ($seoAiAssistantCachedBody !== null) {
    $ssAiHealthRaw = trim((string) ($seoAiAssistantCachedBody['seo_health'] ?? ''));
}
$ssAiHealthNorm = (string) ($seoAiAssistantInsight['seo_health'] ?? \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_WARNING);
if ($ssAiHealthRaw === \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_GOOD
    || $ssAiHealthRaw === \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_WARNING
    || $ssAiHealthRaw === \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_CRITICAL) {
    $ssAiHealthNorm = $ssAiHealthRaw;
}
$ssAiHealthBadgeClass = match ($ssAiHealthNorm) {
    \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_GOOD => 'bg-success',
    \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_CRITICAL => 'bg-danger',
    default => 'bg-warning text-dark',
};
$ssAiHealthBadgeLabel = match ($ssAiHealthNorm) {
    \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_GOOD => __('seo_ai.health.good'),
    \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_CRITICAL => __('seo_ai.health.critical'),
    default => __('seo_ai.health.warning'),
};
$ssAiHealthBadgeTitle = match ($ssAiHealthNorm) {
    \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_GOOD => __('seo_ai.health.tooltip_good'),
    \SeoScope\Services\SeoAiAssistantPayloadService::HEALTH_CRITICAL => __('seo_ai.health.tooltip_critical'),
    default => __('seo_ai.health.tooltip_warning'),
};
?>
<section class="mt-3">
    <div
        class="dashboard-card section-card ss-seo-ai-assistant-card"
        id="ss-seo-ai-assistant-card"
        aria-labelledby="ss-seo-ai-assistant-heading"
        data-ss-seo-ai-endpoint="<?= seoscope_h(seoscope_url('/dashboard/seo-ai-assistant')) ?>"
        data-ss-seo-ai-csrf="<?= seoscope_h($seoAiAssistantCsrf) ?>"
        data-ss-seo-ai-prefilled="<?= $ssAiShowCachedSuccess ? '1' : '0' ?>"
    >
        <div class="d-flex align-items-start justify-content-between flex-wrap gap-3 mb-3">
            <div>
                <div class="section-title mb-0" id="ss-seo-ai-assistant-heading">
                    <span><?= seoscope_h(__('seo_ai.card.title')) ?></span>
                </div>
                <p class="section-subtitle mb-0 mt-2"><?= seoscope_h(__('seo_ai.card.intro_hint')) ?></p>
            </div>
        </div>

        <div id="ss-seo-ai-state-no-property" class="section-subtitle mb-0<?= $ssAiNoProperty ? '' : ' d-none' ?>">
            <?= seoscope_h(__('seo_ai.card.state_no_property')) ?>
        </div>

        <div id="ss-seo-ai-state-no-series" class="section-subtitle mb-0<?= $ssAiNoSeries ? '' : ' d-none' ?>">
            <?= seoscope_h(__('dashboard.coming_soon')) ?>
        </div>

        <div id="ss-seo-ai-state-not-ready" class="section-subtitle mb-0<?= $ssAiNotReady ? '' : ' d-none' ?>">
            <?= seoscope_h(__('seo_ai.dashboard.not_ready')) ?>
        </div>

        <div id="ss-seo-ai-state-configure" class="<?= $ssAiConfigure ? '' : 'd-none' ?>">
            <p class="section-subtitle mb-2"><?= seoscope_h(__('seo_ai.card.configure_hint')) ?></p>
            <a class="btn btn-sm btn-outline-primary" href="<?= seoscope_h($ssAiSettingsAiUrl) ?>"><?= seoscope_h(__('seo_ai.card.open_settings_ai')) ?></a>
        </div>

        <div id="ss-seo-ai-state-idle" class="<?= $ssAiIdle ? '' : 'd-none' ?>">
            <div class="d-flex flex-wrap align-items-center gap-2">
                <button type="button" class="btn btn-sm ss-seo-ai-btn-generate" id="ss-seo-ai-btn-generate" disabled title="<?= seoscope_h(__('seo_ai.card.generate_tooltip')) ?>">
                    <?= seoscope_h(__('seo_ai.card.generate')) ?>
                </button>
                <span id="ss-seo-ai-regenerate-wrap" class="ms-2<?= $seoAiAssistantHasCachedInsight ? '' : ' d-none' ?>">
                    <button type="button" class="btn btn-sm btn-outline-secondary" id="ss-seo-ai-btn-regenerate" disabled title="<?= seoscope_h(__('seo_ai.card.regenerate_tooltip')) ?>">
                        <?= seoscope_h(__('seo_ai.card.regenerate')) ?>
                    </button>
                </span>
            </div>
        </div>

        <div id="ss-seo-ai-state-loading" class="d-none mt-2 text-muted" aria-live="polite">
            <div class="d-flex align-items-center gap-2">
                <div class="spinner-border spinner-border-sm text-primary" role="status" aria-hidden="true"></div>
                <span><?= seoscope_h(__('seo_ai.card.analyzing')) ?></span>
            </div>
        </div>

        <div id="ss-seo-ai-state-error" class="alert alert-danger mt-3 mb-0 py-2 small d-none" role="alert"></div>

        <div id="ss-seo-ai-state-success" class="<?= $ssAiShowCachedSuccess ? 'mt-3' : 'd-none mt-3' ?>" role="status" aria-live="polite">
            <div class="d-flex flex-wrap align-items-center gap-2 mb-3">
                <span class="small text-muted d-inline-flex align-items-center gap-1">
                    <?= seoscope_h(__('seo_ai.card.health_label')) ?>:
                    <span class="text-muted" data-bs-toggle="tooltip" data-bs-placement="top" title="<?= seoscope_h(__('seo_ai.card.health_tooltip')) ?>" role="img" aria-label="<?= seoscope_h(__('seo_ai.card.health_help_aria')) ?>">
                        <i class="fa-regular fa-circle-question" aria-hidden="true"></i>
                    </span>
                </span>
                <span id="ss-seo-ai-health-badge" class="badge rounded-pill <?= seoscope_h($ssAiHealthBadgeClass) ?>" data-ss-health="<?= seoscope_h($ssAiHealthNorm) ?>" title="<?= seoscope_h($ssAiHealthBadgeTitle) ?>"><?= seoscope_h($ssAiHealthBadgeLabel) ?></span>
            </div>
            <div class="mb-3">
                <div class="fw-semibold small text-uppercase text-muted mb-1"><?= seoscope_h(__('seo_ai.card.summary_heading')) ?></div>
                <div id="ss-seo-ai-out-summary" class="small"><?php
                    if ($seoAiAssistantCachedBody !== null) {
                        $t = trim((string) ($seoAiAssistantCachedBody['executive_summary'] ?? ''));
                        echo $t !== '' ? $ssAiNl($t) : '<span class="text-muted">—</span>';
                    }
                ?></div>
            </div>
            <div class="mb-3">
                <div class="fw-semibold small text-uppercase text-muted mb-1"><?= seoscope_h(__('seo_ai.card.insight_heading')) ?></div>
                <div id="ss-seo-ai-out-insight" class="small"><?php
                    if ($seoAiAssistantCachedBody !== null) {
                        $t = trim((string) ($seoAiAssistantCachedBody['seo_interpretation'] ?? ''));
                        echo $t !== '' ? $ssAiNl($t) : '<span class="text-muted">—</span>';
                    }
                ?></div>
            </div>
            <div class="mb-0">
                <div class="fw-semibold small text-uppercase text-muted mb-1"><?= seoscope_h(__('seo_ai.card.action_heading')) ?></div>
                <div id="ss-seo-ai-out-action" class="small"><?php
                    if ($seoAiAssistantCachedBody !== null) {
                        $t = trim((string) ($seoAiAssistantCachedBody['priority_recommendation'] ?? ''));
                        echo $t !== '' ? $ssAiNl($t) : '<span class="text-muted">—</span>';
                    }
                ?></div>
            </div>
        </div>
    </div>
</section>
<?php
$ssSeoAiJsCfg = [
    'healthGood' => __('seo_ai.health.good'),
    'healthWarning' => __('seo_ai.health.warning'),
    'healthCritical' => __('seo_ai.health.critical'),
    'healthTooltipGood' => __('seo_ai.health.tooltip_good'),
    'healthTooltipWarning' => __('seo_ai.health.tooltip_warning'),
    'healthTooltipCritical' => __('seo_ai.health.tooltip_critical'),
    'networkError' => __('seo_ai.card.network_error'),
    'badResponse' => __('seo_ai.card.bad_response'),
    'csrfFailed' => __('seo_ai.card.csrf_failed'),
];
?>
<script>
(function () {
  var wrap = document.getElementById('ss-seo-ai-regenerate-wrap');
  if (!wrap || wrap.classList.contains('d-none') === false) return;
  try {
    if (window.sessionStorage && window.sessionStorage.getItem('ss_seo_ai_has_result') === '1') {
      wrap.classList.remove('d-none');
    }
  } catch (e) {}
})();
(function (CFG) {
  var card = document.getElementById('ss-seo-ai-assistant-card');
  var idle = document.getElementById('ss-seo-ai-state-idle');
  var gen = document.getElementById('ss-seo-ai-btn-generate');
  var reg = document.getElementById('ss-seo-ai-btn-regenerate');
  var loading = document.getElementById('ss-seo-ai-state-loading');
  var errBox = document.getElementById('ss-seo-ai-state-error');
  var okBox = document.getElementById('ss-seo-ai-state-success');
  var badge = document.getElementById('ss-seo-ai-health-badge');
  var outSum = document.getElementById('ss-seo-ai-out-summary');
  var outIns = document.getElementById('ss-seo-ai-out-insight');
  var outAct = document.getElementById('ss-seo-ai-out-action');
  var wrap = document.getElementById('ss-seo-ai-regenerate-wrap');
  if (!card || !idle || idle.classList.contains('d-none')) return;

  var endpoint = card.getAttribute('data-ss-seo-ai-endpoint') || '';
  var csrf = card.getAttribute('data-ss-seo-ai-csrf') || '';
  if (!endpoint || !csrf) return;

  var inFlight = false;

  function escHtml(s) {
    var d = document.createElement('div');
    d.textContent = s;
    return d.innerHTML;
  }

  function formatBlock(s) {
    s = String(s || '').trim();
    if (!s) return '<span class="text-muted">—</span>';
    return escHtml(s).replace(/\r\n|\r|\n/g, '<br>');
  }

  function healthMeta(code) {
    var c = String(code || '');
    if (c === 'good') {
      return { key: 'good', cls: 'bg-success', label: CFG.healthGood, badgeTitle: CFG.healthTooltipGood };
    }
    if (c === 'critical') {
      return { key: 'critical', cls: 'bg-danger', label: CFG.healthCritical, badgeTitle: CFG.healthTooltipCritical };
    }
    return { key: 'warning', cls: 'bg-warning text-dark', label: CFG.healthWarning, badgeTitle: CFG.healthTooltipWarning };
  }

  function setLoading(on) {
    if (loading) loading.classList.toggle('d-none', !on);
    if (gen) gen.disabled = on;
    if (reg) reg.disabled = on;
  }

  function hideError() {
    if (!errBox) return;
    errBox.classList.add('d-none');
    errBox.textContent = '';
  }

  function showError(msg) {
    if (!errBox) return;
    errBox.textContent = String(msg || '');
    errBox.classList.remove('d-none');
  }

  function applySuccess(data) {
    hideError();
    var h = healthMeta(data.seo_health);
    if (badge) {
      badge.className = 'badge rounded-pill ' + h.cls;
      badge.setAttribute('data-ss-health', h.key);
      badge.textContent = h.label;
      badge.setAttribute('title', h.badgeTitle || '');
    }
    if (outSum) outSum.innerHTML = formatBlock(data.executive_summary);
    if (outIns) outIns.innerHTML = formatBlock(data.seo_interpretation);
    if (outAct) outAct.innerHTML = formatBlock(data.priority_recommendation);
    if (okBox) okBox.classList.remove('d-none');
    if (wrap) wrap.classList.remove('d-none');
    card.setAttribute('data-ss-seo-ai-prefilled', '1');
    try {
      if (window.sessionStorage) window.sessionStorage.setItem('ss_seo_ai_has_result', '1');
    } catch (e) {}
  }

  function run(regenerate) {
    if (inFlight || !endpoint || !csrf) return;
    inFlight = true;
    hideError();
    setLoading(true);

    var body = new URLSearchParams();
    body.set('_csrf', csrf);
    if (regenerate) body.set('regenerate', '1');

    // POST must carry the same global dashboard filters as the page URL; otherwise
    // resolveGlobalFilters() sees no ?prop=… and falls back to the first property (wrong cache/KPI).
    var postUrl = endpoint;
    try {
      var u = new URL(endpoint, window.location.origin);
      var cur = new URL(window.location.href);
      ['prop', 'range', 'compare', 'device', 'country'].forEach(function (k) {
        var v = cur.searchParams.get(k);
        if (v !== null && v !== '') u.searchParams.set(k, v);
      });
      postUrl = u.toString();
    } catch (e) {}

    fetch(postUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },
      body: body.toString(),
      credentials: 'same-origin',
    })
      .then(function (res) {
        var ct = (res.headers.get('content-type') || '').toLowerCase();
        return res.text().then(function (raw) {
          var data = null;
          if (ct.indexOf('application/json') !== -1) {
            try {
              data = JSON.parse(raw);
            } catch (e) {
              data = null;
            }
          }
          return { res: res, data: data, raw: raw };
        });
      })
      .then(function (pack) {
        var res = pack.res;
        var data = pack.data;
        if (res.status === 403 && !data) {
          showError(CFG.csrfFailed);
          return;
        }
        if (!data || typeof data !== 'object') {
          showError(CFG.badResponse);
          return;
        }
        if (!data.ok) {
          showError(typeof data.message === 'string' && data.message ? data.message : CFG.badResponse);
          return;
        }
        applySuccess(data);
      })
      .catch(function () {
        showError(CFG.networkError);
      })
      .finally(function () {
        inFlight = false;
        setLoading(false);
      });
  }

  if (gen) gen.disabled = false;
  if (reg) reg.disabled = false;
  if (gen) gen.addEventListener('click', function () { run(false); });
  if (reg) reg.addEventListener('click', function () { run(true); });
})(<?= json_encode($ssSeoAiJsCfg, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE) ?>);
<?php if ($ssAiShowCachedSuccess): ?>
(function () {
  try {
    if (window.sessionStorage) window.sessionStorage.setItem('ss_seo_ai_has_result', '1');
  } catch (e) {}
})();
<?php endif; ?>
</script>
<?php endif; ?>

<?php if (is_array($activeProp) && !empty($dailySeries)): ?>
<section class="mt-4">
    <?php if ($trendDeferred): ?>
        <div class="d-flex align-items-center justify-content-between gap-3 mb-2">
            <div class="text-muted small">
                <strong><?= seoscope_h(__('dashboard.widget.advanced')) ?></strong>: <?= seoscope_h(__('dashboard.widget.click')) ?>
                <a href="#" id="ss-compute-trend"><?= seoscope_h(__('dashboard.widget.compute')) ?></a> <?= seoscope_h(__('dashboard.widget.to_load')) ?>
            </div>
        </div>
    <?php endif; ?>
    <div class="row g-4">
        <?php
            $rt = is_array($rankTrend ?? null) ? $rankTrend : ['volatility_score' => 0, 'trend' => 'neutral', 'moved_up' => 0, 'moved_down' => 0];
            $vol = (int) ($rt['volatility_score'] ?? 0);
            $trend = (string) ($rt['trend'] ?? 'neutral');
            $up = (int) ($rt['moved_up'] ?? 0);
            $down = (int) ($rt['moved_down'] ?? 0);
            $trendLabel = $trend === 'positive'
                ? __('dashboard.trend.positive')
                : ($trend === 'negative' ? __('dashboard.trend.negative') : __('dashboard.trend.neutral'));
            $trendClass = $trend === 'positive' ? 'positive' : ($trend === 'negative' ? 'negative' : null);
        ?>
        <div class="col-12 col-md-6 col-xl-3">
            <div class="dashboard-card metric-card">
                <div class="d-flex justify-content-between align-items-start gap-3">
                    <div>
                        <div class="metric-label d-flex align-items-center gap-2">
                            <span><?= seoscope_h(__('dashboard.volatility.label')) ?></span>
                            <span class="text-muted" data-bs-toggle="tooltip" data-bs-placement="top" title="<?= seoscope_h(__('dashboard.volatility.tooltip')) ?>">
                                <i class="fa-regular fa-circle-question"></i>
                            </span>
                        </div>
                        <div class="metric-value" id="ss-vol-value"><?= !$trendDeferred ? seoscope_h((string) $vol) : '—' ?></div>
                        <div class="metric-footer">
                            <div class="metric-subtext"><?= seoscope_h(__('dashboard.compared_to_previous')) ?></div>
                        </div>
                    </div>
                    <div class="metric-icon"><i class="fa-solid fa-wave-square"></i></div>
                </div>
            </div>
            <?php
                $rng = is_array($importedRange ?? null) ? $importedRange : null;
                $rngMin = is_array($rng) ? (string) ($rng['min'] ?? '') : '';
                $rngMax = is_array($rng) ? (string) ($rng['max'] ?? '') : '';
                $from = is_string($kpiStart) ? $kpiStart : '';
                $to = (is_string($dataAvailableThrough) && $dataAvailableThrough !== '') ? $dataAvailableThrough : (is_string($kpiEnd) ? $kpiEnd : '');
                $showIncomplete = $rngMin !== '' && $from !== '' && $rngMin > $from;
            ?>
            <?php if ($showIncomplete): ?>
                <div class="small text-muted mt-2">
                    <?= seoscope_h(__('dashboard.backfill.note', ['min' => $rngMin, 'max' => $rngMax])) ?>
                </div>
            <?php endif; ?>
        </div>

        <div class="col-12 col-md-6 col-xl-3">
            <div class="dashboard-card metric-card">
                <div class="d-flex justify-content-between align-items-start gap-3">
                    <div>
                        <div class="metric-label d-flex align-items-center gap-2">
                            <span><?= seoscope_h(__('dashboard.trend_direction.label')) ?></span>
                            <span class="text-muted" data-bs-toggle="tooltip" data-bs-placement="top" title="<?= seoscope_h(__('dashboard.trend_direction.tooltip')) ?>">
                                <i class="fa-regular fa-circle-question"></i>
                            </span>
                        </div>
                        <div class="metric-value <?= (!$trendDeferred && $trendClass !== null) ? seoscope_h('text-' . ($trendClass === 'positive' ? 'success' : 'danger')) : '' ?>" id="ss-trend-value">
                            <?= !$trendDeferred ? seoscope_h($trendLabel) : '—' ?>
                        </div>
                        <div class="metric-footer">
                            <div class="metric-subtext"><?= seoscope_h(__('dashboard.compared_to_previous')) ?></div>
                        </div>
                    </div>
                    <div class="metric-icon"><i class="fa-solid fa-arrow-trend-up"></i></div>
                </div>
            </div>
        </div>

        <div class="col-12 col-md-6 col-xl-3">
            <div class="dashboard-card metric-card">
                <div class="d-flex justify-content-between align-items-start gap-3">
                    <div>
                        <div class="metric-label d-flex align-items-center gap-2">
                            <span><?= seoscope_h(__('dashboard.keywords_up.label')) ?></span>
                            <span class="text-muted" data-bs-toggle="tooltip" data-bs-placement="top" title="<?= seoscope_h(__('dashboard.keywords_up.tooltip')) ?>">
                                <i class="fa-regular fa-circle-question"></i>
                            </span>
                        </div>
                        <div class="metric-value text-success" id="ss-up-value"><?= !$trendDeferred ? seoscope_h(number_format($up, 0, '.', ',')) : '—' ?></div>
                        <div class="metric-footer">
                            <div class="metric-subtext"><?= seoscope_h(__('dashboard.compared_to_previous')) ?></div>
                        </div>
                    </div>
                    <div class="metric-icon"><i class="fa-solid fa-arrow-up"></i></div>
                </div>
            </div>
        </div>

        <div class="col-12 col-md-6 col-xl-3">
            <div class="dashboard-card metric-card">
                <div class="d-flex justify-content-between align-items-start gap-3">
                    <div>
                        <div class="metric-label d-flex align-items-center gap-2">
                            <span><?= seoscope_h(__('dashboard.keywords_down.label')) ?></span>
                            <span class="text-muted" data-bs-toggle="tooltip" data-bs-placement="top" title="<?= seoscope_h(__('dashboard.keywords_down.tooltip')) ?>">
                                <i class="fa-regular fa-circle-question"></i>
                            </span>
                        </div>
                        <div class="metric-value text-danger" id="ss-down-value"><?= !$trendDeferred ? seoscope_h(number_format($down, 0, '.', ',')) : '—' ?></div>
                        <div class="metric-footer">
                            <div class="metric-subtext"><?= seoscope_h(__('dashboard.compared_to_previous')) ?></div>
                        </div>
                    </div>
                    <div class="metric-icon"><i class="fa-solid fa-arrow-down"></i></div>
                </div>
            </div>
        </div>
    </div>
</section>

<section class="mt-4">
    <?php if ($trafficDeferred): ?>
        <div class="d-flex align-items-center justify-content-between gap-3 mb-2">
            <div class="text-muted small">
                <strong><?= seoscope_h(__('dashboard.widget.advanced')) ?></strong>: <?= seoscope_h(__('dashboard.widget.click')) ?>
                <a href="#" id="ss-compute-traffic"><?= seoscope_h(__('dashboard.widget.compute')) ?></a> <?= seoscope_h(__('dashboard.widget.to_load')) ?>
            </div>
        </div>
    <?php endif; ?>
    <div class="row g-4">
        <div class="col-12 col-xl-4">
            <div class="dashboard-card section-card">
                <div class="section-title mb-1"><?= seoscope_h(__('dashboard.traffic_device.title')) ?></div>
                <div class="section-subtitle mb-3"><?= seoscope_h(__('dashboard.traffic_device.subtitle')) ?></div>
                <?php if ($trafficDeferred): ?>
                    <div class="text-muted small" id="ss-device-placeholder">—</div>
                    <div class="d-none" id="ss-device-body">
                        <div class="d-flex flex-column align-items-center text-center gap-3">
                            <div style="width: 200px; height: 200px;">
                                <canvas id="ss-device-donut" width="200" height="200" aria-label="<?= seoscope_h(__('dashboard.traffic_device.aria')) ?>"></canvas>
                            </div>
                            <div class="small text-muted w-100" id="ss-device-legend"></div>
                        </div>
                    </div>
                <?php else: ?>
                    <div class="d-flex flex-column align-items-center text-center gap-3">
                        <div style="width: 200px; height: 200px;">
                            <canvas id="ss-device-donut" width="200" height="200" aria-label="<?= seoscope_h(__('dashboard.traffic_device.aria')) ?>"></canvas>
                        </div>
                        <div class="small text-muted w-100" id="ss-device-legend"></div>
                    </div>
                <?php endif; ?>
            </div>
        </div>

        <div class="col-12 col-xl-4">
            <div class="dashboard-card section-card">
                <div class="section-title mb-1"><?= seoscope_h(__('dashboard.traffic_location.title')) ?></div>
                <div class="section-subtitle mb-3"><?= seoscope_h(__('dashboard.traffic_location.subtitle')) ?></div>
                <?php if ($trafficDeferred): ?>
                    <div class="text-muted small" id="ss-location-placeholder">—</div>
                    <div class="d-none" id="ss-location-body">
                        <div class="table-wrap">
                            <div class="table-responsive">
                                <table class="crm-table">
                                    <thead>
                                        <tr>
                                            <th><?= seoscope_h(__('dashboard.traffic_location.col_location')) ?></th>
                                            <th class="text-end"><?= seoscope_h(__('dashboard.traffic_location.col_clicks')) ?></th>
                                            <th class="text-end"><?= seoscope_h(__('dashboard.traffic_location.col_share')) ?></th>
                                        </tr>
                                    </thead>
                                    <tbody id="ss-location-tbody"></tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                <?php else: ?>
                    <div class="table-wrap">
                        <div class="table-responsive">
                            <table class="crm-table">
                                <thead>
                                    <tr>
                                        <th><?= seoscope_h(__('dashboard.traffic_location.col_location')) ?></th>
                                        <th class="text-end"><?= seoscope_h(__('dashboard.traffic_location.col_clicks')) ?></th>
                                        <th class="text-end"><?= seoscope_h(__('dashboard.traffic_location.col_share')) ?></th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php if (empty($topCountries)): ?>
                                        <tr><td colspan="3" class="text-muted small"><?= seoscope_h(__('dashboard.empty.no_data')) ?></td></tr>
                                    <?php else: ?>
                                        <?php foreach ($topCountries as $r): ?>
                                            <?php if (!is_array($r)) continue; ?>
                                            <tr>
                                                <?php $cc = strtoupper((string) ($r['country'] ?? '')); ?>
                                                <td>
                                                    <span class="ss-flag" data-cc="<?= seoscope_h($cc) ?>" aria-hidden="true"></span>
                                                    <code><?= seoscope_h($cc) ?></code>
                                                </td>
                                                <td class="text-end"><?= seoscope_h(number_format((int) ($r['clicks'] ?? 0), 0, '.', ',')) ?></td>
                                                <td class="text-end"><?= seoscope_h(number_format(((float) ($r['share'] ?? 0)) * 100, 1)) ?>%</td>
                                            </tr>
                                        <?php endforeach; ?>
                                    <?php endif; ?>
                                </tbody>
                            </table>
                        </div>
                    </div>
                <?php endif; ?>
            </div>
        </div>

        <div class="col-12 col-xl-4">
            <div class="dashboard-card section-card">
                <div class="section-title mb-1"><?= seoscope_h(__('dashboard.kw_dist.title')) ?></div>
                <div class="section-subtitle mb-3"><?= seoscope_h(__('dashboard.kw_dist.subtitle')) ?></div>
                <?php if ($trafficDeferred): ?>
                    <div class="text-muted small" id="ss-kw-placeholder">—</div>
                    <div class="d-none" id="ss-kw-body">
                        <div class="d-flex flex-column align-items-center text-center gap-3">
                            <div style="width: 200px; height: 200px;">
                                <canvas id="ss-kw-donut" width="200" height="200" aria-label="<?= seoscope_h(__('dashboard.kw_dist.aria')) ?>"></canvas>
                            </div>
                            <div class="small text-muted w-100" id="ss-kw-legend"></div>
                        </div>
                    </div>
                <?php else: ?>
                    <div class="d-flex flex-column align-items-center text-center gap-3">
                        <div style="width: 200px; height: 200px;">
                            <canvas id="ss-kw-donut" width="200" height="200" aria-label="<?= seoscope_h(__('dashboard.kw_dist.aria')) ?>"></canvas>
                        </div>
                        <div class="small text-muted w-100" id="ss-kw-legend"></div>
                    </div>
                <?php endif; ?>
            </div>
        </div>
    </div>

    <?php
        $dashPropId = is_array($activeProp) ? (int) ($activeProp['id'] ?? 0) : 0;
        $dashRange = is_array($globalFilters ?? null) ? (string) ($globalFilters['preset'] ?? $preset) : $preset;
        $kwDashQs = ['range' => $dashRange];
        $pgDashQs = ['range' => $dashRange];
        if ($dashPropId > 0) {
            $kwDashQs['prop'] = (string) $dashPropId;
            $pgDashQs['prop'] = (string) $dashPropId;
        }
        if ($dashboardTrackedCompare) {
            $kwDashQs['compare'] = '1';
            $pgDashQs['compare'] = '1';
        }
        $kwReportUrl = seoscope_url('/keywords?' . http_build_query($kwDashQs));
        $pgReportUrl = seoscope_url('/pages?' . http_build_query($pgDashQs));
        $fmtDashInt = static fn (int $n): string => number_format($n, 0, '.', ',');
        $stripPageLabel = static function (string $fullUrl, ?array $activeProp): string {
            $fullUrl = trim($fullUrl);
            if ($fullUrl === '' || !is_array($activeProp)) {
                return $fullUrl;
            }
            $base = (string) ($activeProp['site_url'] ?? '');
            $base = rtrim($base, '/');
            if ($base === '') {
                return $fullUrl;
            }
            if (stripos($fullUrl, $base) === 0) {
                $rest = substr($fullUrl, strlen($base));

                return $rest !== '' ? $rest : '/';
            }
            $b = parse_url($base);
            $u = parse_url($fullUrl);
            $bHost = is_array($b) ? (string) ($b['host'] ?? '') : '';
            $uHost = is_array($u) ? (string) ($u['host'] ?? '') : '';
            if ($bHost !== '' && $uHost !== '' && strcasecmp($bHost, $uHost) === 0) {
                $path = is_array($u) ? (string) ($u['path'] ?? '') : '';
                $query = is_array($u) ? (string) ($u['query'] ?? '') : '';
                $out = ($path !== '' ? $path : '/');
                if ($query !== '') {
                    $out .= '?' . $query;
                }

                return $out;
            }

            return $fullUrl;
        };
    ?>
    <div class="row g-4 mt-4">
        <div class="col-12 col-md-6">
            <div class="dashboard-card section-card h-100">
                <div class="section-title mb-1"><?= seoscope_h(__('dashboard.tracked_keywords.title')) ?></div>
                <div class="section-subtitle mb-3"><?= seoscope_h(__('dashboard.tracked_keywords.subtitle')) ?></div>
                <?php if ($dashboardTrackedKeywordsRows === []): ?>
                    <p class="text-muted small mb-2 mb-md-0"><?= seoscope_h(__('dashboard.tracked_keywords.empty')) ?></p>
                    <a class="btn btn-sm btn-outline-secondary" href="<?= seoscope_h($kwReportUrl) ?>"><?= seoscope_h(__('dashboard.tracked_keywords.link_all')) ?></a>
                <?php else: ?>
                    <p class="text-muted small mb-2"><?= seoscope_h(__('dashboard.tracked_keywords.table_caption', ['max' => (string) $dashboardTrackedPreviewLimit])) ?></p>
                    <div class="table-wrap">
                        <div class="table-responsive">
                            <table class="crm-table">
                                <thead>
                                    <tr>
                                        <th><?= seoscope_h(__('dashboard.tracked_table.col_query')) ?></th>
                                        <th class="text-end"><?= seoscope_h(__('dashboard.tracked_table.col_clicks')) ?></th>
                                        <th class="text-end"><?= seoscope_h(__('dashboard.tracked_table.col_impressions')) ?></th>
                                        <?php if ($dashboardTrackedCompare): ?>
                                            <th class="text-end"><?= seoscope_h(__('keywords.col_delta_clicks')) ?></th>
                                            <th class="text-end"><?= seoscope_h(__('keywords.col_delta_impr')) ?></th>
                                        <?php endif; ?>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php foreach ($dashboardTrackedKeywordsRows as $kr): ?>
                                        <?php if (!is_array($kr)) {
                                            continue;
                                        } ?>
                                        <?php
                                            $krPc = (float) ($kr['prev_clicks'] ?? 0);
                                            $krPi = (float) ($kr['prev_impressions'] ?? 0);
                                            $krCc = (float) ($kr['clicks'] ?? 0);
                                            $krCi = (float) ($kr['impressions'] ?? 0);
                                            $krDc = $krPc > 0 ? (($krCc - $krPc) / $krPc) : ($krCc > 0 ? 1.0 : 0.0);
                                            $krDi = $krPi > 0 ? (($krCi - $krPi) / $krPi) : ($krCi > 0 ? 1.0 : 0.0);
                                        ?>
                                        <tr>
                                            <td class="small"><?= seoscope_h((string) ($kr['query'] ?? '')) ?></td>
                                            <td class="text-end small"><?= seoscope_h($fmtDashInt((int) ($kr['clicks'] ?? 0))) ?></td>
                                            <td class="text-end small"><?= seoscope_h($fmtDashInt((int) ($kr['impressions'] ?? 0))) ?></td>
                                            <?php if ($dashboardTrackedCompare): ?>
                                                <td class="text-end small <?= $krDc >= 0 ? 'text-success' : 'text-danger' ?>"><?= seoscope_h($formatDeltaPct($krDc)) ?></td>
                                                <td class="text-end small <?= $krDi >= 0 ? 'text-success' : 'text-danger' ?>"><?= seoscope_h($formatDeltaPct($krDi)) ?></td>
                                            <?php endif; ?>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        </div>
                    </div>
                <?php endif; ?>
            </div>
        </div>
        <div class="col-12 col-md-6">
            <div class="dashboard-card section-card h-100">
                <div class="section-title mb-1"><?= seoscope_h(__('dashboard.tracked_pages.title')) ?></div>
                <div class="section-subtitle mb-3"><?= seoscope_h(__('dashboard.tracked_pages.subtitle')) ?></div>
                <?php if ($dashboardTrackedPagesRows === []): ?>
                    <p class="text-muted small mb-2 mb-md-0"><?= seoscope_h(__('dashboard.tracked_pages.empty')) ?></p>
                    <a class="btn btn-sm btn-outline-secondary" href="<?= seoscope_h($pgReportUrl) ?>"><?= seoscope_h(__('dashboard.tracked_pages.link_all')) ?></a>
                <?php else: ?>
                    <p class="text-muted small mb-2"><?= seoscope_h(__('dashboard.tracked_pages.table_caption', ['max' => (string) $dashboardTrackedPreviewLimit])) ?></p>
                    <div class="table-wrap">
                        <div class="table-responsive">
                            <table class="crm-table">
                                <thead>
                                    <tr>
                                        <th><?= seoscope_h(__('dashboard.tracked_table.col_page')) ?></th>
                                        <th class="text-end"><?= seoscope_h(__('dashboard.tracked_table.col_clicks')) ?></th>
                                        <th class="text-end"><?= seoscope_h(__('dashboard.tracked_table.col_impressions')) ?></th>
                                        <?php if ($dashboardTrackedCompare): ?>
                                            <th class="text-end"><?= seoscope_h(__('pages.col_delta_clicks')) ?></th>
                                            <th class="text-end"><?= seoscope_h(__('pages.col_delta_impr')) ?></th>
                                        <?php endif; ?>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php foreach ($dashboardTrackedPagesRows as $pr): ?>
                                        <?php if (!is_array($pr)) {
                                            continue;
                                        } ?>
                                        <?php
                                            $pFull = (string) ($pr['page'] ?? '');
                                            $pDisp = $stripPageLabel($pFull, is_array($activeProp) ? $activeProp : null);
                                        ?>
                                        <?php
                                            $prPc = (float) ($pr['prev_clicks'] ?? 0);
                                            $prPi = (float) ($pr['prev_impressions'] ?? 0);
                                            $prCc = (float) ($pr['clicks'] ?? 0);
                                            $prCi = (float) ($pr['impressions'] ?? 0);
                                            $prDc = $prPc > 0 ? (($prCc - $prPc) / $prPc) : ($prCc > 0 ? 1.0 : 0.0);
                                            $prDi = $prPi > 0 ? (($prCi - $prPi) / $prPi) : ($prCi > 0 ? 1.0 : 0.0);
                                        ?>
                                        <tr>
                                            <td class="small">
                                                <a href="<?= seoscope_h($pFull) ?>" target="_blank" rel="noopener noreferrer"><?= seoscope_h($pDisp) ?></a>
                                            </td>
                                            <td class="text-end small"><?= seoscope_h($fmtDashInt((int) ($pr['clicks'] ?? 0))) ?></td>
                                            <td class="text-end small"><?= seoscope_h($fmtDashInt((int) ($pr['impressions'] ?? 0))) ?></td>
                                            <?php if ($dashboardTrackedCompare): ?>
                                                <td class="text-end small <?= $prDc >= 0 ? 'text-success' : 'text-danger' ?>"><?= seoscope_h($formatDeltaPct($prDc)) ?></td>
                                                <td class="text-end small <?= $prDi >= 0 ? 'text-success' : 'text-danger' ?>"><?= seoscope_h($formatDeltaPct($prDi)) ?></td>
                                            <?php endif; ?>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        </div>
                    </div>
                <?php endif; ?>
            </div>
        </div>
    </div>
</section>

<?php endif; ?>

<?php if (is_array($activeProp) && !empty($dailySeries)):
    $dashboardScriptI18n = [
        'chart' => [
            'clicks' => __('dashboard.kpi.clicks'),
            'impressions' => __('dashboard.kpi.impressions'),
            'ctr' => __('dashboard.chart.dataset.ctr'),
            'position' => __('dashboard.kpi.position'),
        ],
        'trend' => [
            'positive' => __('dashboard.trend.positive'),
            'negative' => __('dashboard.trend.negative'),
            'neutral' => __('dashboard.trend.neutral'),
        ],
        'deviceLabels' => [
            __('global.device_mobile'),
            __('global.device_desktop'),
            __('global.device_tablet'),
        ],
        'btn' => [
            'computing' => __('dashboard.js.computing'),
            'retry' => __('dashboard.js.retry'),
            'compute' => __('dashboard.widget.compute'),
        ],
        'noData' => __('dashboard.empty.no_data'),
    ];
    ?>
<script src="<?= seoscope_h(seoscope_url('/assets/extensions/chart.js/chart.umd.js')) ?>"></script>
<script>
(() => {
  const T = <?= json_encode($dashboardScriptI18n, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
  if (!window.Chart) return;
  const el = document.getElementById('ss-performance-chart');
  if (!el) return;

  // Server sends one point per calendar day in [range start..end] (gaps = zeros).
  // For UX, we still stop the chart at the last day that has any data, otherwise trailing
  // zeros look like a sudden drop/error when sync hasn't reached "today" yet.
  const rawAll = <?= json_encode($dailySeries, JSON_UNESCAPED_SLASHES) ?>;
  const lastDataIdx = (() => {
    for (let i = rawAll.length - 1; i >= 0; i--) {
      const r = rawAll[i] || {};
      const clicks = Number(r.clicks || 0);
      const impr = Number(r.impressions || 0);
      if (clicks > 0 || impr > 0) return i;
    }
    return rawAll.length - 1;
  })();
  const raw = rawAll.slice(0, Math.max(0, lastDataIdx + 1));
  const labels = raw.map(r => r.date);
  const xIdx = labels.map((_, i) => i);

  const colors = {
    clicks: { line: '#0f766e', fill: 'rgba(15,118,110,0.10)' },
    impressions: { line: '#2563eb', fill: 'rgba(37,99,235,0.08)' },
    ctr: { line: '#7c3aed', fill: 'rgba(124,58,237,0.06)' },
    position: { line: '#f59e0b', fill: 'rgba(245,158,11,0.06)' },
  };

  const dsY = {
    clicks: raw.map(r => (r.clicks || 0)),
    impressions: raw.map(r => (r.impressions || 0)),
    ctr: raw.map(r => (Math.round((Number(r.ctr || 0) * 100) * 100) / 100)), // percent
    position: raw.map(r => (Math.round((Number(r.position || 0)) * 100) / 100)),
  };

  const ds = {
    clicks: xIdx.map((x, i) => ({ x, y: dsY.clicks[i] })),
    impressions: xIdx.map((x, i) => ({ x, y: dsY.impressions[i] })),
    ctr: xIdx.map((x, i) => ({ x, y: dsY.ctr[i] })),
    position: xIdx.map((x, i) => ({ x, y: dsY.position[i] })),
  };

  const ctrVals = dsY.ctr.filter(v => typeof v === 'number' && isFinite(v));
  const ctrMaxRaw = ctrVals.length ? Math.max(...ctrVals) : 0;
  const ctrMax = Math.max(2, Math.ceil(ctrMaxRaw * 1.25 * 100) / 100); // add headroom

  const make = (key, label, yAxisID, hidden) => ({
    label,
    data: ds[key],
    borderColor: colors[key].line,
    backgroundColor: colors[key].fill,
    tension: 0.35,
    pointRadius: 0,
    borderWidth: 3,
    borderCapStyle: 'round',
    borderJoinStyle: 'round',
    fill: true,
    yAxisID,
    hidden,
    parsing: false,
  });

  const chart = new Chart(el.getContext('2d'), {
    type: 'line',
    data: {
      datasets: [
        make('clicks', T.chart.clicks, 'y', false),
        make('impressions', T.chart.impressions, 'y_impr', false),
        make('ctr', T.chart.ctr, 'y_ctr', true),
        make('position', T.chart.position, 'y_pos', true),
      ]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      layout: { padding: { left: 0 } },
      interaction: { mode: 'index', intersect: false },
      plugins: {
        legend: { display: false },
        tooltip: {
          callbacks: {
            title: (items) => {
              if (!items || !items.length) return '';
              const x = items[0].parsed.x;
              return labels[x] || '';
            },
            label: (ctx) => `${ctx.dataset.label}: ${ctx.parsed.y}`,
          }
        }
      },
      scales: {
        x: {
          type: 'linear',
          min: 0,
          max: Math.max(0, labels.length - 1),
          grid: { display: false },
          border: { display: false },
          offset: false,
          ticks: {
            maxRotation: 0,
            autoSkip: true,
            maxTicksLimit: 8,
            padding: 0,
            callback: (v) => labels[Number(v)] || '',
          },
        },
        y: {
          position: 'left',
          display: false,
          grid: { display: false, drawTicks: false },
          border: { display: false },
          ticks: { display: false },
        },
        y_impr: {
          position: 'right',
          grid: { drawOnChartArea: false, drawTicks: false },
          border: { display: false },
          ticks: { display: false },
        },
        y_ctr: {
          position: 'right',
          grid: { drawOnChartArea: false, drawTicks: false },
          border: { display: false },
          ticks: { display: false },
          min: 0,
          max: ctrMax,
        },
        y_pos: {
          position: 'right',
          grid: { drawOnChartArea: false, drawTicks: false },
          border: { display: false },
          ticks: { display: false },
          reverse: true,
        },
      }
    }
  });

  // Mobile: reduce remaining left gutter by nudging X bounds slightly.
  // (Chart.js keeps some internal padding even when axes are hidden.)
  try {
    const isMobile = window.matchMedia && window.matchMedia('(max-width: 576px)').matches;
    if (isMobile) {
      const maxX = Math.max(0, labels.length - 1);
      chart.options.scales.x.min = -0.2;
      chart.options.scales.x.max = maxX + 0.2;
      chart.update();
    }
  } catch (e) {}

  const toggles = document.querySelectorAll('.ss-metric-toggle');
  toggles.forEach(btn => {
    btn.addEventListener('click', () => {
      const key = btn.getAttribute('data-metric');
      if (!key) return;
      const idx = { clicks: 0, impressions: 1, ctr: 2, position: 3 }[key];
      const d = chart.data.datasets[idx];
      d.hidden = !d.hidden;
      btn.classList.toggle('active', !d.hidden);
      chart.update();
    });
  });

  const makeDonutLegend = (el, labels, values, colors) => {
    if (!el) return;
    const total = values.reduce((a, b) => a + b, 0) || 0;
    el.innerHTML = labels.map((lab, i) => {
      const v = values[i] || 0;
      const pct = total > 0 ? ((v / total) * 100) : 0;
      return `<div class="d-flex align-items-center justify-content-between gap-3 mb-2">
        <div class="d-flex align-items-center gap-2">
          <span class="dot" style="background:${colors[i]};"></span>
          <span>${lab}</span>
        </div>
        <div style="font-weight:700;">${pct.toFixed(1)}%</div>
      </div>`;
    }).join('');
  };

  // Country flag helper (emoji flags from ISO-3166-1 alpha-2).
  const iso3To2 = {
    ITA: 'IT', DEU: 'DE', FRA: 'FR', ESP: 'ES', GBR: 'GB', IRL: 'IE', NLD: 'NL', BEL: 'BE',
    CHE: 'CH', AUT: 'AT', PRT: 'PT', SWE: 'SE', NOR: 'NO', DNK: 'DK', FIN: 'FI', POL: 'PL',
    CZE: 'CZ', SVK: 'SK', HUN: 'HU', ROU: 'RO', BGR: 'BG', GRC: 'GR', HRV: 'HR', SVN: 'SI',
    SRB: 'RS', UKR: 'UA', RUS: 'RU', TUR: 'TR', ISR: 'IL', SAU: 'SA', ARE: 'AE', EGY: 'EG',
    MAR: 'MA', DZA: 'DZ', TUN: 'TN', ZAF: 'ZA', NGA: 'NG', KEN: 'KE',
    USA: 'US', CAN: 'CA', MEX: 'MX', BRA: 'BR', ARG: 'AR', CHL: 'CL', COL: 'CO', PER: 'PE',
    AUS: 'AU', NZL: 'NZ', IND: 'IN', PAK: 'PK', BGD: 'BD', LKA: 'LK',
    CHN: 'CN', JPN: 'JP', KOR: 'KR', HKG: 'HK', TWN: 'TW', SGP: 'SG', MYS: 'MY', THA: 'TH',
    IDN: 'ID', VNM: 'VN', PHL: 'PH',
  };

  const flagEmoji = (cc) => {
    if (!cc || typeof cc !== 'string') return '';
    const raw = cc.trim().toUpperCase();
    const s = /^[A-Z]{3}$/.test(raw) ? (iso3To2[raw] || '') : raw;
    if (!/^[A-Z]{2}$/.test(s)) return '';
    const A = 0x1F1E6;
    return String.fromCodePoint(A + (s.charCodeAt(0) - 65), A + (s.charCodeAt(1) - 65));
  };
  document.querySelectorAll('.ss-flag[data-cc]').forEach(el => {
    const cc = el.getAttribute('data-cc') || '';
    const f = flagEmoji(cc);
    if (f) {
      el.textContent = f;
      el.style.marginRight = '8px';
    }
  });

  const isTrendDeferred = <?= !empty($trendDeferred) ? 'true' : 'false' ?>;
  const isTrafficDeferred = <?= !empty($trafficDeferred) ? 'true' : 'false' ?>;

  const fmtInt = (n) => {
    const x = Number(n || 0);
    return x.toLocaleString('en-US');
  };

  const setBtnState = (btn, state) => {
    if (!btn) return;
    if (state === 'loading') {
      btn.disabled = true;
      btn.textContent = T.btn.computing;
    } else if (state === 'error') {
      btn.disabled = false;
      btn.textContent = T.btn.retry;
    } else {
      btn.disabled = false;
      btn.textContent = T.btn.compute;
    }
  };

  const renderDeviceDonut = (deviceRaw) => {
    const deviceLabels = T.deviceLabels;
    const deviceKeys = ['mobile', 'desktop', 'tablet'];
    const deviceVals = deviceKeys.map(k => Math.max(0, Number((deviceRaw || {})[k] || 0)));
    const deviceColors = ['#0f766e', '#f59e0b', '#7c3aed'];
    const deviceEl = document.getElementById('ss-device-donut');
    if (!deviceEl) return;
    new Chart(deviceEl.getContext('2d'), {
      type: 'doughnut',
      data: { labels: deviceLabels, datasets: [{ data: deviceVals, backgroundColor: deviceColors, borderWidth: 0 }] },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        cutout: '68%',
        plugins: { legend: { display: false }, tooltip: { callbacks: { label: (ctx) => `${ctx.label}: ${ctx.parsed}` } } },
      }
    });
    makeDonutLegend(document.getElementById('ss-device-legend'), deviceLabels, deviceVals, deviceColors);
  };

  const renderKeywordsDonut = (dist) => {
    dist = dist || {};
    const kwLabels = ['TOP 3', 'TOP 10', 'TOP 50', 'TOP 100'];
    const top3 = Number(dist.top3 || 0);
    const top10 = Math.max(0, Number(dist.top10 || 0) - top3);
    const top50 = Math.max(0, Number(dist.top50 || 0) - Number(dist.top10 || 0));
    const top100 = Math.max(0, Number(dist.top100 || 0) - Number(dist.top50 || 0));
    const kwVals = [top3, top10, top50, top100];
    const kwColors = ['#ea580c', '#f59e0b', '#fed7aa', '#0f766e'];
    const kwEl = document.getElementById('ss-kw-donut');
    if (!kwEl) return;
    new Chart(kwEl.getContext('2d'), {
      type: 'doughnut',
      data: { labels: kwLabels, datasets: [{ data: kwVals, backgroundColor: kwColors, borderWidth: 0 }] },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        cutout: '68%',
        plugins: { legend: { display: false }, tooltip: { callbacks: { label: (ctx) => `${ctx.label}: ${ctx.parsed}` } } },
      }
    });
    makeDonutLegend(document.getElementById('ss-kw-legend'), kwLabels, kwVals, kwColors);
  };

  const renderLocationsTable = (rows) => {
    const tbody = document.getElementById('ss-location-tbody');
    if (!tbody) return;
    rows = Array.isArray(rows) ? rows : [];
    if (!rows.length) {
      tbody.textContent = '';
      const r = tbody.insertRow();
      const c = r.insertCell();
      c.colSpan = 3;
      c.className = 'text-muted small';
      c.textContent = T.noData || '—';
      return;
    }
    tbody.innerHTML = rows.map(r => {
      const cc = String((r || {}).country || '').toUpperCase();
      const clicks = fmtInt((r || {}).clicks || 0);
      const share = Number((r || {}).share || 0);
      const pct = (share * 100).toFixed(1) + '%';
      const flag = flagEmoji(cc);
      return `<tr>
        <td>${flag ? `<span class=\"ss-flag\" aria-hidden=\"true\">${flag}</span>` : ''}<code>${cc || '—'}</code></td>
        <td class=\"text-end\">${clicks}</td>
        <td class=\"text-end\">${pct}</td>
      </tr>`;
    }).join('');
  };

  const fetchGroup = async (group) => {
    const url = new URL(<?= json_encode(seoscope_url('/dashboard/widgets')) ?>, window.location.origin);
    url.searchParams.set('group', group);
    // Preserve current filter query string (prop/range/compare etc.)
    const cur = new URL(window.location.href);
    ['prop', 'range', 'compare', 'device', 'country'].forEach(k => {
      const v = cur.searchParams.get(k);
      if (v) url.searchParams.set(k, v);
    });
    const res = await fetch(url.toString(), { credentials: 'same-origin' });
    return await res.json();
  };

  const computeTrend = async (ev) => {
    if (ev && typeof ev.preventDefault === 'function') ev.preventDefault();
    const btn = document.getElementById('ss-compute-trend');
    setBtnState(btn, 'loading');
    try {
      const data = await fetchGroup('trend');
      if (!data || !data.ok) throw new Error((data && data.error) || 'failed');
      const rt = (data.payload || {}).rankTrend || {};
      const vol = Number(rt.volatility_score || 0);
      const trend = String(rt.trend || 'neutral');
      const up = Number(rt.moved_up || 0);
      const down = Number(rt.moved_down || 0);

      const volEl = document.getElementById('ss-vol-value');
      if (volEl) volEl.textContent = String(vol);

      const trendEl = document.getElementById('ss-trend-value');
      if (trendEl) {
        trendEl.textContent = trend === 'positive' ? T.trend.positive : (trend === 'negative' ? T.trend.negative : T.trend.neutral);
        trendEl.classList.remove('text-success', 'text-danger');
        if (trend === 'positive') trendEl.classList.add('text-success');
        if (trend === 'negative') trendEl.classList.add('text-danger');
      }

      const upEl = document.getElementById('ss-up-value');
      if (upEl) upEl.textContent = fmtInt(up);

      const downEl = document.getElementById('ss-down-value');
      if (downEl) downEl.textContent = fmtInt(down);

      setBtnState(btn, 'idle');
      btn.disabled = true;
    } catch (e) {
      setBtnState(btn, 'error');
    }
  };

  const computeTraffic = async (ev) => {
    if (ev && typeof ev.preventDefault === 'function') ev.preventDefault();
    const btn = document.getElementById('ss-compute-traffic');
    setBtnState(btn, 'loading');
    try {
      const data = await fetchGroup('traffic');
      if (!data || !data.ok) throw new Error((data && data.error) || 'failed');
      const p = data.payload || {};

      const devPh = document.getElementById('ss-device-placeholder');
      const devBody = document.getElementById('ss-device-body');
      if (devPh) devPh.classList.add('d-none');
      if (devBody) devBody.classList.remove('d-none');
      renderDeviceDonut(p.deviceClicks || {});

      const locPh = document.getElementById('ss-location-placeholder');
      const locBody = document.getElementById('ss-location-body');
      if (locPh) locPh.classList.add('d-none');
      if (locBody) locBody.classList.remove('d-none');
      renderLocationsTable(p.topCountries || []);

      const kwPh = document.getElementById('ss-kw-placeholder');
      const kwBody = document.getElementById('ss-kw-body');
      if (kwPh) kwPh.classList.add('d-none');
      if (kwBody) kwBody.classList.remove('d-none');
      renderKeywordsDonut(p.kwDist || {});

      setBtnState(btn, 'idle');
      btn.disabled = true;
    } catch (e) {
      setBtnState(btn, 'error');
    }
  };

  if (!isTrafficDeferred) {
    // Render immediately for short ranges (server already provided data).
    const deviceRaw = <?= json_encode($deviceClicks ?? [], JSON_UNESCAPED_SLASHES) ?>;
    const dist = <?= json_encode($kwDist ?? ['top3'=>0,'top10'=>0,'top50'=>0,'top100'=>0,'total'=>0], JSON_UNESCAPED_SLASHES) ?>;
    renderDeviceDonut(deviceRaw);
    renderKeywordsDonut(dist);
  } else {
    const btnTraffic = document.getElementById('ss-compute-traffic');
    if (btnTraffic) btnTraffic.addEventListener('click', computeTraffic);
  }

  if (isTrendDeferred) {
    const btnTrend = document.getElementById('ss-compute-trend');
    if (btnTrend) btnTrend.addEventListener('click', computeTrend);
  }
})();
</script>
<?php endif; ?>
<?php
$content = ob_get_clean();
require __DIR__ . '/layout_admin.php';
