HEX
Server: Apache
System: Linux 244.240.109.208.host.secureserver.net 5.14.0-611.11.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Dec 3 09:47:37 EST 2025 x86_64
User: icsla (1002)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: /home/icsla/public_html/wp-content/plugins/link-whisper/templates/report_dashboard.php
<div class="wrap wpil-report-page wpil_styles">
<?php
    // Error report codes
    $codes = Wpil_Dashboard::getAllErrorCodes();
    $codes = (!empty($codes)) ? '&codes=' . implode(',', $codes) : '';

    // Loading state used by wizard banners
    $loading = (isset($_GET['loading']) && !empty($_GET['loading']));

    // Stats
    $posts_crawled       = (int) Wpil_Dashboard::getPostCount();
    $orphanedCount       = (int) Wpil_Dashboard::getOrphanedPostsCount();
    $brokenLinksCount    = (int) Wpil_Dashboard::getBrokenLinksCount();
    $notfoundLinksCount  = (int) Wpil_Dashboard::get404LinksCount(); // not used in template yet

    // Link coverage percent
    $link_density = Wpil_Dashboard::get_percent_of_posts_hitting_link_targets();
    $link_coverage_percent = !empty($link_density['percent']) ? (float) $link_density['percent'] : 0.0;

    // Click stats
    $summary   = Wpil_Dashboard::get_click_traffic_stats();
    $clicks_30 = isset($summary['clicks_30']) ? (int) $summary['clicks_30'] : 0;
    $clicks_old = isset($summary['clicks_old']) ? (int) $summary['clicks_old'] : 0;

    $difference = $clicks_30 - $clicks_old;
    $percent_change = $clicks_old != 0
        ? round(($difference / $clicks_old) * 100, 2)
        : ($clicks_30 > 0 ? 100 : 0);

    $is_positive = ($difference >= 0);

    // External focus
    $external_link_emphasis = Wpil_Dashboard::get_external_link_distribution(1);
    $external_link_emphasis_percent = 0.0;
    if(!empty($external_link_emphasis) && isset($external_link_emphasis[0]->representation)){
        $external_link_emphasis_percent = (float) (round($external_link_emphasis[0]->representation, 2) * 100);
    }

    // Anchor length score (your old flow uses total/filtered)
    $anchor_word_counts = Wpil_Dashboard::getAnchorPostCounts();
    $anchor_length_percent = null;
    if(!empty($anchor_word_counts['total']) && !empty($anchor_word_counts['filtered'])){
        $anchor_length_percent = (float) (round($anchor_word_counts['filtered'] / $anchor_word_counts['total'], 2) * 100);
    }

    // Internal & External links
    $internal_links = Wpil_Dashboard::getInternalLinksCount();
    $external_links = Wpil_Dashboard::getExternalLinksCount();

    $internal_percent = round((($internal_links > 0) ? $internal_links / ($external_links + $internal_links): 0) * 100);
    $external_percent = round((($external_links > 0) ? $external_links / ($external_links + $internal_links): 0) * 100);

    // Link Quality Score
    $link_relatedness = Wpil_Dashboard::get_related_link_percentage();

    $relatedness_dash = max(0, min(100, $link_relatedness));
    $relatedness_dash_str = number_format($relatedness_dash, 0) . ', 100';

    // Links inserted
    $links_inserted = Wpil_Dashboard::get_tracked_link_insert_count();

    // Small helper: status badge classes
    function wpil_dash_badge($type, $value){
        $value = (float) $value;

        if($type === 'coverage'){
            if($value >= 80) return ['Good', 'bg-green-50 text-green-600'];
            if($value >= 60) return ['OK', 'bg-orange-50 text-orange-600'];
            return ['Needs Attention', 'bg-red-50 text-red-600'];
        }

        if($type === 'countup'){
            if($value >= 1) return ['Great Job!', 'bg-green-50 text-green-600'];
            if($value >= 0) return ['Getting Started', 'bg-orange-50 text-orange-600'];
            return ['Needs Attention', 'bg-red-50 text-red-600'];
        }

        // counts (orphaned, broken)
        if((int)$value <= 0){
            return ['Good', 'bg-green-50 text-green-600'];
        }

        return ['Needs Attention', 'bg-red-50 text-red-600'];
    }

    // Circular gauge for coverage card
    // Uses 36x36 circle path style like your HTML mockup
    $coverage_dash = max(0, min(100, $link_coverage_percent));
    $coverage_dash_str = number_format($coverage_dash, 0) . ', 100';

    // Existing outbound icon used in old action buttons. Keep if you want later.
    $link_icon = '<svg width="24" height="24" style="position: absolute; margin: 1px 0px 0 3px; height: 12px; width: 12px; fill: #ffffff; stroke: #ffffff; display:inline-block;" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(0.046875,0,0,0.046875,0.0234375,0.02343964)"><path d="M 473.563,227.063 407.5,161 262.75,305.75 c -25,25 -49.563,41 -74.5,16 -25,-25 -9,-49.5 16,-74.5 L 349,102.5 283.937,37.406 c -14.188,-14.188 -2,-37.906 19,-37.906 h 170.625 c 20.938,0 37.938,16.969 37.938,37.906 v 170.688 c 0,20.937 -23.687,33.187 -37.937,18.969 z M 63.5,447.5 h 320 V 259.313 l 64,64 V 447.5 c 0,35.375 -28.625,64 -64,64 h -320 c -35.375,0 -64,-28.625 -64,-64 v -320 c 0,-35.344 28.625,-64 64,-64 h 124.188 l 64,64 H 63.5 Z"></path></g></svg>';

    // Badges
    $coverage_badge = wpil_dash_badge('coverage', $link_coverage_percent);
    $orphan_badge   = wpil_dash_badge('count', $orphanedCount);
    $broken_badge   = wpil_dash_badge('count', $brokenLinksCount);
    $insert_badge   = wpil_dash_badge('countup', $links_inserted);

    // Tooltip markup is still WPIL custom, keep styles minimal and rely on existing plugin CSS

    // Site Health Score
    $health_metrics = [
        'posts_crawled'            => $posts_crawled,
        'broken_links'             => $brokenLinksCount,
        'orphaned_posts'           => $orphanedCount,
        'link_coverage_percent'    => $link_coverage_percent,
        'link_relatedness_percent' => $link_relatedness,
        'external_site_focus'      => $external_link_emphasis_percent,
    ];

    $health = Wpil_Dashboard::wpil_dash_site_health_score($health_metrics);
    $health_meta = Wpil_Dashboard::wpil_dash_site_health_meta($health['score']);
    $health_hint = Wpil_Dashboard::wpil_dash_site_health_hint($health);

    // Circle math for the SVG ring
    $health_radius = 40;
    $health_circumference = 2 * M_PI * $health_radius; // 251.2 ish
    $health_progress = max(0, min(100, (int) $health['score']));
    $health_dasharray = $health_circumference;
    $health_dashoffset = $health_circumference * (1 - ($health_progress / 100));

    // Recommended Actions
    // 1) URLs (match keys used by your generator)
    $admin_urls = [
        'broken_links'       => htmlspecialchars(admin_url('admin.php?page=link_whisper&type=error' . $codes)),
        'orphaned_posts'     => admin_url('admin.php?page=link_whisper&type=links&orphaned=1'),
        'link_density'       => admin_url('admin.php?page=link_whisper&type=links&link_density=1'),
        'link_relation'      => admin_url('admin.php?page=link_whisper&type=links&link_relation=1'),
        'domains_report'     => admin_url('admin.php?page=link_whisper&type=domains'),
        'anchor_suggestions' => '', // wire later
    ];

    // 2) Metrics
    $action_metrics = [
        'broken_links'            => $brokenLinksCount,
        'orphaned_posts'          => $orphanedCount,
        'anchor_length_percent'   => $anchor_length_percent,          // can be null
        'link_coverage_percent'   => $link_coverage_percent,
        'link_relatedness_percent'=> $link_relatedness,
        'external_site_focus'     => $external_link_emphasis_percent, // <-- you already compute this above
        'admin_urls'              => $admin_urls,
    ];

    // 3) Generate actions
    $recommended_actions = Wpil_Dashboard::wpil_dash_generate_recommended_actions($action_metrics);

    // 4) Serious count (enabled CTAs only)
    $serious = Wpil_Dashboard::wpil_dash_count_serious_actions($recommended_actions);

    // generate hints for the health report!
    $hint = Wpil_Dashboard::wpil_dash_health_hint_payload($health, $recommended_actions, $admin_urls);
    $hint_text = !empty($hint['text']) ? $hint['text'] : '';
    $hint_target = !empty($hint['target_action_id']) ? $hint['target_action_id'] : '';
    $hint_url = !empty($hint['fallback_url']) ? $hint['fallback_url'] : '#';
    $hint_key = !empty($health['top_drag']['key']) ? (string) $health['top_drag']['key'] : '';
    $hint_stat_map = [
        'broken_links'  => 'wpil-stat-broken-links',
        'orphaned_posts'=> 'wpil-stat-orphaned-posts',
        'link_coverage' => 'wpil-stat-link-coverage',
        'link_quality'  => 'wpil-stat-link-quality',
        'external_focus'=> 'wpil-stat-external-links',
    ];
    $hint_stat_id = (!empty($hint_key) && isset($hint_stat_map[$hint_key])) ? $hint_stat_map[$hint_key] : '';

?>

<script>
    document.addEventListener('click', function(e) {
    var el = e.target.closest('[data-wpil-hint-action-id]');
    if (!el) return;

    var actionId = el.getAttribute('data-wpil-hint-action-id');
    var statId = el.getAttribute('data-wpil-hint-stat-id');

    var target = null;
    if (actionId) {
        target = document.getElementById('wpil-action-' + actionId);
    }
    if (!target && statId) {
        target = document.getElementById(statId);
    }
    if (!target) return; // no target, let normal link behavior happen

    e.preventDefault();

    target.scrollIntoView({ behavior: 'smooth', block: 'center' });

    // highlight
    target.classList.add('wpil-health-highlight');
    window.setTimeout(function() {
        target.classList.remove('wpil-health-highlight');
    }, 1800);
    });
</script>
<style>
    /* Keep brand helpers from your mock */
    .lw-gradient-bg { background: linear-gradient(90deg, #7F5AF0 0%, #2C6BFF 100%); }
    .lw-text-gradient { background: linear-gradient(90deg, #7F5AF0 0%, #2C6BFF 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }

    @keyframes fillBar { from { width: 0%; } }
    .animate-fill { animation: fillBar 1.5s ease-out forwards; }

    .wpil-health-highlight{
        box-shadow: 0 0 0 3px rgba(127, 90, 240, 0.35);
        border-color: rgba(127, 90, 240, 0.65) !important;
        transition: box-shadow 150ms ease, border-color 150ms ease;
    }

    .wpil-fix-progress-wrap{
        display: inline-flex;
        align-items: center;
        gap: 6px;
        margin-left: 10px;
        vertical-align: middle;
        font-size: 11px;
        font-weight: 700;
        color: #2563eb;
    }
    .wpil-fix-progress-wrap.is-complete{
        color: #16a34a;
    }
    .wpil-fix-progress-ring{
        width: 16px;
        height: 16px;
        border-radius: 999px;
        background:
            conic-gradient(#3b82f6 var(--wpil-fix-progress, 0%), #e5e7eb 0);
        position: relative;
        display: inline-block;
    }
    .wpil-fix-progress-ring::after{
        content: '';
        position: absolute;
        inset: 3px;
        border-radius: 999px;
        background: #fff;
    }
    .wpil-fix-progress-link{
        cursor: pointer;
    }
</style>

<h1 class="wp-heading-inline wpil-is-tooltipped wpil-no-overlay wpil-no-scale" <?php echo Wpil_Toolbox::generate_tooltip_text('dashboard-intro'); ?>>Dashboard</h1>
<hr class="wp-header-end">

<div id="poststuff">
  <div id="post-body" class="metabox-holder">
    <div id="post-body-content" class="relative">

      <?php //include_once 'report_tabs_dashboard.php'; ?>

      <?php if($loading){ ?>
        <input type="hidden" class="wpil-wizard-loading-dashboard" value="1">
        <input type="hidden" class="wpil-wizard-inserting-autolinks" value="<?php echo get_option('wpil_wizard_import_autolink_rules', 0); ?>">
        <input type="hidden" class="wpil-wizard-loading-dashboard-nonce" value="<?php echo wp_create_nonce($user->ID . 'wpil_dashboard_loading_nonce'); ?>">

        <div class="syns_div wpil_report_need_prepare wpil-report-download-banner wpil-is-tooltipped wpil-no-scale" <?php echo Wpil_Toolbox::generate_tooltip_text('dashboard-report-loading-bar'); ?>>
          <div class="progress_panel relative">
            <div class="wpil-dashboard-processing-status absolute z-10 w-full">
              <div class="wpil-report-download-banner-process">
                <i class="dashicons dashicons-clock" style="width:40px;height:40px;color:#fff;margin:10px;font-size:40px;"></i>
                <span class="wpil-dashboard-processing-message" style="margin-left:5px; padding:18px 0 !important; position:absolute; font-size:20px; color:#fff;">Scanning Site</span>
              </div>
              <div class="wpil-report-download-banner-remaining-time" style="margin-left:5px; padding:18px 0 !important; position:absolute; font-size:20px; color:#fff; right:15px; top:0;">
                <span class="wpil-dashboard-processing-time-remaining" style="margin-right:10px;">Calculating Time Remaining</span>
                <span class="wpil-dashboard-processing-clock">--:--:--</span>
              </div>
            </div>
            <div class="progress_count" style="background-color:#2da7fd"><span class="wpil-loading-status"></span></div>
          </div>
        </div>

        <div class="syns_div wpil_report_need_prepare wpil-report-autolink-insert-banner wpil-is-tooltipped wpil-no-scale" style="display:none;" <?php echo Wpil_Toolbox::generate_tooltip_text('dashboard-report-loading-bar'); ?>>
          <div class="progress_panel relative">
            <div class="wpil-dashboard-processing-status absolute z-10 w-full">
              <div class="wpil-report-autolink-insert-process">
                <i class="dashicons dashicons-admin-links" style="width:40px;height:40px;color:#fff;margin:10px;font-size:40px;"></i>
                <span class="wpil-dashboard-processing-message" style="margin-left:5px; padding:18px 0 !important; position:absolute; font-size:20px; color:#fff;">Creating Links!</span>
              </div>
              <div class="wpil-report-autolink-insert-remaining-time" style="margin-left:5px; padding:18px 0 !important; position:absolute; font-size:20px; color:#fff; right:15px; top:0;">
                <span style="margin-right:10px;">Links Created:</span>
                <span class="wpil-dashboard-processing-autolinks-inserted">0</span>
              </div>
            </div>
            <div class="progress_count" style="width:100%; background-color:#b63ef8;"><span class="wpil-loading-status"></span></div>
          </div>
        </div>
      <?php } ?>

      <!-- Dashboard container -->
      <div class="mx-auto space-y-8 mt-4">

        <!-- Header -->
        <div class="flex flex-col md:flex-row md:items-center justify-between gap-4" style="display:none">
          <div>
            <h2 class="text-3xl font-bold text-gray-900">Dashboard</h2>
            <p class="text-gray-500 text-sm mt-1">Overview of your site's internal linking structure.</p>
          </div>

          <div class="flex items-center space-x-4 justify-end">
            <div class="hidden md:flex flex-col items-end mr-2">
              <span class="text-xs font-bold text-gray-400 uppercase">AI Credits</span>
              <span class="text-sm font-bold text-[#7F5AF0]">
                <!--TO-IMPLEMENT: show real AI credits available -->
                <?php echo (int) number_format($credits); ?> Available
              </span>
            </div>

            <a style="display:none;" href="<?php echo admin_url('admin.php?page=link_whisper&type=links'); ?>"
               class="bg-white border border-gray-200 text-gray-700 font-medium px-4 py-2.5 rounded-xl shadow-sm hover:bg-gray-50 transition-colors flex items-center">
              <span>Reports</span>
              <!--TO-IMPLEMENT: if you want a dropdown, replace this with a menu -->
            </a>

            <a href="<?php echo admin_url('admin.php?page=link_whisper'); ?>"
               class="lw-gradient-bg text-white font-bold px-6 py-2.5 rounded-xl shadow-lg hover:shadow-xl hover:opacity-95 transition-all flex items-center">
              <span>Run New Scan</span>
              <!--TO-IMPLEMENT: wire to scan start action (wizard kickoff) -->
            </a>
          </div>
        </div>
        <div class="mx-auto space-y-8 mt-4">
            <!-- Tabs -->
            <div class="border-b flex justify-between border-gray-200">
                <nav class="-mb-px flex space-x-8" aria-label="Tabs">
                    <a href="<?php echo admin_url('admin.php?page=link_whisper'); ?>"
                    class="border-[#7F5AF0] text-[#7F5AF0] whitespace-nowrap py-4 px-1 border-b-2 font-bold text-sm">Dashboard</a>

                    <a href="<?php echo admin_url('admin.php?page=link_whisper&type=links'); ?>"
                    class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">Links Report</a>

                    <a href="<?php echo admin_url('admin.php?page=link_whisper&type=domains'); ?>"
                    class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">Domains Report</a>

                    <a href="<?php echo admin_url('admin.php?page=link_whisper&type=clicks'); ?>"
                    class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">Clicks Report</a>

                    <a href="<?php echo htmlspecialchars(admin_url('admin.php?page=link_whisper&type=error' . $codes)); ?>"
                    class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">Broken Links Report</a>
                
                    <a href="<?php echo admin_url('admin.php?page=link_whisper&type=sitemaps'); ?>"
                    class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">Visual Sitemaps</a>
                </nav>
                <div class="flex items-center space-x-4 justify-end">
                    <div class="hidden md:flex flex-col items-end mr-2">
                        <span class="text-xs font-bold text-gray-400 uppercase">AI Credits</span>
                        <span class="text-sm font-bold text-[#7F5AF0]">
                            <!--TO-IMPLEMENT: show real AI credits available -->
                            <?php echo number_format($credits); ?> Available
                        </span>
                    </div>
                    <a href="<?php echo admin_url('admin.php?page=link_whisper'); ?>"
                    class="lw-gradient-bg text-white font-bold px-6 py-2.5 rounded-xl shadow-lg hover:shadow-xl hover:opacity-95 transition-all flex items-center">
                    <span>Run Link Scan</span>
                    <!--TO-IMPLEMENT: wire to scan start action (wizard kickoff) -->
                    </a>
                </div>
            </div>
        </div>

        <!-- Stat cards -->
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">

          <!-- Posts Crawled -->
          <a href="<?php echo admin_url('admin.php?page=link_whisper&type=links'); ?>" target="_blank"
             class="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 flex flex-col justify-between h-32 relative overflow-hidden group hover:border-purple-200 transition-colors">
            <div class="absolute right-0 top-0 w-24 h-24 bg-purple-50 rounded-full -mr-8 -mt-8 opacity-50 group-hover:scale-110 transition-transform"></div>
            <h3 class="text-sm font-bold text-gray-400 uppercase tracking-wide z-10">Posts Crawled</h3>
            <div class="flex items-end justify-between z-10">
              <span class="text-4xl font-extrabold text-gray-900 wpil-report-stats-posts-crawled"><?php echo $posts_crawled; ?></span>
            </div>
          </a>

          <!-- Link Coverage -->
          <a href="<?php echo admin_url('admin.php?page=link_whisper&type=links&link_density=1'); ?>" target="_blank" id="wpil-stat-link-coverage"
             class="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 flex flex-col justify-between h-32 relative overflow-hidden group hover:border-blue-200 transition-colors">
            <h3 class="text-sm font-bold text-gray-400 uppercase tracking-wide z-10 flex items-center gap-2">
              Link Coverage

              <span class="wpil-report-header-container cust-tooltipdash relative">
                <span
                  class="dashicons dashicons-editor-help wpil-tippy-tooltipped"
                  data-wpil-tooltip-placement="top"
                  data-wpil-tooltip-allowhtml="1"
                  data-wpil-tooltip-content="Link Coverage tells you how many pages are receiving internal links.<br><br>Recommended: at least 1 inbound internal link and 3 outbound internal links.">
                </span>
              </span>
            </h3>

            <div class="flex items-end justify-between z-10">
              <span class="text-4xl font-extrabold text-gray-900 wpil-report-stats-link-coverage">
                <?php echo rtrim(rtrim(number_format($link_coverage_percent, 2), '0'), '.'); ?>%
              </span>

              <div class="w-12 h-12 relative">
                <svg viewBox="0 0 36 36" class="w-12 h-12 transform -rotate-90">
                  <path class="text-gray-100"
                        d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
                        fill="none" stroke="currentColor" stroke-width="4" />
                  <path class="<?php echo ($link_coverage_percent >= 60 ? 'text-orange-400' : 'text-red-400'); ?>"
                        stroke-dasharray="<?php echo esc_attr($coverage_dash_str); ?>"
                        d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
                        fill="none" stroke="currentColor" stroke-width="4" />
                </svg>
              </div>
            </div>
          </a>

          <!-- Orphaned Posts -->
          <a href="<?php echo admin_url('admin.php?page=link_whisper&type=links&orphaned=1'); ?>" target="_blank" id="wpil-stat-orphaned-posts"
             class="bg-white rounded-2xl p-6 shadow-sm border <?php echo ($orphanedCount > 0) ? 'border-red-100' : 'border-gray-100'; ?> flex flex-col justify-between h-32 relative overflow-hidden">
            <div class="absolute right-0 top-0 w-24 h-24 <?php echo ($orphanedCount > 0) ? 'bg-red-50' : 'bg-gray-50'; ?> rounded-full -mr-8 -mt-8 opacity-50"></div>
            <h3 class="text-sm font-bold <?php echo ($orphanedCount > 0) ? 'text-red-400' : 'text-gray-400'; ?> uppercase tracking-wide z-10 flex items-center">
              Orphaned Posts
              <?php if($orphanedCount > 0){ ?>
                <span class="ml-2 w-2 h-2 bg-red-500 rounded-full animate-pulse"></span>
              <?php } ?>
            </h3>
            <div class="flex items-end justify-between z-10">
              <?php if($loading){ ?>
                <span class="text-4xl font-extrabold text-gray-900">
                  <span class="wpil-report-dashboard-loading la-ball-clip-rotate la-mid inline-block align-middle">
                    <span style="border-color: black; border-bottom-color: transparent;"></span>
                  </span>
                </span>
              <?php } else { ?>
                <span class="text-4xl font-extrabold text-gray-900"><?php echo $orphanedCount; ?></span>
              <?php } ?>
              <span class="text-xs font-bold px-2 py-1 rounded-lg <?php echo esc_attr($orphan_badge[1]); ?>">
                <?php echo esc_html($orphan_badge[0]); ?>
              </span>
            </div>
          </a>

          <!-- Broken Links -->
          <a href="<?php echo htmlspecialchars(admin_url('admin.php?page=link_whisper&type=error' . $codes)); ?>" target="_blank" id="wpil-stat-broken-links"
             class="bg-white rounded-2xl p-6 shadow-sm border <?php echo ($brokenLinksCount > 0) ? 'border-orange-100' : 'border-gray-100'; ?> flex flex-col justify-between h-32 relative overflow-hidden">
            <div class="absolute right-0 top-0 w-24 h-24 <?php echo ($brokenLinksCount > 0) ? 'bg-orange-50' : 'bg-gray-50'; ?> rounded-full -mr-8 -mt-8 opacity-50"></div>
            <h3 class="text-sm font-bold <?php echo ($brokenLinksCount > 0) ? 'text-orange-400' : 'text-gray-400'; ?> uppercase tracking-wide z-10 flex items-center">
              Broken Links
              <?php if($brokenLinksCount > 0){ ?>
                <span class="ml-2 w-2 h-2 bg-orange-500 rounded-full animate-pulse"></span>
              <?php } ?>
            </h3>
            <div class="flex items-end justify-between z-10">
              <span class="text-4xl font-extrabold text-gray-900"><?php echo $brokenLinksCount; ?></span>
              <span class="text-xs font-bold px-2 py-1 rounded-lg <?php echo esc_attr($broken_badge[1]); ?>">
                <?php echo esc_html($broken_badge[0]); ?>
              </span>
            </div>
          </a>

        </div>

        <!-- Mid row -->
        <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">

            <!-- Site Health Score -->
            <div class="bg-white rounded-2xl p-8 shadow-sm border border-gray-100 flex flex-col justify-center items-center text-center relative">
                <h3 class="text-gray-500 font-bold mb-4">Site Health Score</h3>

                <div class="relative w-40 h-40 mb-4">
                    <svg class="w-full h-full" viewBox="0 0 100 100">
                    <circle class="text-gray-100 stroke-current" stroke-width="8" cx="50" cy="50" r="40" fill="transparent"></circle>

                    <circle
                        class="<?php echo esc_attr($health_meta['ring']); ?> stroke-current"
                        stroke-width="8"
                        stroke-linecap="round"
                        cx="50" cy="50" r="40"
                        fill="transparent"
                        style="stroke-dasharray: <?php echo esc_attr($health_dasharray); ?>; stroke-dashoffset: <?php echo esc_attr($health_dashoffset); ?>; transform: rotate(-90deg); transform-origin: 50% 50%;"
                    ></circle>
                    </svg>

                    <div class="absolute inset-0 flex flex-col items-center justify-center">
                    <span class="text-4xl font-extrabold text-gray-900"><?php echo (int) $health['score']; ?></span>
                    <span class="text-xs text-gray-400 uppercase font-bold"><?php echo esc_html($health_meta['label']); ?></span>
                    </div>
                </div>

                <a href="<?php echo esc_url($hint_url); ?>" class="text-sm text-gray-600 px-4 inline-block hover:underline" data-wpil-hint-action-id="<?php echo esc_attr($hint_target); ?>" data-wpil-hint-stat-id="<?php echo esc_attr($hint_stat_id); ?>">
                    <?php echo esc_html($hint_text); ?>
                </a>
            </div>


          <!-- Link Distribution (map to existing stats that exist today) -->
          <div class="lg:col-span-2 bg-white rounded-2xl p-8 shadow-sm border border-gray-100">
            <div class="flex justify-between items-center mb-6">
              <h3 class="text-lg font-bold text-gray-900">Link Distribution</h3>
            </div>

            <div class="space-y-6">

              <!-- Clicks tracked -->
              <div>
                <div class="flex justify-between text-sm mb-2">
                  <span class="font-medium text-gray-600">Internal Links</span>
                  <span class="font-bold text-gray-900"><?php echo number_format($internal_links); ?></span>
                </div>
                <div class="w-full bg-gray-100 rounded-full h-2.5">
                  <!--TO-IMPLEMENT: decide what this bar represents, currently static -->
                  <div class="lw-gradient-bg h-2.5 rounded-full animate-fill" style="width: <?php echo (int) min(100, max(0, $internal_percent)); ?>%"></div>
                </div>
              </div>

              <!-- External Site Focus -->
              <div id="wpil-stat-external-links">
                <div class="flex justify-between text-sm mb-2">
                  <span class="font-medium text-gray-600">External Links</span>
                  <span class="font-bold text-gray-900"><?php echo number_format($external_links); ?></span>
                </div>
                <div class="w-full bg-gray-100 rounded-full h-2.5">
                  <div class="bg-blue-300 h-2.5 rounded-full animate-fill" style="width: <?php echo (int) min(100, max(0, $external_percent)); ?>%"></div>
                </div>
                <div class="mt-3" style="display: none;">
                  <a href="<?php echo admin_url('admin.php?page=link_whisper&type=domains&domain_focus=1'); ?>"
                     class="inline-flex items-center text-xs font-bold text-[#7F5AF0] hover:underline" target="_blank">
                    View Domains Report →
                  </a>
                </div>
              </div>

              <!-- Anchor Length Score -->
              <div>
                <div class="flex justify-between text-sm mb-2">
                  <span class="font-medium text-gray-600">Anchor Length Score</span>
                  <span class="font-bold text-gray-900">
                    <?php echo ($anchor_length_percent === null) ? 'Unknown' : ((int) $anchor_length_percent . '%'); ?>
                  </span>
                </div>
                <div class="w-full bg-gray-100 rounded-full h-2.5">
                  <div class="bg-yellow-400 h-2.5 rounded-full animate-fill"
                       style="width: <?php echo ($anchor_length_percent === null) ? 37 : (int) min(100, max(0, $anchor_length_percent)); ?>%"></div>
                </div>
              </div>

            </div>
          </div>

        </div>

        <!-- Third row -->
         <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">

          <!-- Clicks Tracked -->
          <a href="<?php echo admin_url('admin.php?page=link_whisper&type=clicks'); ?>" target="_blank"
             class="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 flex flex-col justify-between h-32 relative overflow-hidden group hover:border-purple-200 transition-colors">
            <div class="absolute right-0 top-0 w-24 h-24 bg-purple-50 rounded-full -mr-8 -mt-8 opacity-50 group-hover:scale-110 transition-transform"></div>
            <h3 class="text-sm font-bold text-gray-400 uppercase tracking-wide z-10">Clicks Tracked</h3>
            <div class="flex items-end justify-between z-10">
              <span class="text-4xl font-extrabold text-gray-900 wpil-report-stats-posts-crawled"><?php echo $clicks_30; ?></span>
              <span class="text-green-500 text-xs font-bold bg-green-50 px-2 py-1 rounded-lg flex items-center">
                <?php if($is_positive){ ?>
                  <span class="mr-1">▲</span>
                <?php } else { ?>
                  <span class="mr-1">▼</span>
                <?php } ?>
                <?php echo ($is_positive ? '+' : '') . $percent_change; ?>%
              </span>
            </div>
          </a>

          <!-- Link Relation -->
          <a href="<?php echo admin_url('admin.php?page=link_whisper&type=links&link_relation=1'); ?>" target="_blank" id="wpil-stat-link-quality"
             class="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 flex flex-col justify-between h-32 relative overflow-hidden group hover:border-blue-200 transition-colors">
            <h3 class="text-sm font-bold text-gray-400 uppercase tracking-wide z-10 flex items-center gap-2">
              Link Quality Score
              <span class="wpil-report-header-container cust-tooltipdash relative">
                <span
                  class="dashicons dashicons-editor-help wpil-tippy-tooltipped"
                  data-wpil-tooltip-placement="top"
                  data-wpil-tooltip-allowhtml="1"
                  data-wpil-tooltip-content="Link Quality Score measures how closely related your internal links are based on AI analysis.<br><br>Higher percentages indicate stronger topical relevance.">
                </span>
              </span>
            </h3>

            <div class="flex items-end justify-between z-10">
              <span class="text-4xl font-extrabold text-gray-900 wpil-report-stats-link-coverage">
                <?php echo rtrim(rtrim(number_format($link_relatedness, 2), '0'), '.'); ?>%
              </span>

              <div class="w-12 h-12 relative">
                <svg viewBox="0 0 36 36" class="w-12 h-12 transform -rotate-90">
                  <path class="text-gray-100"
                        d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
                        fill="none" stroke="currentColor" stroke-width="4" />
                  <path class="<?php echo ($link_relatedness >= 60 ? 'text-orange-400' : 'text-red-400'); ?>"
                        stroke-dasharray="<?php echo esc_attr($relatedness_dash_str); ?>"
                        d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
                        fill="none" stroke="currentColor" stroke-width="4" />
                </svg>
              </div>
            </div>
          </a>

          <!-- Links Inserted -->
          <div
             class="bg-white rounded-2xl p-6 shadow-sm border border-blue-100 flex flex-col justify-between h-32 relative overflow-hidden">
            <div class="absolute right-0 top-0 w-24 h-24 bg-blue-50 rounded-full -mr-8 -mt-8 opacity-50"></div>
            <h3 class="text-sm font-bold text-gray-400 uppercase tracking-wide z-10 flex items-center">
              Links Created
            </h3>
            <div class="flex items-end justify-between z-10">
                <span class="text-4xl font-extrabold text-gray-900"><?php echo $links_inserted; ?></span>
              <span class="text-xs font-bold px-2 py-1 rounded-lg <?php echo esc_attr($insert_badge[1]); ?>">
                <?php echo esc_html($insert_badge[0]); ?>
              </span>
            </div>
            </div>
        </div>

        <!-- Bottom row -->
        <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 pb-12">

            <!-- Recommended Actions -->
            <div class="lg:col-span-2 space-y-4">
            <h3 class="text-lg font-bold text-gray-900 mb-2 flex items-center">
                Recommended Actions
                <span class="ml-3 bg-red-100 text-red-600 text-xs font-bold px-2 py-0.5 rounded-full">
                    <?php echo (int) $serious; ?> Serious
                </span>
            </h3>

            <?php
                // 5) Render actions
                Wpil_Dashboard::wpil_dash_render_recommended_actions($recommended_actions);
            ?>
            </div><!-- /Recommended Actions -->

          <!-- Notification Hub -->
          <div class="space-y-4">
            <h3 class="text-lg font-bold text-gray-900 mb-2">Notification Hub</h3>

            <div class="bg-white p-5 rounded-xl border border-gray-200">
              <?php include 'notification_hub.php'; ?>
            </div>

            <!-- Optional promo card -->
            <div class="hidden bg-gradient-to-br from-purple-50 to-blue-50 p-5 rounded-xl border border-purple-100 relative overflow-hidden">
              <div class="flex items-start space-x-3 relative z-10">
                <div class="bg-white p-1.5 rounded-lg shadow-sm text-[#7F5AF0]">
                  <span class="font-black">⚡</span>
                </div>
                <div>
                  <h4 class="font-bold text-gray-900 text-sm">Running low on AI Credits?</h4>
                  <p class="text-xs text-gray-600 mt-1 leading-relaxed">Power up your content analysis with our new AI models.</p>
                  <a href="#" class="inline-block mt-3 text-xs font-bold text-[#7F5AF0] hover:underline">Get 50% Off Refill →</a>
                  <!--TO-IMPLEMENT: real link and logic -->
                </div>
              </div>
            </div>
          </div>

        </div>
      </div><!-- /max-w-7xl -->

</div>
</div>
</div>
<?php include_once 'fix-modal.php'; ?>
<?php include_once 'wizard/credits-modal.php'; ?>
</div>
<script>
  window.WPIL_AI_CREDITS = <?php echo (int) Wpil_AI::get_available_ai_credits(); ?>;
  window.WPIL_AI_FIX_NONCE = '<?php echo esc_js(wp_create_nonce('wpil_ai_fix_nonce')); ?>';
</script>
<script>
(function() {
  let lastFixContext = null;

  function wpilParseInt(val) {
    if (val === undefined || val === null) return 0;
    const s = String(val).replace(/,/g, '').trim();
    const n = parseInt(s, 10);
    return isNaN(n) ? 0 : n;
  }

  function wpilFormatInt(n) {
    return wpilParseInt(n).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }

  function setAll(selector, value) {
    document.querySelectorAll(selector).forEach(function(el) {
      el.textContent = value;
    });
  }

  function padShortfall(shortfall) {
    let padded = Math.ceil(shortfall * 1.25);
    padded = Math.round(padded / 100) * 100;
    if (padded < shortfall) padded += 100;
    if (padded < 500) padded = 500;
    return padded;
  }

  function openFixModal(ctx) {
    lastFixContext = ctx;

    const estimate = wpilParseInt(ctx.estimate);
    const balance = wpilParseInt(ctx.balance);

    document.getElementById('wpil-fix-description').textContent = ctx.description || '';
    setAll('[data-wpil-fix-estimate]', wpilFormatInt(estimate));
    setAll('[data-wpil-fix-balance]', wpilFormatInt(balance));

    const enoughCredits = (estimate <= 0) ? true : (balance >= estimate);

    const statusBadge = document.querySelector('[data-role="wpil-fix-status"]');
    if (statusBadge) {
      statusBadge.textContent = enoughCredits ? 'Ready' : 'Not enough credits';
      statusBadge.classList.toggle('is-bad', !enoughCredits);
    }

    const bar = document.querySelector('[data-role="wpil-fix-bar"]');
    if (bar) {
      const pct = (estimate > 0) ? Math.min(100, Math.round((balance / estimate) * 100)) : 100;
      bar.style.width = pct + '%';
    }

    document.getElementById('wpil-fix-warning').classList.toggle('hidden', enoughCredits);
    document.getElementById('wpil-fix-actions-enough').classList.toggle('hidden', !enoughCredits);
    document.getElementById('wpil-fix-actions-short').classList.toggle('hidden', enoughCredits);

    if (!enoughCredits) {
      const shortfall = Math.max(0, estimate - balance);
      const padded = padShortfall(shortfall);
      setAll('[data-wpil-fix-shortfall]', wpilFormatInt(padded));

      const buyBtn = document.getElementById('wpil-fix-buy');
      buyBtn.dataset.credits = padded;
      buyBtn.dataset.quantity = padded;
    }

    const modal = document.getElementById('wpil-fix-modal');
    modal.classList.remove('hidden');
    modal.setAttribute('aria-hidden', 'false');
  }

  function closeFixModal() {
    const modal = document.getElementById('wpil-fix-modal');
    modal.classList.add('hidden');
    modal.setAttribute('aria-hidden', 'true');
  }

  document.addEventListener('click', function(e) {
    const fixBtn = e.target.closest('[data-wpil-fix-type]');
    if (!fixBtn) return;

    e.preventDefault();

    const ctx = {
      type: fixBtn.dataset.wpilFixType,
      itemId: fixBtn.dataset.wpilFixItemId || '',
      estimate: parseInt(fixBtn.dataset.wpilFixEstimate, 10),
      description: fixBtn.dataset.wpilFixDescription || '',
      balance: window.WPIL_AI_CREDITS || 0
    };

    openFixModal(ctx);
  });

  document.querySelectorAll('[data-wpil-fix-cancel]').forEach(function(btn) {
    btn.addEventListener('click', closeFixModal);
  });

  document.getElementById('wpil-fix-begin')
    ?.addEventListener('click', function() {
      closeFixModal();

      // START FIX PROCESS HERE
      // You already have this pattern in scanning.php
      if(window.wpilAiFixRunner && typeof window.wpilAiFixRunner.start === 'function'){
        window.wpilAiFixRunner.start(lastFixContext);
      }
    });

  if (window.jQuery) {
    jQuery(document).on('lwcc:paid', function() {
      if (!lastFixContext) return;

      const buyBtn = document.getElementById('wpil-fix-buy');
      const purchase = wpilParseInt(buyBtn ? buyBtn.dataset.credits : 0);

      if (purchase > 0) {
        window.WPIL_AI_CREDITS = wpilParseInt(window.WPIL_AI_CREDITS) + purchase;
      }

      lastFixContext.balance = window.WPIL_AI_CREDITS || 0;
      openFixModal(lastFixContext);
    });
  }
})();
</script>