<?php
/**
 * firefly-seo.php – SEO Report + Step‑by‑Step Wizard (per‑page)
 *
 * Features:
 *  - Customizer overlay with two reports: General (Score /5) and Wizard (Score /10)
 *  - Per‑page meta box redesigned as a 4‑step wizard
 *  - Standalone bulk editor under Pages → Bulk SEO Wizard
 *  - Single‑page wizard (hidden admin page) for focused editing
 *  - Report 2 uses card layout with page status, progress bar, inline edit
 *  - Token‑based scoring: URL, title, H1 show match counts; progress bar includes fractional points.
 *
 * Load via your theme loader:
 *   require_once get_template_directory() . '/firefly-seo.php';
 */

if (!defined('ABSPATH')) exit;

/* ============================================================
 *  A) SHARED HELPER FUNCTIONS (used by reports & wizard)
 * ============================================================ */

/**
 * Split a textarea value (comma or newline separated) into a clean array.
 */
function firefly_split_list(string $s): array {
    $s = str_replace(["\r\n", "\r"], "\n", $s);
    $s = str_replace([",", ";"], "\n", $s);
    $parts = array_map('trim', explode("\n", $s));
    return array_values(array_filter($parts, fn($v) => $v !== '' && $v !== '-'));
}



function firefly_url_to_absolute(string $href): string {
    $href = trim($href);
    if ($href === '') return '';

    // Already absolute (http/https)
    if (preg_match('#^https?://#i', $href)) return $href;

    // Protocol-relative //example.com/path
    if (strpos($href, '//') === 0) {
        $scheme = is_ssl() ? 'https:' : 'http:';
        return $scheme . $href;
    }

    // Root-relative /path
    if (strpos($href, '/') === 0) {
        return home_url($href);
    }

    // Other relative (path)
    return home_url('/' . ltrim($href, '/'));
}

function firefly_norm_url_compare(string $url): string {
    $url = trim($url);
    if ($url === '') return '';

    // Make absolute if needed
    $url = firefly_url_to_absolute($url);

    // Strip fragment & query
    $url = preg_replace('/[#?].*$/', '', $url);

    // Normalize scheme + host + path
    $parts = wp_parse_url($url);
    if (empty($parts['host'])) return rtrim($url, '/');

    $host = strtolower($parts['host']);
    $path = isset($parts['path']) ? $parts['path'] : '';
    $path = '/' . ltrim($path, '/');

    // Decode and normalize slashes
    $path = rawurldecode($path);
    $path = preg_replace('#/+#', '/', $path);

    // Remove trailing slash (except root)
    if ($path !== '/') $path = rtrim($path, '/');

    return $host . $path;
}


/**
 * Normalize a string for comparison.
 */
function firefly_strip_macrons(string $s): string {
    // Māori macrons → plain vowels (case-insensitive)
    $map = [
        'Ā'=>'A','Ē'=>'E','Ī'=>'I','Ō'=>'O','Ū'=>'U',
        'ā'=>'a','ē'=>'e','ī'=>'i','ō'=>'o','ū'=>'u',
    ];
    return strtr($s, $map);
}

function firefly_normalize(string $s): string {
    // Light normalize for labels/comparisons
    $s = firefly_strip_macrons($s);
    $s = strtolower(trim($s));
    $s = preg_replace('/\s+/u', ' ', $s);
    return $s;
}

/**
 * Strong normalize for matching (case-insensitive, ignores macrons, treats hyphens as spaces).
 */
function firefly_norm_match(string $s): string {
    $s = html_entity_decode($s, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    $s = firefly_strip_macrons($s);
    $s = mb_strtolower($s, 'UTF-8');
    // treat hyphens as spaces
    $s = str_replace(['-', '–', '—'], ' ', $s);
    // everything else non-letter/number → space
    $s = preg_replace('/[^\p{L}\p{N}]+/u', ' ', $s);
    $s = preg_replace('/\s+/u', ' ', trim($s));
    return $s;
}

/**
 * Extract keyword tokens from a phrase (remove stopwords, plurals, etc.).
 * Returns an array of tokens (words) for scoring.
 */
function firefly_keyword_tokens(string $phrase): array {
    /**
     * Parse a keyword phrase into "terms" for matching.
     *
     * Rules:
     * - Words outside quotes are order-insensitive.
     * - Anything inside double quotes is treated as an ordered phrase term.
     * - Case-insensitive, ignores macrons (Māori == maori).
     * - Hyphens are treated as spaces unless the user quotes the hyphenated phrase.
     *
     * Returns an array of terms (strings). Phrase terms may contain spaces.
     */
    static $stopwords = [
        'a','an','and','are','as','at','be','by','for','from','has','have','how','i','in','is','it','its',
        'of','on','or','that','the','this','to','was','were','what','when','where','who','why','with'
    ];

    $raw = trim((string)$phrase);
    if ($raw === '') return [];

    // Extract quoted phrases
    $phrases = [];
    if (preg_match_all('/"([^"]+)"/u', $raw, $m)) {
        foreach ($m[1] as $ph) {
            $ph = firefly_norm_match($ph);
            if ($ph !== '') $phrases[] = $ph;
        }
        // Remove the quoted segments from the remainder
        $raw = preg_replace('/"[^"]+"/u', ' ', $raw);
    }

    // Now extract unquoted words
    $norm = firefly_norm_match($raw);
    $words = [];
    if ($norm !== '') {
        $parts = preg_split('/\s+/u', $norm);
        foreach ($parts as $w) {
            $w = trim($w);
            if ($w === '') continue;
            if (in_array($w, $stopwords, true)) continue;
            // basic singular: remove trailing s
            $w2 = preg_replace('/s$/u', '', $w);
            if ($w2 === '') $w2 = $w;
            $words[] = $w2;
        }
    }

    // Unique but preserve order: phrases first then words
    $out = [];
    foreach (array_merge($phrases, $words) as $t) {
        if ($t === '') continue;
        if (!in_array($t, $out, true)) $out[] = $t;
    }
    return $out;
}

/**
 * Flatten terms into individual "word tokens" (splits multi-word terms into words).
 * Keeps unique order.
 */
function firefly_terms_to_word_tokens(array $terms): array {
    $out = [];
    foreach ($terms as $t) {
        $t = firefly_norm_match((string)$t);
        if ($t === '') continue;

        $parts = preg_split('/\s+/u', $t);
        foreach ($parts as $w) {
            $w = trim((string)$w);
            if ($w === '') continue;
            if (!in_array($w, $out, true)) $out[] = $w;
        }
    }
    return $out;
}

/**
 * Count how many of the target tokens appear in a given text.
 * Returns a float (count of tokens found).
 */
function firefly_token_match_count(string $text, array $terms): float {
    if (empty($terms)) return 0;
    $hay = firefly_norm_match($text);
    if ($hay === '') return 0;

    $found = 0;
    foreach ($terms as $term) {
        $term = firefly_norm_match((string)$term);
        if ($term === '') continue;

        if (strpos($term, ' ') !== false) {
            if (strpos(' ' . $hay . ' ', ' ' . $term . ' ') !== false) $found++;
        } else {
            $t = preg_quote($term, '/');
            if (preg_match('/\b' . $t . 's?\b/u', $hay)) $found++;
        }
    }
    return $found;
}

function firefly_match_map(string $text, array $terms): array {
    $hay = firefly_norm_match($text);
    $map = [];
    foreach ($terms as $term) {
        $t = firefly_norm_match((string)$term);
        if ($t === '') continue;
        $ok = false;
        if (strpos($t, ' ') !== false) {
            $ok = (strpos(' ' . $hay . ' ', ' ' . $t . ' ') !== false);
        } else {
            $tt = preg_quote($t, '/');
            $ok = (bool)preg_match('/\b' . $tt . 's?\b/u', $hay);
        }
        $map[$t] = $ok;
    }
    return $map;
}

function firefly_map_counts(array $map): array {
    $total = count($map);
    $matched = 0;
    foreach ($map as $ok) if ($ok) $matched++;
    return [$matched, $total];
}

function firefly_status_label(int $matched, int $total): array {
    if ($total <= 0) return ['FAIL', 'ff-fail'];
    if ($matched >= $total) return ['PASS', 'ff-pass'];
    if ($matched <= 0) return ['FAIL', 'ff-fail'];
    return ['PARTIAL FAIL', 'ff-partial'];
}

function firefly_render_pills(array $map): string {
    if (empty($map)) return '';
    $out = '<div class="ff-pills">';
    foreach ($map as $term => $ok) {
        $cls = $ok ? 'ff-pill ok' : 'ff-pill bad';
        $out .= '<span class="' . esc_attr($cls) . '">' . esc_html($term) . '</span>';
    }
    $out .= '</div>';
    return $out;
}

/**
 * Fuzzy count of tokens in text for checklist items that require full phrase presence.
 */
function firefly_fuzzy_count(string $text, array $tokens): int {
    if (empty($tokens)) return 0;
    $text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');

    if (count($tokens) === 1) {
        $norm = mb_strtolower($text);
        $norm = preg_replace('/[^\p{L}\p{N}]+/u', ' ', $norm);
        $t = preg_quote($tokens[0], '/');
        preg_match_all('/\b' . $t . 's?\b/u', $norm, $m);
        return count($m[0]);
    }

    $chunks = preg_split('/[.!?]+/u', $text);
    $count = 0;
    foreach ($chunks as $chunk) {
        $c = mb_strtolower($chunk);
        $c = preg_replace('/[^\p{L}\p{N}]+/u', ' ', $c);
        $ok = true;
        foreach ($tokens as $tok) {
            $t = preg_quote($tok, '/');
            if (!preg_match('/\b' . $t . 's?\b/u', $c)) { $ok = false; break; }
        }
        if ($ok) $count++;
    }
    return $count;
}

function firefly_fuzzy_has(string $text, array $tokens): bool {
    return firefly_fuzzy_count($text, $tokens) > 0;
}

/**
 * Check if a menu label contains any of the tokens.
 */
function firefly_menu_label_has(int $page_id, array $tokens): bool {
    if (empty($tokens)) return false;
    $menus = wp_get_nav_menus();
    foreach ($menus as $menu) {
        $items = wp_get_nav_menu_items($menu->term_id);
        if (empty($items)) continue;
        foreach ($items as $it) {
            if ((int)$it->object_id === $page_id && $it->object === 'page') {
                $label = (string)($it->title ?? '');
                if ($label !== '' && firefly_fuzzy_has($label, $tokens)) return true;
            }
        }
    }
    return false;
}

/**
 * Check if another page links to this page with an anchor containing the tokens.
 */
if (!function_exists('firefly_has_inbound_link')) {
    function firefly_has_inbound_link(int $page_id, string $permalink, array $tokens): bool {
        if (empty($tokens) || $permalink === '') return false;

        $target = firefly_norm_url_compare($permalink);
        if ($target === '') return false;

        $others = get_posts([
            'post_type'      => 'page',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'fields'         => 'ids',
            'post__not_in'   => [$page_id],
            'no_found_rows'  => true,
        ]);

        foreach ($others as $oid) {
            $post = get_post($oid);
            if (!$post) continue;

            // Avoid heavy recursion / block rendering: use raw content
            $html = (string)$post->post_content;

            if (!preg_match_all('/<a\b[^>]*href\s*=\s*([\'"])(.*?)\1[^>]*>(.*?)<\/a>/is', $html, $mm, PREG_SET_ORDER)) {
                continue;
            }

            foreach ($mm as $m) {
                $hrefNorm = firefly_norm_url_compare((string)$m[2]);
                if ($hrefNorm === '' || $hrefNorm !== $target) continue;

                $anchor = html_entity_decode(wp_strip_all_tags((string)$m[3]), ENT_QUOTES | ENT_HTML5, 'UTF-8');
                if ($anchor !== '' && firefly_fuzzy_has($anchor, $tokens)) {
                    return true;
                }
            }
        }

        return false;
    }
}

/**
 * Compute the 10 checklist items and score for a given page.
 * Returns an array with 'checks' (assoc array a-j) and 'score'.
 */
function firefly_get_page_seo_checklist(int $post_id): array {
    $post = get_post($post_id);
    $keys = ['a','b','c','d','e','f','g','h','i','j'];
    if (!$post) {
        return [
            'checks' => array_fill_keys($keys, false),
            'score'  => 0,
            'detail' => [],
        ];
    }

    $SEOtarget   = (string) get_post_meta($post_id, 'SEOtarget', true);
    $SEOsynonyms = (string) get_post_meta($post_id, 'SEOsynonyms', true);
    $SEOkeywords = (string) get_post_meta($post_id, 'SEOkeywords', true);

    $nosea = "";

    if ( $SEOtarget == true AND $SEOsynonyms == true AND $SEOkeywords == true ) {
        $noseo = "yes";
    }

    $syn_list = firefly_split_list($SEOsynonyms); // each entry is a phrase (may be multi-word)
    $key_list = firefly_split_list($SEOkeywords);

    $target_terms = $SEOtarget !== '' ? firefly_keyword_tokens($SEOtarget) : [];

    $rendered = apply_filters('the_content', $post->post_content);

    // H1
    $h1 = ''; $has_h1 = false;
    if (preg_match('/<h1\b[^>]*>(.*?)<\/h1>/is', (string)$rendered, $m)) {
        $h1 = trim(html_entity_decode(wp_strip_all_tags($m[1]), ENT_QUOTES | ENT_HTML5, 'UTF-8'));
        if ($h1 !== '') $has_h1 = true;
    }

    // Body text excluding first H1
    $html_wo_h1 = preg_replace('/<h1\b[^>]*>.*?<\/h1>/is', ' ', (string)$rendered, 1);
    $body_text  = html_entity_decode(wp_strip_all_tags((string)$html_wo_h1), ENT_QUOTES | ENT_HTML5, 'UTF-8');

    // ALT texts
    $alts = [];
    if (preg_match_all('/<img\b[^>]*\balt\s*=\s*([\'"])(.*?)\1[^>]*>/is', (string)$rendered, $mm)) {
        foreach ($mm[2] as $alt) {
            $alt_text = html_entity_decode(wp_strip_all_tags((string)$alt), ENT_QUOTES | ENT_HTML5, 'UTF-8');
            if ($alt_text !== '') $alts[] = $alt_text;
        }
    }

    // H2 texts
    $h2s = [];
    if (preg_match_all('/<h2\b[^>]*>(.*?)<\/h2>/is', (string)$rendered, $hm)) {
        foreach ($hm[1] as $h2raw) {
            $h2 = trim(html_entity_decode(wp_strip_all_tags((string)$h2raw), ENT_QUOTES | ENT_HTML5, 'UTF-8'));
            if ($h2 !== '') $h2s[] = $h2;
        }
    }

    $slug = (string)($post->post_name ?? '');
    $title = get_the_title($post);
    $permalink = get_permalink($post);

    $checks = array_fill_keys($keys, false);
    $detail = [];

    // a–e: token/phrase pills from SEOtarget
    if (!empty($target_terms)) {
        $map_slug  = firefly_match_map($slug, $target_terms);
        $map_title = firefly_match_map($title, $target_terms);
        $map_h1    = $has_h1 ? firefly_match_map($h1, $target_terms) : array_fill_keys($target_terms, false);
        $map_body  = firefly_match_map($body_text, $target_terms);

        $best_alt_map = [];
        $best_alt_hits = -1;
        foreach ($alts as $alt) {
            $malt = firefly_match_map($alt, $target_terms);
            [$hits, $tot] = firefly_map_counts($malt);
            if ($hits > $best_alt_hits) { $best_alt_hits = $hits; $best_alt_map = $malt; }
            if ($tot > 0 && $hits >= $tot) break; // perfect
        }
        if (empty($alts)) {
            $best_alt_map = array_fill_keys($target_terms, false);
        }

        [$a_hits, $a_tot] = firefly_map_counts($map_slug);
        [$b_hits, $b_tot] = firefly_map_counts($map_title);
        [$c_hits, $c_tot] = firefly_map_counts($map_h1);
        [$d_hits, $d_tot] = firefly_map_counts($map_body);
        [$e_hits, $e_tot] = firefly_map_counts($best_alt_map);

        $checks['a'] = ($a_tot > 0 && $a_hits >= $a_tot);
        $checks['b'] = ($b_tot > 0 && $b_hits >= $b_tot);
        $checks['c'] = ($has_h1 && $c_tot > 0 && $c_hits >= $c_tot);
        $checks['d'] = ($d_tot > 0 && $d_hits >= $d_tot);
        $checks['e'] = ($e_tot > 0 && $e_hits >= $e_tot);

        $detail['a'] = ['map'=>$map_slug,  'hits'=>$a_hits, 'tot'=>$a_tot];
        $detail['b'] = ['map'=>$map_title, 'hits'=>$b_hits, 'tot'=>$b_tot];
        $detail['c'] = ['map'=>$map_h1,    'hits'=>$c_hits, 'tot'=>$c_tot];
        $detail['d'] = ['map'=>$map_body,  'hits'=>$d_hits, 'tot'=>$d_tot];
        $detail['e'] = ['map'=>$best_alt_map,'hits'=>$e_hits,'tot'=>$e_tot];
    } else {
        // keep empty maps so renderer stays safe
        foreach (['a','b','c','d','e'] as $k) $detail[$k] = ['map'=>[], 'hits'=>0, 'tot'=>0];
    }

    // f: H2 includes any SEOsynonyms (NOW: per-word pills + partial hits/tot)
    $syn_terms_all = [];
    foreach ($syn_list as $syn) {
        $syn_terms_all = array_merge($syn_terms_all, firefly_keyword_tokens($syn));
    }
    $syn_tokens_all = firefly_terms_to_word_tokens($syn_terms_all);

    $h2_text_all = '';
    if (!empty($h2s)) {
        $h2_text_all = implode(' ', $h2s);
    }

    $syn_map_h2 = !empty($syn_tokens_all) ? firefly_match_map($h2_text_all, $syn_tokens_all) : [];
    [$f_hits, $f_tot] = firefly_map_counts($syn_map_h2);

    // checklist boolean meaning: "any synonym word appears in any H2"
    $checks['f'] = ($f_tot > 0 && $f_hits > 0);

    $detail['f'] = ['map'=>$syn_map_h2,'hits'=>$f_hits,'tot'=>$f_tot];

    // g: Image ALT includes any SEOsynonyms (NOW: per-word pills + partial hits/tot)
    $alt_text_all = '';
    if (!empty($alts)) {
        $alt_text_all = implode(' ', $alts);
    }

    $syn_map_alt = !empty($syn_tokens_all) ? firefly_match_map($alt_text_all, $syn_tokens_all) : [];
    [$g_hits, $g_tot] = firefly_map_counts($syn_map_alt);

    // checklist boolean meaning: "any synonym word appears in any ALT"
    $checks['g'] = ($g_tot > 0 && $g_hits > 0);

    $detail['g'] = ['map'=>$syn_map_alt,'hits'=>$g_hits,'tot'=>$g_tot];

    // h: ALL SEOkeywords appear in body (NOW: per-word pills + partial hits/tot)
    $kw_terms_all = [];
    foreach ($key_list as $kw) {
        $kw_terms_all = array_merge($kw_terms_all, firefly_keyword_tokens($kw));
    }
    $kw_tokens_all = firefly_terms_to_word_tokens($kw_terms_all);

    $kw_map_body = !empty($kw_tokens_all) ? firefly_match_map($body_text, $kw_tokens_all) : [];
    [$h_hits,$h_tot] = firefly_map_counts($kw_map_body);

    // checklist boolean meaning: "ALL keyword words must appear"
    $checks['h'] = ($h_tot > 0 && $h_hits >= $h_tot);

    $detail['h'] = ['map'=>$kw_map_body,'hits'=>$h_hits,'tot'=>$h_tot];

    // i & j use existing helpers (order-insensitive words)
  // i & j use existing helpers (order-insensitive words)
if (!empty($target_terms)) {

    // For menu/inbound, ignore phrase terms; use individual words only
    $words_only = [];
    foreach ($target_terms as $t) {
        if (strpos($t, ' ') === false) $words_only[] = $t;
    }
    $words_only = array_values(array_unique($words_only));

    $i_ok = (!empty($words_only)) ? firefly_menu_label_has($post_id, $words_only) : false;
    $j_ok = (!empty($words_only)) ? firefly_has_inbound_link($post_id, $permalink, $words_only) : false;

    $checks['i'] = $i_ok;
    $checks['j'] = $j_ok;

    // Give the renderer something to show (pills + counts)
    $detail['i'] = [
        'map'  => !empty($words_only) ? array_fill_keys($words_only, $i_ok) : [],
        'hits' => $i_ok ? count($words_only) : 0,
        'tot'  => count($words_only),
    ];

    $detail['j'] = [
        'map'  => !empty($words_only) ? array_fill_keys($words_only, $j_ok) : [],
        'hits' => $j_ok ? count($words_only) : 0,
        'tot'  => count($words_only),
    ];
} else {
    // keep renderer safe
    $detail['i'] = ['map'=>[], 'hits'=>0, 'tot'=>0];
    $detail['j'] = ['map'=>[], 'hits'=>0, 'tot'=>0];
}

    $score = 0;
    foreach ($checks as $ok) if ($ok) $score++;

    return ['checks' => $checks, 'score' => $score, 'detail' => $detail];
}

/* ============================================================
 *  B) STEP‑BY‑STEP WIZARD META BOX (still available in page editor)
 * ============================================================ */

add_action('add_meta_boxes', function () {
    add_meta_box(
        'firefly_seo_wizard',
        __('Firefly SEO Wizard', 'firefly'),
        'firefly_render_seo_wizard_metabox',
        'page',
        'normal',
        'high'
    );
});

function firefly_render_seo_wizard_metabox(\WP_Post $post){
    $target   = (string) get_post_meta($post->ID, 'SEOtarget', true);
    $synonyms = (string) get_post_meta($post->ID, 'SEOsynonyms', true);
    $keywords = (string) get_post_meta($post->ID, 'SEOkeywords', true);

    wp_nonce_field('firefly_seo_wizard_save', 'firefly_seo_wizard_nonce');

    $checklist = firefly_get_page_seo_checklist($post->ID);
    $checks = $checklist['checks'];
    $score = $checklist['score'];

    $labels = [
        'a' => 'URL includes SEOtarget',
        'b' => 'Page title includes SEOtarget',
        'c' => 'H1 includes SEOtarget',
        'd' => 'Body text includes SEOtarget',
        'e' => 'Image ALT includes SEOtarget',
        'f' => 'H2 includes any SEOsynonyms',
        'g' => 'Image ALT includes any SEOsynonyms',
        'h' => 'All SEOkeywords appear in body',
        'i' => 'Menu label includes SEOtarget',
        'j' => 'Inbound link uses SEOtarget as anchor'
    ];
    ?>
    <div id="firefly-seo-wizard" class="firefly-wizard" style="max-width:900px;">
        <p style="margin:0 0 10px 0; color:#555;">
            Follow the steps below to optimise this page. After saving, the report will show your progress.
        </p>

        <div class="firefly-wizard-steps" style="display:flex; border-bottom:2px solid #e6e6e6; margin-bottom:20px;">
            <button type="button" class="step-tab" data-step="1" style="flex:1; padding:10px; background:#f1f1f1; border:none; border-radius:8px 8px 0 0; cursor:pointer; font-weight:bold;">1. Primary Keyword</button>
            <button type="button" class="step-tab" data-step="2" style="flex:1; padding:10px; background:#f1f1f1; border:none; border-radius:8px 8px 0 0; cursor:pointer; font-weight:bold;">2. Synonyms</button>
            <button type="button" class="step-tab" data-step="3" style="flex:1; padding:10px; background:#f1f1f1; border:none; border-radius:8px 8px 0 0; cursor:pointer; font-weight:bold;">3. Related Keywords</button>
            <button type="button" class="step-tab" data-step="4" style="flex:1; padding:10px; background:#f1f1f1; border:none; border-radius:8px 8px 0 0; cursor:pointer; font-weight:bold;">4. Report</button>
        </div>

        <!-- Step 1: Primary Keyword -->
        <div class="wizard-step" data-step="1" style="display:block;">
            <div style="border:1px solid #e6e6e6; border-radius:10px; padding:14px; background:#fff;">
                <h3>1) Primary keyword or phrase</h3>
                <p style="color:#666;">Example: “ice to penguins” or “chicken napping”.</p>
                <input type="text" name="firefly_SEOtarget" value="<?php echo esc_attr($target); ?>" style="width:100%; max-width:700px; padding:8px 10px; border:1px solid #ccd0d4; border-radius:8px;" />
                <p style="margin:8px 0 0 0; color:#777; font-size:12px;">Saved as <code>SEOtarget</code></p>
                <div style="margin-top:20px; text-align:right;">
                    <button type="button" class="button button-primary next-step" data-next="2">Next →</button>
                </div>
            </div>
        </div>

        <!-- Step 2: Synonyms -->
        <div class="wizard-step" data-step="2" style="display:none;">
            <div style="border:1px solid #e6e6e6; border-radius:10px; padding:14px; background:#fff;">
                <h3>2) Synonyms for the primary keywords</h3>
                <p style="color:#666;">One per line (or comma-separated). Example: “South Pole”, “Emperor Penguin colonies”.</p>
                <textarea name="firefly_SEOsynonyms" rows="4" style="width:100%; max-width:700px; padding:8px 10px; border:1px solid #ccd0d4; border-radius:8px;"><?php echo esc_textarea($synonyms); ?></textarea>
                <p style="margin:8px 0 0 0; color:#777; font-size:12px;">Saved as <code>SEOsynonyms</code></p>
                <div style="margin-top:20px; display:flex; justify-content:space-between;">
                    <button type="button" class="button prev-step" data-prev="1">← Previous</button>
                    <button type="button" class="button button-primary next-step" data-next="3">Next →</button>
                </div>
            </div>
        </div>

        <!-- Step 3: Related Keywords -->
        <div class="wizard-step" data-step="3" style="display:none;">
            <div style="border:1px solid #e6e6e6; border-radius:10px; padding:14px; background:#fff;">
                <h3>3) Related keywords (specific to this page)</h3>
                <p style="color:#666;">One per line (or comma-separated). Example: “cold”, “frozen”, “ice delivery”.</p>
                <textarea name="firefly_SEOkeywords" rows="5" style="width:100%; max-width:700px; padding:8px 10px; border:1px solid #ccd0d4; border-radius:8px;"><?php echo esc_textarea($keywords); ?></textarea>
                <p style="margin:8px 0 0 0; color:#777; font-size:12px;">Saved as <code>SEOkeywords</code></p>
                <div style="margin-top:20px; display:flex; justify-content:space-between;">
                    <button type="button" class="button prev-step" data-prev="2">← Previous</button>
                    <button type="button" class="button button-primary next-step" data-next="4">Next →</button>
                </div>
            </div>
        </div>

        <!-- Step 4: Report -->
        <div class="wizard-step" data-step="4" style="display:none;">
            <div style="border:1px solid #e6e6e6; border-radius:10px; padding:14px; background:#fff;">
                <h3>SEO Checklist & Score</h3>
                <p class="sub" style="margin:0 0 12px 0;">After saving, the checklist below shows how well this page meets the 10 criteria.</p>
                <div style="margin-bottom:16px;">
                    <span class="ff-score" style="display:inline-flex; align-items:center; gap:8px; padding:6px 12px; border-radius:999px; border:1px solid rgba(10,107,43,.25); background:rgba(10,107,43,.06); color:#0a6b2b; font-weight:bold;">
                        <span class="ff-stars"><?php echo str_repeat('★', $score) . str_repeat('☆', 10 - $score); ?></span>
                        <span><?php echo $score; ?>/10</span>
                    </span>
                </div>
                <ul class="ff-checklist" style="margin:0; padding:0; list-style:none;">
                    <?php foreach ($labels as $k => $lab): 
                        $ok = !empty($checks[$k]);
                    ?>
                    <li style="margin:6px 0; padding:8px 10px; border:1px solid #eee; border-radius:10px; display:flex; gap:10px; align-items:flex-start;">
                        <div class="key" style="width:22px; font-weight:700; color:#555;"><?php echo $k; ?>.</div>
                        <div>
                            <?php if ($ok): ?>
                                <span class="ff-ok" style="display:inline-block; padding:3px 8px; border-radius:999px; font-size:12px; border:1px solid rgba(10,107,43,.25); background:rgba(10,107,43,.06); color:#0a6b2b; margin-right:6px;">OK</span>
                            <?php else: ?>
                                <span class="ff-warn" style="display:inline-block; padding:3px 8px; border-radius:999px; font-size:12px; border:1px solid rgba(176,0,32,.25); background:rgba(176,0,32,.06); color:#b00020; margin-right:6px;">Missing</span>
                            <?php endif; ?>
                            <?php echo esc_html($lab); ?>
                        </div>
                    </li>
                    <?php endforeach; ?>
                </ul>
                <div style="margin-top:20px; display:flex; justify-content:space-between;">
                    <button type="button" class="button prev-step" data-prev="3">← Previous</button>
                    <button type="button" class="button" onclick="location.reload();">↻ Refresh Report</button>
                </div>
            </div>
        </div>
        <p style="margin-top:12px; color:#666;">After saving, open <b>Appearance → Customize → Firefly SEO report</b> to see the full site report.</p>
    </div>
    <script>
    (function() {
        var wizard = document.getElementById('firefly-seo-wizard');
        if (!wizard) return;
        var tabs = wizard.querySelectorAll('.step-tab');
        var steps = wizard.querySelectorAll('.wizard-step');
        function showStep(stepNumber) {
            steps.forEach(step => step.style.display = 'none');
            var activeStep = wizard.querySelector('.wizard-step[data-step="'+stepNumber+'"]');
            if (activeStep) activeStep.style.display = 'block';
            tabs.forEach(tab => {
                tab.style.background = '#f1f1f1';
                tab.style.fontWeight = 'normal';
            });
            var activeTab = wizard.querySelector('.step-tab[data-step="'+stepNumber+'"]');
            if (activeTab) {
                activeTab.style.background = '#e1e1e1';
                activeTab.style.fontWeight = 'bold';
            }
        }
        tabs.forEach(tab => {
            tab.addEventListener('click', function(e) {
                e.preventDefault();
                var step = this.getAttribute('data-step');
                showStep(step);
            });
        });
        wizard.querySelectorAll('.next-step').forEach(btn => {
            btn.addEventListener('click', function(e) {
                e.preventDefault();
                var next = this.getAttribute('data-next');
                if (next) showStep(next);
            });
        });
        wizard.querySelectorAll('.prev-step').forEach(btn => {
            btn.addEventListener('click', function(e) {
                e.preventDefault();
                var prev = this.getAttribute('data-prev');
                if (prev) showStep(prev);
            });
        });
    })();
    </script>
    <?php
}

add_action('save_post_page', function($post_id){
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if (!current_user_can('edit_page', $post_id)) return;
    if (empty($_POST['firefly_seo_wizard_nonce']) || !wp_verify_nonce($_POST['firefly_seo_wizard_nonce'], 'firefly_seo_wizard_save')) {
        return;
    }
    $target   = isset($_POST['firefly_SEOtarget']) ? sanitize_text_field((string)$_POST['firefly_SEOtarget']) : '';
    $synonyms = isset($_POST['firefly_SEOsynonyms']) ? sanitize_textarea_field((string)$_POST['firefly_SEOsynonyms']) : '';
    $keywords = isset($_POST['firefly_SEOkeywords']) ? sanitize_textarea_field((string)$_POST['firefly_SEOkeywords']) : '';
    update_post_meta($post_id, 'SEOtarget', $target);
    update_post_meta($post_id, 'SEOsynonyms', $synonyms);
    update_post_meta($post_id, 'SEOkeywords', $keywords);
});

/* ============================================================
 *  C) STANDALONE BULK SEO WIZARD (Pages → Bulk SEO Wizard)
 * ============================================================ */

add_action('admin_menu', function() {
    add_pages_page(
        __('Bulk SEO Wizard', 'firefly'),
        __('Bulk SEO Wizard', 'firefly'),
        'edit_pages',
        'firefly-seo-bulk-wizard',
        'firefly_render_bulk_seo_wizard_page'
    );
});

function firefly_render_bulk_seo_wizard_page() {
    if (!current_user_can('edit_pages')) wp_die('Unauthorized');
    if (isset($_POST['save_seo']) && check_admin_referer('firefly_seo_wizard_bulk')) {
        foreach ($_POST['pages'] as $page_id => $data) {
            $page_id = intval($page_id);
            if (!$page_id) continue;
            update_post_meta($page_id, 'SEOtarget', sanitize_text_field($data['target']));
            update_post_meta($page_id, 'SEOsynonyms', sanitize_textarea_field($data['synonyms']));
            update_post_meta($page_id, 'SEOkeywords', sanitize_textarea_field($data['keywords']));
        }
      echo '<div class="notice notice-success">
    <p>SEO data updated.</p>
    <h1>
        <a href="' . admin_url('customize.php?autofocus[section]=firefly_seo_report_section') . '">
            Continue…
        </a>
    </h1>
</div>';    }
    $pages = get_posts([
        'post_type'      => 'page',
        'post_status'    => 'publish',
        'posts_per_page' => -1,
        'orderby'        => 'title',
        'order'          => 'ASC',
    ]);
    $current_page_id = isset($_GET['page_id']) ? intval($_GET['page_id']) : 0;
    ?>
    <div class="wrap">
        <h1><?php _e('Bulk SEO Wizard', 'firefly'); ?></h1>
        <p><?php _e('Edit SEOtarget, SEOsynonyms, and SEOkeywords for all published pages at once.', 'firefly'); ?></p>
        <form method="post">
            <?php wp_nonce_field('firefly_seo_wizard_bulk'); ?>
            <table class="wp-list-table widefat fixed striped">
                <thead>
                    <tr>
                        <th scope="col" style="width: 25%;"><?php _e('Page', 'firefly'); ?></th>
                        <th scope="col" style="width: 25%;"><?php _e('SEOtarget', 'firefly'); ?></th>
                        <th scope="col" style="width: 25%;"><?php _e('SEOsynonyms', 'firefly'); ?></th>
                        <th scope="col" style="width: 25%;"><?php _e('SEOkeywords', 'firefly'); ?></th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($pages as $page):
                        $target   = get_post_meta($page->ID, 'SEOtarget', true);
                        $synonyms = get_post_meta($page->ID, 'SEOsynonyms', true);
                        $keywords = get_post_meta($page->ID, 'SEOkeywords', true);
                        $row_id   = 'page-' . $page->ID;
                    ?>
                    <tr id="<?php echo $row_id; ?>" <?php if ($page->ID == $current_page_id) echo ' class="highlight"'; ?>>
                        <td>
                            <strong><?php echo esc_html(get_the_title($page)); ?></strong>
                            <div class="row-actions">
                                <a href="<?php echo get_edit_post_link($page->ID); ?>"><?php _e('Edit in editor', 'firefly'); ?></a>
                            </div>
                        </td>
                        <td>
                            <input type="text" name="pages[<?php echo $page->ID; ?>][target]" value="<?php echo esc_attr($target); ?>" class="large-text">
                        </td>
                        <td>
                            <textarea name="pages[<?php echo $page->ID; ?>][synonyms]" rows="3" class="large-text"><?php echo esc_textarea($synonyms); ?></textarea>
                        </td>
                        <td>
                            <textarea name="pages[<?php echo $page->ID; ?>][keywords]" rows="3" class="large-text"><?php echo esc_textarea($keywords); ?></textarea>
                        </td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
            <p class="submit">
                <input type="submit" name="save_seo" class="button-primary" value="<?php _e('Save All Changes', 'firefly'); ?>">
            </p>
        </form>
    </div>
    <?php if ($current_page_id): ?>
    <script>
    (function() {
        var row = document.getElementById('page-<?php echo $current_page_id; ?>');
        if (row) {
            row.scrollIntoView({ behavior: 'smooth', block: 'center' });
            row.style.backgroundColor = '#ffffcc';
            setTimeout(() => row.style.backgroundColor = '', 3000);
        }
    })();
    </script>
    <?php endif; ?>
    <?php
}

/* ============================================================
 *  D) SINGLE PAGE SEO WIZARD (accessed via SEO edit link)
 * ============================================================ */

add_action('admin_menu', function() {
    add_submenu_page(
        null,
        __('SEO Wizard', 'firefly'),
        __('SEO Wizard', 'firefly'),
        'edit_pages',
        'firefly-seo-single-wizard',
        'firefly_render_single_seo_wizard_page'
    );
});

function firefly_render_single_seo_wizard_page() {
    if (!current_user_can('edit_pages')) wp_die('Unauthorized');
    $page_id = isset($_GET['page_id']) ? intval($_GET['page_id']) : 0;
    if (!$page_id) wp_die(__('No page specified.', 'firefly'));
    $post = get_post($page_id);
    if (!$post || $post->post_type !== 'page') wp_die(__('Invalid page.', 'firefly'));

    $target   = get_post_meta($page_id, 'SEOtarget', true);
    $synonyms = get_post_meta($page_id, 'SEOsynonyms', true);
    $keywords = get_post_meta($page_id, 'SEOkeywords', true);

    if (isset($_POST['save_seo']) && check_admin_referer('firefly_seo_single_wizard_' . $page_id)) {
        update_post_meta($page_id, 'SEOtarget', sanitize_text_field($_POST['firefly_SEOtarget']));
        update_post_meta($page_id, 'SEOsynonyms', sanitize_textarea_field($_POST['firefly_SEOsynonyms']));
        update_post_meta($page_id, 'SEOkeywords', sanitize_textarea_field($_POST['firefly_SEOkeywords']));
        echo '<div class="notice notice-success"><p>' . __('SEO data saved.    < <h1>
        <a href="' . admin_url('customize.php?autofocus[section]=firefly_seo_report_section&firefly_seo_open=2') . '">
            Continue…
        </a>
    </h1>', 'firefly') . '</p></div>';
        $target   = get_post_meta($page_id, 'SEOtarget', true);
        $synonyms = get_post_meta($page_id, 'SEOsynonyms', true);
        $keywords = get_post_meta($page_id, 'SEOkeywords', true);
    
        if (isset($_GET['firefly_return']) && (int)$_GET['firefly_return'] === 1) {
            $url = admin_url('customize.php?autofocus[section]=firefly_seo_report_section&firefly_seo_open=2');
            // optional focus
            $url = add_query_arg(['firefly_seo_focus' => $page_id], $url);
            wp_safe_redirect($url);
            exit;
        }

    }

    $checklist = firefly_get_page_seo_checklist($page_id);
    $checks = $checklist['checks'];
    $score = $checklist['score'];

    $labels = [
        'a' => 'URL includes SEOtarget',
        'b' => 'Page title includes SEOtarget',
        'c' => 'H1 includes SEOtarget',
        'd' => 'Body text includes SEOtarget',
        'e' => 'Image ALT includes SEOtarget',
        'f' => 'H2 includes any SEOsynonyms',
        'g' => 'Image ALT includes any SEOsynonyms',
        'h' => 'All SEOkeywords appear in body',
        'i' => 'Menu label includes SEOtarget',
        'j' => 'Inbound link uses SEOtarget as anchor'
    ];
    ?>
    <div class="wrap">
        <h1><?php _e('SEO Wizard for:', 'firefly'); ?> <?php echo esc_html(get_the_title($page_id)); ?></h1>
        <p><a href="<?php echo get_edit_post_link($page_id); ?>" class="button">← <?php _e('Back to Page Editor', 'firefly'); ?></a></p>
        <div id="firefly-seo-wizard" class="firefly-wizard" style="max-width:900px;">
            <p style="margin:0 0 10px 0; color:#555;">Follow the steps below to optimise this page. After saving, the report will show your progress.</p>
            <div class="firefly-wizard-steps" style="display:flex; border-bottom:2px solid #e6e6e6; margin-bottom:20px;">
                <button type="button" class="step-tab" data-step="1" style="flex:1; padding:10px; background:#f1f1f1; border:none; border-radius:8px 8px 0 0; cursor:pointer; font-weight:bold;">1. Primary Keyword</button>
                <button type="button" class="step-tab" data-step="2" style="flex:1; padding:10px; background:#f1f1f1; border:none; border-radius:8px 8px 0 0; cursor:pointer; font-weight:bold;">2. Synonyms</button>
                <button type="button" class="step-tab" data-step="3" style="flex:1; padding:10px; background:#f1f1f1; border:none; border-radius:8px 8px 0 0; cursor:pointer; font-weight:bold;">3. Related Keywords</button>
                <button type="button" class="step-tab" data-step="4" style="flex:1; padding:10px; background:#f1f1f1; border:none; border-radius:8px 8px 0 0; cursor:pointer; font-weight:bold;">4. Report</button>
            </div>
            <form method="post">
                <?php wp_nonce_field('firefly_seo_single_wizard_' . $page_id); ?>
                <!-- Step 1 -->
                <div class="wizard-step" data-step="1" style="display:block;">
                    <div style="border:1px solid #e6e6e6; border-radius:10px; padding:14px; background:#fff;">
                        <h3>1) Primary keyword or phrase</h3>
                        <p style="color:#666;">Example: “ice to penguins” or “chicken napping”.</p>
                        <input type="text" name="firefly_SEOtarget" value="<?php echo esc_attr($target); ?>" style="width:100%; max-width:700px; padding:8px 10px; border:1px solid #ccd0d4; border-radius:8px;" />
                        <p style="margin:8px 0 0 0; color:#777; font-size:12px;">Saved as <code>SEOtarget</code></p>
                        <div style="margin-top:20px; text-align:right;"><button type="button" class="button button-primary next-step" data-next="2">Next →</button></div>
                    </div>
                </div>
                <!-- Step 2 -->
                <div class="wizard-step" data-step="2" style="display:none;">
                    <div style="border:1px solid #e6e6e6; border-radius:10px; padding:14px; background:#fff;">
                        <h3>2) Synonyms for the primary keywords</h3>
                        <p style="color:#666;">One per line (or comma-separated). Example: “South Pole”, “Emperor Penguin colonies”.</p>
                        <textarea name="firefly_SEOsynonyms" rows="4" style="width:100%; max-width:700px; padding:8px 10px; border:1px solid #ccd0d4; border-radius:8px;"><?php echo esc_textarea($synonyms); ?></textarea>
                        <p style="margin:8px 0 0 0; color:#777; font-size:12px;">Saved as <code>SEOsynonyms</code></p>
                        <div style="margin-top:20px; display:flex; justify-content:space-between;">
                            <button type="button" class="button prev-step" data-prev="1">← Previous</button>
                            <button type="button" class="button button-primary next-step" data-next="3">Next →</button>
                        </div>
                    </div>
                </div>
                <!-- Step 3 -->
                <div class="wizard-step" data-step="3" style="display:none;">
                    <div style="border:1px solid #e6e6e6; border-radius:10px; padding:14px; background:#fff;">
                        <h3>3) Related keywords (specific to this page)</h3>
                        <p style="color:#666;">One per line (or comma-separated). Example: “cold”, “frozen”, “ice delivery”.</p>
                        <textarea name="firefly_SEOkeywords" rows="5" style="width:100%; max-width:700px; padding:8px 10px; border:1px solid #ccd0d4; border-radius:8px;"><?php echo esc_textarea($keywords); ?></textarea>
                        <p style="margin:8px 0 0 0; color:#777; font-size:12px;">Saved as <code>SEOkeywords</code></p>
                        <div style="margin-top:20px; display:flex; justify-content:space-between;">
                            <button type="button" class="button prev-step" data-prev="2">← Previous</button>
                            <button type="button" class="button button-primary next-step" data-next="4">Next →</button>
                        </div>
                    </div>
                </div>
                <!-- Step 4 -->
                <div class="wizard-step" data-step="4" style="display:none;">
                    <div style="border:1px solid #e6e6e6; border-radius:10px; padding:14px; background:#fff;">
                        <h3>SEO Checklist & Score</h3>
                        <p class="sub" style="margin:0 0 12px 0;">After saving the fields above, the checklist below shows how well this page meets the 10 criteria.</p>
                        <div style="margin-bottom:16px;">
                            <span class="ff-score" style="display:inline-flex; align-items:center; gap:8px; padding:6px 12px; border-radius:999px; border:1px solid rgba(10,107,43,.25); background:rgba(10,107,43,.06); color:#0a6b2b; font-weight:bold;">
                                <span class="ff-stars"><?php echo str_repeat('★', $score) . str_repeat('☆', 10 - $score); ?></span>
                                <span><?php echo $score; ?>/10</span>
                            </span>
                        </div>
                        <ul class="ff-checklist" style="margin:0; padding:0; list-style:none;">
                            <?php foreach ($labels as $k => $lab): $ok = !empty($checks[$k]); ?>
                            <li style="margin:6px 0; padding:8px 10px; border:1px solid #eee; border-radius:10px; display:flex; gap:10px; align-items:flex-start;">
                                <div class="key" style="width:22px; font-weight:700; color:#555;"><?php echo $k; ?>.</div>
                                <div>
                                    <?php if ($ok): ?>
                                        <span class="ff-ok" style="display:inline-block; padding:3px 8px; border-radius:999px; font-size:12px; border:1px solid rgba(10,107,43,.25); background:rgba(10,107,43,.06); color:#0a6b2b; margin-right:6px;">OK</span>
                                    <?php else: ?>
                                        <span class="ff-warn" style="display:inline-block; padding:3px 8px; border-radius:999px; font-size:12px; border:1px solid rgba(176,0,32,.25); background:rgba(176,0,32,.06); color:#b00020; margin-right:6px;">Missing</span>
                                    <?php endif; ?>
                                    <?php echo esc_html($lab); ?>
                                </div>
                            </li>
                            <?php endforeach; ?>
                        </ul>
                        <div style="margin-top:20px; display:flex; justify-content:space-between;">
                            <button type="button" class="button prev-step" data-prev="3">← Previous</button>
                            <input type="submit" name="save_seo" class="button button-primary" value="<?php _e('Save Changes', 'firefly'); ?>">
                        </div>
                    </div>
                </div>
            </form>
            <p style="margin-top:12px; color:#666;">After saving, return to <b>Appearance → Customize → Firefly SEO report</b> to see the updated score.</p>
        </div>
    </div>
    <script>
    (function() {
        var wizard = document.getElementById('firefly-seo-wizard');
        if (!wizard) return;
        var tabs = wizard.querySelectorAll('.step-tab');
        var steps = wizard.querySelectorAll('.wizard-step');
        function showStep(stepNumber) {
            steps.forEach(step => step.style.display = 'none');
            var activeStep = wizard.querySelector('.wizard-step[data-step="'+stepNumber+'"]');
            if (activeStep) activeStep.style.display = 'block';
            tabs.forEach(tab => {
                tab.style.background = '#f1f1f1';
                tab.style.fontWeight = 'normal';
            });
            var activeTab = wizard.querySelector('.step-tab[data-step="'+stepNumber+'"]');
            if (activeTab) {
                activeTab.style.background = '#e1e1e1';
                activeTab.style.fontWeight = 'bold';
            }
        }
        tabs.forEach(tab => {
            tab.addEventListener('click', function(e) {
                e.preventDefault();
                var step = this.getAttribute('data-step');
                showStep(step);
            });
        });
        wizard.querySelectorAll('.next-step').forEach(btn => {
            btn.addEventListener('click', function(e) {
                e.preventDefault();
                var next = this.getAttribute('data-next');
                if (next) showStep(next);
            });
        });
        wizard.querySelectorAll('.prev-step').forEach(btn => {
            btn.addEventListener('click', function(e) {
                e.preventDefault();
                var prev = this.getAttribute('data-prev');
                if (prev) showStep(prev);
            });
        });
    })();
    </script>
    <?php
}

/* ============================================================
 *  E) CUSTOMIZER: Two buttons for reports
 * ============================================================ */

if (class_exists('WP_Customize_Control') && !class_exists('Firefly_SEO_Report_Button_Control')) {
    class Firefly_SEO_Report_Button_Control extends WP_Customize_Control {
        public $type = 'firefly_seo_button';
        public $button_label = '';
        public $report_type = 1;
        public function render_content() {
            ?>
            <div style="margin:10px 0;">
                <button type="button" class="button button-primary firefly-report-btn" data-report="<?php echo esc_attr($this->report_type); ?>" style="width:100%;"><?php echo esc_html($this->button_label); ?></button>
            </div>
            <?php
        }
    }
}

add_action('customize_register', function($wp_customize){
    $wp_customize->add_section('firefly_seo_report_section', [
        'title'       => __('Firefly SEO report', 'firefly'),
        'priority'    => 35,
        'description' => __('Choose which report to display in the preview.', 'firefly'),
    ]);

    // Button for General Report (Report 1)
    $wp_customize->add_setting('firefly_seo_general_btn', [
        'default' => '',
        'sanitize_callback' => 'sanitize_text_field',
    ]);
    $wp_customize->add_control(new Firefly_SEO_Report_Button_Control($wp_customize, 'firefly_seo_general_btn', [
        'section' => 'firefly_seo_report_section',
        'settings' => 'firefly_seo_general_btn',
        'button_label' => __('General Report (Score /5)', 'firefly'),
        'report_type' => 1,
    ]));

    // Button for Wizard Report (Report 2)
    $wp_customize->add_setting('firefly_seo_wizard_btn', [
        'default' => '',
        'sanitize_callback' => 'sanitize_text_field',
    ]);
    $wp_customize->add_control(new Firefly_SEO_Report_Button_Control($wp_customize, 'firefly_seo_wizard_btn', [
        'section' => 'firefly_seo_report_section',
        'settings' => 'firefly_seo_wizard_btn',
        'button_label' => __('Wizard Report (Score /10)', 'firefly'),
        'report_type' => 2,
    ]));
});

add_action('customize_controls_enqueue_scripts', function () {

    wp_add_inline_script('customize-controls', <<<'JS'
(function(wp){
    if (!wp || !wp.customize) return;

    var STORAGE_KEY = "firefly_seo_active_report";
    var queuedReport = "wizard";
    var lastSent = null;

    // Restore last report (but we'll still default to wizard when entering the section)
    try {
        var saved = window.sessionStorage.getItem(STORAGE_KEY);
        if (saved) queuedReport = saved;
    } catch(e) {}

    function seoSectionIsActive(){
        try {
            var sec = wp.customize.section && wp.customize.section("firefly_seo_report");
            return !!(sec && sec.expanded && sec.expanded());
        } catch(e) {}
        return false;
    }

    function queue(reportType){
        queuedReport = reportType || "wizard";
        try { window.sessionStorage.setItem(STORAGE_KEY, queuedReport); } catch(e) {}
    }

    function sendWhenPreviewReady(reportType){
        reportType = reportType || queuedReport || "wizard";
        queue(reportType);

        // Avoid spamming identical sends
        if (lastSent === reportType) return;

        try {
            // Wait until preview iframe says it's ready (important after refresh)
            wp.customize.previewer.bind("ready", function(){
                try {
                    wp.customize.previewer.send("firefly_show_report", { type: reportType });
                    lastSent = reportType;
                } catch(e) {}
            });

            // If it's already ready, this will fire quickly anyway
            wp.customize.previewer.send("firefly_show_report", { type: reportType });
            lastSent = reportType;

        } catch(e) {}
    }

    // Your button clicks (General / Wizard)
    document.addEventListener("click", function(e) {
        var btn = e.target && e.target.closest ? e.target.closest(".firefly-report-btn") : null;
        if (!btn) return;

        e.preventDefault();
        var report = btn.getAttribute("data-report") || "wizard";
        sendWhenPreviewReady(report);
    });

    // Always show Wizard by default when the SEO section is opened
    wp.customize.bind("ready", function(){

        // If we land on the SEO section already open, force wizard immediately
        if (seoSectionIsActive()) {
            sendWhenPreviewReady("wizard");
        }

        // When user opens the SEO section, force wizard
        if (wp.customize.section && wp.customize.section("firefly_seo_report")) {
            wp.customize.section("firefly_seo_report", function(section){
                section.expanded.bind(function(isExpanded){
                    if (isExpanded) {
                        sendWhenPreviewReady("wizard");
                    }
                });
            });
        }

        // After ANY preview refresh/reload (Quick Edit save etc), re-open the queued report
        try {
            wp.customize.previewer.bind("refresh", function(){
                // refresh happens before reload; reset lastSent so we re-send after reload
                lastSent = null;
            });

            wp.customize.previewer.bind("ready", function(){
                if (seoSectionIsActive()) {
                    sendWhenPreviewReady(queuedReport || "wizard");
                }
            });
        } catch(e) {}

        // Optional: coming back from wizard save using ?firefly_seo_open=wizard
        try {
            var qs = new URLSearchParams(window.location.search || "");
            var open = qs.get("firefly_seo_open");
            if (open) sendWhenPreviewReady(open);
        } catch(e) {}

    });

})(window.wp);
JS
    );

});



add_action('customize_preview_init', function () {
    if (!is_customize_preview()) return;
    wp_enqueue_script('customize-preview');
    $nonce = wp_create_nonce('firefly_seo_report');
    wp_add_inline_script('customize-preview', '
        (function(wp){
            if (!wp || !wp.customize) return;
            var overlayId = "firefly-seo-report-overlay";
            var cssId     = "firefly-seo-report-css";
            var isOn      = false;
            var loading   = false;
            var currentReport = 1; // default
            var ajaxUrl = ' . json_encode(admin_url('admin-ajax.php')) . ';

            function ensureCss(){
                if (document.getElementById(cssId)) return;
                var style = document.createElement("style");
                style.id = cssId;
                style.textContent = `
                    body.firefly-seo-report-on > *:not(#${overlayId}) { display:none !important; }
                    body.firefly-seo-report-on { margin:0 !important; background:#fff !important; color:#111 !important; font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif !important; }
                    #${overlayId}{ display:block; background:#fff; min-height:100vh; padding:22px 26px; box-sizing:border-box; }
                    #${overlayId} .wrap{ max-width:1600px; margin:0 auto; }
                    #${overlayId} h1{ margin:0 0 6px 0; font-size:18px; font-weight:700; }
                    #${overlayId} .sub{ margin:0 0 16px 0; font-size:13px; color:#555; }
                    #${overlayId} .ff-bad{ color:#b00020; font-weight:700; }
                    #${overlayId} .ff-good{ color:#0a6b2b; font-weight:700; }
                    #${overlayId} .ff-warn{ display:inline-block; padding:3px 8px; border-radius:999px; font-size:12px; border:1px solid rgba(176,0,32,.25); background: rgba(176,0,32,.06); color:#b00020; margin-right:6px; margin-bottom:4px; }
                    #${overlayId} .ff-ok{ display:inline-block; padding:3px 8px; border-radius:999px; font-size:12px; border:1px solid rgba(10,107,43,.25); background: rgba(10,107,43,.06); color:#0a6b2b; margin-right:6px; margin-bottom:4px; }
                    #${overlayId} .ff-score{ display:inline-flex; align-items:center; gap:8px; padding:4px 10px; border-radius:999px; font-size:12px; border:1px solid rgba(10,107,43,.25); background: rgba(10,107,43,.06); color:#0a6b2b; }
                    #${overlayId} .ff-stars{ letter-spacing:1px; white-space:nowrap; font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif; }
                    #${overlayId} .ff-box{ margin-top:16px; border:1px solid #e6e6e6; border-radius:10px; padding:14px 16px; background:#fff; }
                    #${overlayId} .ff-box h2{ margin:0 0 8px 0; font-size:14px; font-weight:700; }
                    #${overlayId} .ff-line{ display:flex; align-items:center; gap:10px; font-size:13px; margin:6px 0; }
                    #${overlayId} .ff-line .phrase{ min-width:260px; }
                    #${overlayId} .ff-line .score{ color:#0a6b2b; font-weight:700; white-space:nowrap; }
                    #${overlayId} .ff-checklist{ margin:10px 0 0 0; padding:0; list-style:none; }
                    #${overlayId} .ff-checklist li{ margin:6px 0; padding:8px 10px; border:1px solid #eee; border-radius:10px; display:flex; gap:10px; align-items:flex-start; }
                    #${overlayId} .ff-checklist .key{ width:22px; font-weight:700; color:#555; }
                    #${overlayId} .ff-seo-edit-btn{ background:none; border:none; padding:0; margin:0; color:#0b57d0; cursor:pointer; text-decoration:underline; font:inherit; }
                    #${overlayId} .ff-pills{ display:flex; gap:8px; flex-wrap:wrap; margin-top:8px; }
                    #${overlayId} .ff-pill{ display:inline-flex; align-items:center; padding:6px 12px; border-radius:999px; font-size:12px; border:1px solid rgba(0,0,0,.12); }
                    #${overlayId} .ff-pill.ok{ background:rgba(10,107,43,.06); border-color:rgba(10,107,43,.25); color:#0a6b2b; }
                    #${overlayId} .ff-pill.bad{ background:rgba(176,0,32,.06); border-color:rgba(176,0,32,.25); color:#b00020; }
                    #${overlayId} .ff-pass{ color:#0a6b2b; }
                    #${overlayId} .ff-partial{ color:#b00020; }
                    #${overlayId} .ff-fail{ color:#b00020; }

                    /* Card layout for Report 2 */
                    .firefly-page-card { background: #f9f9f9; border: 1px solid #e0e0e0; border-radius: 12px; padding: 20px; margin-bottom: 20px; }
                    .firefly-page-card h2 { margin-top: 0; }
                    .firefly-status-badge { display: inline-block; padding: 4px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; text-transform: uppercase; }
                    .firefly-status-publish { background: #e6f3e6; color: #0a6b2b; }
                    .firefly-status-draft { background: #f0f0f0; color: #666; }
                    .firefly-status-private { background: #ffe6e6; color: #b00020; }
                    .firefly-meta-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 15px; margin: 15px 0; }
                    .firefly-meta-item { background: white; padding: 10px; border-radius: 8px; border: 1px solid #eee; }
                    .firefly-meta-item strong { display: block; margin-bottom: 5px; color: #333; }
                    .progress-bar { background:#f0f0f0; border-radius:10px; margin:15px 0; height:24px; width:100%; overflow:hidden; }
                    .progress-bar-fill { background:#0a6b2b; height:24px; text-align:center; color:white; font-size:12px; line-height:24px; }
                `;
                document.head.appendChild(style);
            }

            function ensureOverlay(){
                var el = document.getElementById(overlayId);
                if (el) return el;
                el = document.createElement("div");
                el.id = overlayId;
                el.innerHTML = `<div class="wrap"><h1>Firefly SEO report</h1><p class="sub">Loading…</p></div>`;
                document.body.appendChild(el);
                return el;
            }

            function fetchReport(reportType){
                if (loading) return;
                loading = true;
                var el = ensureOverlay();
                var sub = el.querySelector(".sub");
                if (sub) sub.textContent = "Loading…";
                var data = new FormData();
                data.append("action", "firefly_seo_report_html");
                data.append("nonce", ' . json_encode($nonce) . ');
                data.append("report_type", reportType);
                fetch(' . json_encode(admin_url('admin-ajax.php')) . ', { method: "POST", credentials: "same-origin", body: data })
                .then(r => r.text())
                .then(html => { el.innerHTML = html; loading = false; })
                .catch(() => { if (sub) sub.textContent = "Failed to load report."; loading = false; });
            }

            function turnOn(reportType){
                currentReport = parseInt(reportType, 10) || 1;
                if (!isOn) {
                    isOn = true;
                    ensureCss();
                    document.body.classList.add("firefly-seo-report-on");
                }
                fetchReport(reportType);
            }

            function turnOff(){
                if (isOn) {
                    isOn = false;
                    document.body.classList.remove("firefly-seo-report-on");
                }
            }

            
            function openUrl(url){
                if (!url) return;
                try {
                    // Best chance inside Customizer: ask the parent to open the admin URL
                    if (window.parent && window.parent !== window && typeof window.parent.open === "function") {
                        window.parent.open(url, "_blank");
                        return;
                    }
                } catch(e) {}
                try { window.open(url, "_blank"); } catch(e) {}
            }

            // Delegate clicks for buttons inside the overlay (works after AJAX HTML replacement)
            document.addEventListener("click", function(e){
                var t = e.target;
                if (!t) return;

                // Open admin/editor URLs
                if (t.classList && t.classList.contains("ff-open-url")) {
                    e.preventDefault();
                    openUrl(t.getAttribute("data-url"));
                    return;
                }

                // Toggle Quick Edit
                if (t.classList && t.classList.contains("firefly-quick-edit")) {
                    e.preventDefault();
                    var pid = t.getAttribute("data-page-id");
                    var box = document.getElementById("quick-edit-" + pid);
                    if (box) box.style.display = (box.style.display === "none" || box.style.display === "") ? "block" : "none";
                    return;
                }

                // Cancel Quick Edit
                if (t.classList && t.classList.contains("firefly-cancel-quick-edit")) {
                    e.preventDefault();
                    var pid2 = t.getAttribute("data-page-id");
                    var box2 = document.getElementById("quick-edit-" + pid2);
                    if (box2) box2.style.display = "none";
                    return;
                }
            });

            // AJAX-save Quick Edit + inline slug/title saves so we stay on the report overlay
            document.addEventListener("submit", function(e){
                var form = e.target;
                if (!form) return;

                var isQuick = form.classList && form.classList.contains("firefly-quick-edit-form");
                var isInline = form.classList && form.classList.contains("firefly-inline-save");
                if (!isQuick && !isInline) return;

                e.preventDefault();

                var fd = new FormData(form);
                // Ensure action is present
                if (!fd.get("action")) fd.append("action", "firefly_seo_quick_save");

                var pid = form.getAttribute("data-page-id") || fd.get("page_id") || "";

                // spinner (if present)
                var sp = form.querySelector(".spinner");
                if (sp) sp.classList.add("is-active");

                fetch(ajaxUrl, { method:"POST", credentials:"same-origin", body: fd })
                .then(r => r.json())
                .then(res => {
                    if (sp) sp.classList.remove("is-active");

                    if (res && res.success) {
                        // Hide quick edit after save (user asked to go back to report)
                        if (isQuick && pid) {
                            var box = document.getElementById("quick-edit-" + pid);
                            if (box) box.style.display = "none";
                        }
                        // Refresh the current report view
                        fetchReport(currentReport);
                    } else {
                        alert((res && res.data) ? res.data : "Save failed");
                    }
                })
                .catch(() => {
                    if (sp) sp.classList.remove("is-active");
                    alert("Save failed");
                });
            });

wp.customize.bind("preview-ready", function(){
                wp.customize.preview.bind("firefly_show_report", function(msg){
                    if (msg && msg.type) {
                        turnOn(msg.type);
                    } else {
                        turnOff();
                    }
                });
            });
        })(window.wp);
    ');
});

/* ============================================================
 *  F) AJAX: generate report HTML (server-side) with card layout and token‑based scoring
 * ============================================================ */

add_action('wp_ajax_firefly_seo_report_html', function () {
    if (!current_user_can('customize')) { status_header(403); echo 'Forbidden'; wp_die(); }
    $nonce = isset($_POST['nonce']) ? (string)$_POST['nonce'] : '';
    if (!wp_verify_nonce($nonce, 'firefly_seo_report')) { status_header(403); echo 'Bad nonce'; wp_die(); }

    $report_type = isset($_POST['report_type']) ? intval($_POST['report_type']) : 1;

    $pages = get_posts([
        'post_type'              => 'page',
        'post_status'            => ['publish', 'draft', 'private'],
        'posts_per_page'         => -1,
        'orderby'                => 'menu_order',
        'order'                  => 'ASC',
        'no_found_rows'          => true,
        'update_post_meta_cache' => true,
        'update_post_term_cache' => false,
    ]);

    $front_id = (int) get_option('page_on_front');

    $generic_slugs = [
        'home','homepage','about','about-us','aboutus','contact','contact-us','contactus',
        'products','product','services','service','blog','news','events','gallery','portfolio',
        'shop','store','faq','help','privacy','privacy-policy','terms','terms-and-conditions','sample-page',
    ];

    $normalize = 'firefly_normalize';
    $split_list = 'firefly_split_list';
    $keyword_tokens = 'firefly_keyword_tokens';
    $token_match_count = 'firefly_token_match_count';
    $fuzzy_has = 'firefly_fuzzy_has';
    $menu_label_has = 'firefly_menu_label_has';
    $has_inbound_link = 'firefly_has_inbound_link';
    $get_checklist = 'firefly_get_page_seo_checklist';

    $stars_for = function(int $score, int $max): string {
        $score = max(0, min($max, $score));
        return str_repeat('★', $score) . str_repeat('☆', $max - $score);
    };

    $is_generic_slug = fn(string $slug) => in_array(trim(strtolower(trim($slug)),'/'), $generic_slugs, true);
    $is_generic_title = function(string $title) use ($normalize): bool {
        $t = $normalize($title);
        return in_array($t, ['home','contact','contact us','about','about us','products','services','sample page'], true);
    };
    $looks_like_contact = function(\WP_Post $p) use ($normalize): bool {
        $slug = strtolower(trim((string)($p->post_name ?? '')));
        if ($slug !== '' && strpos($slug, 'contact') !== false) return true;
        $title = $normalize(get_the_title($p));
        if ($title === 'contact' || $title === 'contact us') return true;
        $content = strtolower(wp_strip_all_tags((string)$p->post_content));
        return (strpos($content, 'contact') !== false && (strpos($content, 'email') !== false || strpos($content, 'phone') !== false));
    };

    $summary_5  = [];
    $summary_10 = [];

    // Labels for checklist items
    $labels = [
        'a' => 'URL includes SEOtarget',
        'b' => 'Page title includes SEOtarget',
        'c' => 'H1 includes SEOtarget',
        'd' => 'Body text includes SEOtarget',
        'e' => 'Image ALT includes SEOtarget',
        'f' => 'H2 includes any SEOsynonyms',
        'g' => 'Image ALT includes any SEOsynonyms',
        'h' => 'All SEOkeywords appear in body',
        'i' => 'Menu label includes SEOtarget',
        'j' => 'Inbound link uses SEOtarget as anchor'
    ];

    // Recommendations for missing items
    $recommendations = [
        'a' => 'Edit the URL of this page to include the keywords from SEOtarget.',
        'b' => 'Update the page title to include your primary keyword.',
        'c' => 'Add an H1 heading that contains the primary keyword.',
        'd' => 'Write some body text that includes the primary keyword naturally.',
        'e' => 'Add an image with an alt attribute containing the primary keyword.',
        'f' => 'Add an H2 subheading that includes one of the synonyms.',
        'g' => 'Add an image with an alt attribute containing one of the synonyms.',
        'h' => 'Ensure all related keywords appear in the body text in a meaningful way.',
        'i' => 'Change the menu label for this page to include the primary keyword.',
        'j' => 'Create a link from another page to this page using the primary keyword as anchor text.'
    ];

    ob_start();

    if ($report_type == 1) {
        // Report 1: General SEO signals (unchanged)
        ?>
        <div class="wrap">
            <h1>Firefly SEO report – General</h1>
            <div class="ff-box">
                <h2>General SEO signals (Score /5)</h2>
                <table>
                    <thead>
                        <tr>
                            <th style="width:22%;">URL</th>
                            <th style="width:16%;">Page title</th>
                            <th style="width:14%;">H1 content</th>
                            <th style="width:12%;">Keyword in body</th>
                            <th style="width:12%;">Keyword in image ALT</th>
                            <th style="width:12%;">Score</th>
                            <th style="width:12%;">Alerts</th>
                        </tr>
                    </thead>
                    <tbody>
                    <?php
                    if (empty($pages)) {
                        echo '<tr><td colspan="7" class="muted">No pages found.</td></tr>';
                    } else {
                        foreach ($pages as $p) {
                            $pid   = (int)$p->ID;
                            $title = get_the_title($p);
                            $url   = get_permalink($p);
                            $slug  = (string)($p->post_name ?? '');
                            $edit_url = admin_url('admin.php?page=firefly-seo-single-wizard&page_id=' . $pid . '&firefly_return=1');
                            $page_edit_url = get_edit_post_link($pid);

                            $rendered = apply_filters('the_content', $p->post_content);

                            $h1 = ''; $has_h1 = false;
                            if (preg_match('/<h1\b[^>]*>(.*?)<\/h1>/is', (string)$rendered, $m)) {
                                $h1 = trim(html_entity_decode(wp_strip_all_tags($m[1]), ENT_QUOTES | ENT_HTML5, 'UTF-8'));
                                if ($h1 !== '') $has_h1 = true;
                            }

                            $keyword = '';
                            if (!$is_generic_title($title)) $keyword = $title;
                            elseif ($has_h1 && !$is_generic_title($h1)) $keyword = $h1;

                            $slug_generic  = $is_generic_slug($slug);
                            $title_generic = $is_generic_title($title);
                            $h1_generic    = ($has_h1 ? $is_generic_title($h1) : true);

                            $score_title = (!$title_generic ? 1 : 0);
                            $score_url   = (!$slug_generic ? 1 : 0);
                            $score_h1    = ($has_h1 && !$h1_generic ? 1 : 0);

                            $tokens = ($keyword !== '') ? $keyword_tokens($keyword) : [];

                            $body_count = 0; $body_score = 0;
                            if ($keyword !== '') {
                                $html_wo_h1 = preg_replace('/<h1\b[^>]*>.*?<\/h1>/is', ' ', (string)$rendered, 1);
                                $body_text  = html_entity_decode(wp_strip_all_tags((string)$html_wo_h1), ENT_QUOTES | ENT_HTML5, 'UTF-8');
                                $body_count = firefly_fuzzy_count($body_text, $tokens);
                                $body_score = ($body_count > 0 ? 1 : 0);
                            }

                            $alt_match_count = 0; $alt_score = 0;
                            if ($keyword !== '') {
                                if (preg_match_all('/<img\b[^>]*\balt\s*=\s*([\'"])(.*?)\1[^>]*>/is', (string)$rendered, $mm)) {
                                    foreach ($mm[2] as $alt) {
                                        $alt_text = html_entity_decode(wp_strip_all_tags((string)$alt), ENT_QUOTES | ENT_HTML5, 'UTF-8');
                                        if ($alt_text !== '' && firefly_fuzzy_has($alt_text, $tokens)) $alt_match_count++;
                                    }
                                }
                                $alt_score = ($alt_match_count > 0 ? 1 : 0);
                            }

                            if ($keyword === '') {
                                $score_title=$score_url=$score_h1=$body_score=$alt_score=0;
                                $body_count=0; $alt_match_count=0;
                            }

                            $score_total = $score_title + $score_url + $score_h1 + $body_score + $alt_score;

                            $alerts = [];
                            if (!$has_h1) $alerts[] = 'Missing H1';
                            if ($slug_generic) $alerts[] = 'Generic URL slug';

                            $rename_warning = false;
                            if ($pid === $front_id && $normalize($title) === 'home') $rename_warning = true;
                            if ($looks_like_contact($p) && in_array($normalize($title), ['contact','contact us'], true)) $rename_warning = true;

                            if ($keyword !== '') {
                                if (!isset($summary_5[$keyword]) || $score_total > $summary_5[$keyword]['score']) {
                                    $summary_5[$keyword] = ['score'=>$score_total,'max'=>5,'stars'=>$stars_for($score_total,5)];
                                }
                            }

                            echo '<tr>';
                            echo '<td>';
                            echo '<a href="' . esc_url($url) . '" target="_blank" rel="noopener noreferrer">' . esc_html($url) . '</a>';
                            echo '<div class="muted" style="margin-top:6px;">';
                            echo '<button type="button" class="ff-seo-edit-btn firefly-seo-edit" data-url="' . esc_attr($edit_url) . '">SEO edit</button> | ';
                            echo '<a href="' . esc_url($page_edit_url) . '" target="_blank" class="ff-seo-edit-link">Edit page</a>';
                            echo '</div>';
                            if ($slug_generic && $slug !== '') echo '<div class="ff-warn" style="margin-top:6px;">Generic URL slug: ' . esc_html($slug) . '</div>';
                            echo '</td>';
                            echo '<td>' . esc_html($title) . ($rename_warning ? '<div class="ff-warn" style="margin-top:6px;">Rename this page meaningfully</div>' : '') . ($keyword === '' ? '<div class="muted" style="margin-top:6px;">Excluded (generic page)</div>' : '') . '</td>';
                            echo ($has_h1 && !$h1_generic) ? '<td>' . esc_html($h1) . '</td>' : '<td class="ff-bad">No H1</td>';
                            if ($keyword === '') echo '<td class="muted">—</td>';
                            else echo ($body_count>0) ? '<td><span class="ff-good">Yes</span> <span class="muted">(' . (int)$body_count . ')</span></td>' : '<td><span class="ff-bad">No</span> <span class="muted">(0)</span></td>';
                            if ($keyword === '') echo '<td class="muted">—</td>';
                            else echo ($alt_match_count>0) ? '<td><span class="ff-good">Yes</span> <span class="muted">(' . (int)$alt_match_count . ')</span></td>' : '<td><span class="ff-bad">No</span> <span class="muted">(0)</span></td>';
                            echo '<td><span class="ff-score"><span class="ff-stars">' . esc_html($stars_for($score_total,5)) . '</span><span>' . esc_html($score_total) . '/5</span></span></td>';
                            echo '<td>';
                            if (!empty($alerts)) foreach ($alerts as $a) echo '<span class="ff-warn">' . esc_html($a) . '</span>';
                            else echo '<span class="muted">—</span>';
                            echo '</td>';
                            echo '</tr>';
                        }
                    }
                    ?>
                    </tbody>
                </table>
                <?php if (!empty($summary_5)) {
                    uasort($summary_5, fn($a,$b)=>($a['score']===$b['score'])?0:(($a['score']>$b['score'])?-1:1));
                    echo '<div class="ff-box" style="margin-top:14px;"><h2>This site is optimised for the following words and phrases:</h2>';
                    foreach ($summary_5 as $phrase => $info) {
                        echo '<div class="ff-line"><div class="phrase">' . esc_html('"' . $phrase . '"') . '</div><div class="ff-stars">' . esc_html($info['stars']) . '</div><div class="score">' . esc_html($info['score'] . '/' . $info['max']) . '</div></div>';
                    }
                    echo '</div>';
                } ?>
            </div>
        </div>
        <?php
    } else {
        // Report 2: Wizard checklist with card layout and token‑based scoring
        ?>
        <div class="wrap">
            <h1>Firefly SEO report – Wizard</h1>
            <p class="sub">Set <code>SEOtarget</code>, <code>SEOsynonyms</code>, <code>SEOkeywords</code> per page. Click "Quick Edit" to update fields inline.</p>
            <?php
            foreach ($pages as $p) {
                $pid   = (int)$p->ID;
                $title = get_the_title($p);
                $url   = get_permalink($p);
                $slug  = (string)($p->post_name ?? '');
                $status = $p->post_status;
                $status_label = $status === 'publish' ? 'Live' : ($status === 'draft' ? 'Draft' : 'Private');
                $status_class = 'firefly-status-' . $status;
                $edit_url = admin_url('admin.php?page=firefly-seo-single-wizard&page_id=' . $pid . '&firefly_return=1');
                $page_edit_url = get_edit_post_link($pid);

                $checklist = $get_checklist($pid);
                $checks = $checklist['checks'];
                $score10 = $checklist['score'];

                $SEOtarget   = (string) get_post_meta($pid, 'SEOtarget', true);
                $SEOsynonyms = (string) get_post_meta($pid, 'SEOsynonyms', true);
                $SEOkeywords = (string) get_post_meta($pid, 'SEOkeywords', true);

                // Token‑based partial scoring for URL, title, H1
                $target_tokens = $SEOtarget !== '' ? $keyword_tokens($SEOtarget) : [];
                $token_count = count($target_tokens);

                $slug_matches = $token_count > 0 ? $token_match_count($slug, $target_tokens) : 0;
                $title_matches = $token_count > 0 ? $token_match_count($title, $target_tokens) : 0;
                $h1_matches = 0;
                if ($token_count > 0) {
                    $rendered = apply_filters('the_content', $p->post_content);
                    if (preg_match('/<h1\b[^>]*>(.*?)<\/h1>/is', (string)$rendered, $m)) {
                        $h1_text = trim(html_entity_decode(wp_strip_all_tags($m[1]), ENT_QUOTES | ENT_HTML5, 'UTF-8'));
                        $h1_matches = $token_match_count($h1_text, $target_tokens);
                    }
                }

                // Fields completed: 3 fields (each counts as 1 if non-empty)
                $fields_completed = 0;
                if (!empty($SEOtarget)) $fields_completed++;
                if (!empty($SEOsynonyms)) $fields_completed++;
                if (!empty($SEOkeywords)) $fields_completed++;

                // Checklist score is $score10 (0-10)

                // Token‑based partial: add fractional points for slug, title, H1
                $token_partial = 0;
                if ($token_count > 0) {
                    $token_partial = ($slug_matches / $token_count) + ($title_matches / $token_count) + ($h1_matches / $token_count);
                }

                // Total completed: fields + checklist + token partial (max 13)
                $total_completed = $fields_completed + $score10 + $token_partial;
                $percentage = round(($total_completed / 16) * 100);
                if ($percentage > 100) $percentage = 100;
                if ($percentage < 0) $percentage = 0;

                if (!empty($SEOtarget)) {
                    if (!isset($summary_10[$SEOtarget]) || $score10 > $summary_10[$SEOtarget]['score']) {
                        $summary_10[$SEOtarget] = ['score'=>$score10,'max'=>10,'stars'=>$stars_for($score10,10)];
                    }
                }

                ?>
                <div class="firefly-page-card" data-page-id="<?php echo $pid; ?>">
                    <div style="display: flex; justify-content: space-between; align-items: center;">
                        <h2 style="margin:0;"><a href="<?php echo esc_url($url); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html($title); ?></a></h2>
                        <span class="firefly-status-badge <?php echo $status_class; ?>"><?php echo $status_label; ?></span>
                    </div>

                    <div class="firefly-meta-grid">
                        <div class="firefly-meta-item">
                            <strong>SEOtarget</strong>
                            <div class="firefly-target-display"><?php echo $SEOtarget !== '' ? esc_html($SEOtarget) : '<span class="muted">Not set</span>'; ?></div>
</div>
                        <div class="firefly-meta-item">
                            <strong>SEOsynonyms</strong>
                            <div class="firefly-synonyms-display"><?php echo $SEOsynonyms !== '' ? esc_html($SEOsynonyms) : '<span class="muted">—</span>'; ?></div>
                        </div>
                        <div class="firefly-meta-item">
                            <strong>SEOkeywords</strong>
                            <div class="firefly-keywords-display"><?php echo $SEOkeywords !== '' ? esc_html($SEOkeywords) : '<span class="muted">—</span>'; ?></div>
                        </div>
                    </div><?php
 

                        if (  $SEOtarget == "" AND $SEOsynonyms == "" AND $SEOkeywords == "" ) {
                            echo "<div style='background-color:red;padding:10px;text-align:center; color:white;'>THERE IS NO SEO FOR THIS PAGE!!</div>";
                        }
                        
                    ?>

                    <div class="progress-bar">
                        <div class="progress-bar-fill" style="width:<?php echo $percentage; ?>%;"><?php echo $percentage; ?>%</div>
                    </div>
                    <div style="margin: 10px 0;">
                        <button type="button" class="button-link firefly-quick-edit" data-page-id="<?php echo $pid; ?>">Quick Edit</button> |
                        <button type="button" class="button ff-open-url" data-url="<?php echo esc_attr($edit_url); ?>">Full Wizard</button> |
                        <button type="button" class="button ff-open-url" data-url="<?php echo esc_attr($page_edit_url); ?>">Edit page</button>
                    </div>

                    <!-- Quick Edit Form (hidden) -->
                    <div id="quick-edit-<?php echo $pid; ?>" style="display:none; margin-top:15px; border-top:1px solid #ddd; padding-top:15px;">
                        <form class="firefly-quick-edit-form" data-page-id="<?php echo $pid; ?>">
                            <input type="hidden" name="page_id" value="<?php echo $pid; ?>">
                            <input type="hidden" name="action" value="firefly_seo_quick_save">
                            <input type="hidden" name="nonce" value="<?php echo esc_attr(wp_create_nonce('firefly_seo_quick_save')); ?>">
<p><label>SEOtarget:<br><input type="text" name="firefly_SEOtarget" value="<?php echo esc_attr($SEOtarget); ?>" style="width:100%;"></label></p>
                            <p><label>SEOsynonyms:<br><textarea name="firefly_SEOsynonyms" rows="3" style="width:100%;"><?php echo esc_textarea($SEOsynonyms); ?></textarea></label></p>
                            <p><label>SEOkeywords:<br><textarea name="firefly_SEOkeywords" rows="3" style="width:100%;"><?php echo esc_textarea($SEOkeywords); ?></textarea></label></p>
                            <p><button type="submit" class="button button-primary">Save</button> <button type="button" class="button firefly-cancel-quick-edit" data-page-id="<?php echo $pid; ?>">Cancel</button> <span class="spinner" style="float:none; margin-top:0;"></span></p>
                        </form>
                    </div>

                    <!-- Checklist (collapsible) -->
<details style="margin-top:15px;" closed>
    <summary style="cursor:pointer; font-weight:bold;">Checklist (<?php echo $score10; ?>/10 completed)</summary>

    <?php
        $detail = isset($checklist['detail']) && is_array($checklist['detail']) ? $checklist['detail'] : [];
        $edit_content_url = $page_edit_url ? $page_edit_url : '';
        // helper: safe get detail
        $dget = function($k) use ($detail) {
            if (isset($detail[$k]) && is_array($detail[$k])) return $detail[$k];
            return ['map'=>[], 'hits'=>0, 'tot'=>0];
        };

        // status + pills for item
        $render_item = function($k, $lab, $rec = '') use ($dget, $edit_content_url) {
            $d = $dget($k);
            $map = isset($d['map']) && is_array($d['map']) ? $d['map'] : [];
            $hits = isset($d['hits']) ? (int)$d['hits'] : 0;
            $tot  = isset($d['tot'])  ? (int)$d['tot']  : 0;
            [$statusText, $statusCls] = firefly_status_label($hits, $tot);
            $pills = firefly_render_pills($map);
            ?>
            <div class="ff-check-row" style="border:1px solid #eee; border-radius:12px; padding:12px; margin:10px 0; background:#fff;">
                <div style="display:flex; align-items:flex-start; gap:10px;">
                    <div style="width:28px; font-weight:700; color:#555;"><?php echo esc_html($k); ?>.</div>
                    <div style="flex:1;">
                        <div style="display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;">
                            <div style="font-size:18px; font-weight:600;"><?php echo esc_html($lab); ?><?php if ($tot>0): ?> (<?php echo $hits; ?>/<?php echo $tot; ?>)<?php endif; ?></div>
                            <div class="<?php echo esc_attr($statusCls); ?>" style="font-weight:800; font-size:22px; letter-spacing:.5px;">
                                <?php echo esc_html($statusText); ?>
                            </div>
                        </div>
                        <?php echo $pills; ?>
                        <?php if ($statusText !== 'PASS' && $rec): ?>
                            <div style="margin-top:6px; color:#0b57d0; font-style:italic;">💡 <?php echo esc_html($rec); ?></div>
                        <?php endif; ?>

                        <?php if ($edit_content_url): ?>
                            <div style="margin-top:10px;">
                                <button type="button" class="button ff-open-url" data-url="<?php echo esc_url($edit_content_url); ?>">Edit page content</button>
                            </div>
                        <?php endif; ?>
                    </div>
                </div>
            </div>
            <?php
        };
    ?>

    <?php
        // a: URL slug includes SEOtarget (inline editor)
        $da = $dget('a'); [$ast,$acls] = firefly_status_label((int)$da['hits'], (int)$da['tot']);
    ?>
    <div class="ff-check-row" style="border:1px solid #eee; border-radius:12px; padding:12px; margin:10px 0; background:#fff;">
        <div style="display:flex; gap:10px;">
            <div style="width:28px; font-weight:700; color:#555;">a.</div>
            <div style="flex:1;">
                <div style="display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;">
                    <div style="font-size:18px; font-weight:600;"><?php echo esc_html($labels['a']); ?><?php if ((int)$da['tot']>0): ?> (<?php echo (int)$da['hits']; ?>/<?php echo (int)$da['tot']; ?>)<?php endif; ?></div>
                    <div class="<?php echo esc_attr($acls); ?>" style="font-weight:800; font-size:22px;"><?php echo esc_html($ast); ?></div>
                </div>
                <?php echo firefly_render_pills(isset($da['map']) ? (array)$da['map'] : []); ?>

                <div style="margin-top:10px;">
                    <form class="firefly-inline-save" data-page-id="<?php echo (int)$pid; ?>" data-refresh="2">
                        <input type="hidden" name="action" value="firefly_seo_quick_save">
                        <input type="hidden" name="nonce" value="<?php echo esc_attr(wp_create_nonce('firefly_seo_quick_save')); ?>">
                        <input type="hidden" name="page_id" value="<?php echo (int)$pid; ?>">
                        <label style="font-weight:600;">Edit page URL:</label>
                        <input type="text" name="post_name" value="<?php echo esc_attr($slug); ?>" style="width:260px; max-width:70%;">
                        <button type="submit" class="button">Save</button>
                        <span class="ff-save-msg" style="margin-left:8px; color:#0a6b2b; display:none;">Saved</span>
                    </form>
                </div>

                <?php if (!empty($recommendations['a']) && $ast !== 'PASS'): ?>
                    <div style="margin-top:6px; color:#0b57d0; font-style:italic;">💡 <?php echo esc_html($recommendations['a']); ?></div>
                <?php endif; ?>

                <?php if ($page_edit_url): ?>
                    <div style="margin-top:10px;">
                        <button type="button" class="button ff-open-url" data-url="<?php echo esc_url($page_edit_url); ?>">Edit page content</button>
                    </div>
                <?php endif; ?>
            </div>
        </div>
    </div>

    <?php
        // b: Title includes SEOtarget (inline editor)
        $db = $dget('b'); [$bst,$bcls] = firefly_status_label((int)$db['hits'], (int)$db['tot']);
    ?>
    <div class="ff-check-row" style="border:1px solid #eee; border-radius:12px; padding:12px; margin:10px 0; background:#fff;">
        <div style="display:flex; gap:10px;">
            <div style="width:28px; font-weight:700; color:#555;">b.</div>
            <div style="flex:1;">
                <div style="display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;">
                    <div style="font-size:18px; font-weight:600;"><?php echo esc_html($labels['b']); ?><?php if ((int)$db['tot']>0): ?> (<?php echo (int)$db['hits']; ?>/<?php echo (int)$db['tot']; ?>)<?php endif; ?></div>
                    <div class="<?php echo esc_attr($bcls); ?>" style="font-weight:800; font-size:22px;"><?php echo esc_html($bst); ?></div>
                </div>
                <?php echo firefly_render_pills(isset($db['map']) ? (array)$db['map'] : []); ?>

                <div style="margin-top:10px;">
                    <form class="firefly-inline-save" data-page-id="<?php echo (int)$pid; ?>" data-refresh="2">
                        <input type="hidden" name="action" value="firefly_seo_quick_save">
                        <input type="hidden" name="nonce" value="<?php echo esc_attr(wp_create_nonce('firefly_seo_quick_save')); ?>">
                        <input type="hidden" name="page_id" value="<?php echo (int)$pid; ?>">
                        <label style="font-weight:600;">Edit page title:</label>
                        <input type="text" name="post_title" value="<?php echo esc_attr($title); ?>" style="width:420px; max-width:85%;">
                        <button type="submit" class="button">Save</button>
                        <span class="ff-save-msg" style="margin-left:8px; color:#0a6b2b; display:none;">Saved</span>
                    </form>
                </div>

                <?php if (!empty($recommendations['b']) && $bst !== 'PASS'): ?>
                    <div style="margin-top:6px; color:#0b57d0; font-style:italic;">💡 <?php echo esc_html($recommendations['b']); ?></div>
                <?php endif; ?>

                <?php if ($page_edit_url): ?>
                    <div style="margin-top:10px;">
                        <button type="button" class="button ff-open-url" data-url="<?php echo esc_url($page_edit_url); ?>">Edit page content</button>
                    </div>
                <?php endif; ?>
            </div>
        </div>
    </div>

    <?php
        // c–h with same pills/status
        $render_item('c', $labels['c'], $recommendations['c'] ?? '');
        $render_item('d', $labels['d'], $recommendations['d'] ?? '');
        $render_item('e', $labels['e'], $recommendations['e'] ?? '');
        $render_item('f', $labels['f'], $recommendations['f'] ?? '');
        $render_item('g', $labels['g'], $recommendations['g'] ?? '');
        $render_item('h', $labels['h'], $recommendations['h'] ?? '');
        $render_item('i', $labels['i'], $recommendations['i'] ?? '');
$render_item('j', $labels['j'], $recommendations['j'] ?? '');
    ?>

</details>

                </div>
                <?php
            }
            ?>
        </div>
        <?php
    }

    echo ob_get_clean();
    wp_die();
});

/* ============================================================
 *  G) AJAX handler for quick edit save (including post title & slug)
 * ============================================================ */
add_action('wp_ajax_firefly_seo_quick_save', function() {
    if (!current_user_can('edit_pages')) {
        wp_send_json_error('Unauthorized');
    }
    $nonce = isset($_POST['nonce']) ? $_POST['nonce'] : '';
    if (!wp_verify_nonce($nonce, 'firefly_seo_quick_save')) {
        wp_send_json_error('Invalid nonce');
    }
    $page_id = isset($_POST['page_id']) ? intval($_POST['page_id']) : 0;
    if (!$page_id) {
        wp_send_json_error('No page ID');
    }

    // Update post title and slug if provided
    $post_data = [];
    if (isset($_POST['post_title'])) {
        $post_data['post_title'] = sanitize_text_field($_POST['post_title']);
    }
    if (isset($_POST['post_name'])) {
        $post_data['post_name'] = sanitize_title($_POST['post_name']);
    }
    if (!empty($post_data)) {
        $post_data['ID'] = $page_id;
        wp_update_post($post_data);
    }

    // Update meta fields (ONLY if the field was submitted, so slug/title edits don't wipe SEO settings)
    if (isset($_POST['firefly_SEOtarget'])) {
        $target = sanitize_text_field($_POST['firefly_SEOtarget']);
        update_post_meta($page_id, 'SEOtarget', $target);
    } else {
        $target = (string) get_post_meta($page_id, 'SEOtarget', true);
    }

    if (isset($_POST['firefly_SEOsynonyms'])) {
        $synonyms = sanitize_textarea_field($_POST['firefly_SEOsynonyms']);
        update_post_meta($page_id, 'SEOsynonyms', $synonyms);
    } else {
        $synonyms = (string) get_post_meta($page_id, 'SEOsynonyms', true);
    }

    if (isset($_POST['firefly_SEOkeywords'])) {
        $keywords = sanitize_textarea_field($_POST['firefly_SEOkeywords']);
        update_post_meta($page_id, 'SEOkeywords', $keywords);
    } else {
        $keywords = (string) get_post_meta($page_id, 'SEOkeywords', true);
    }

    // Get updated title (in case it was changed)
    $updated_post = get_post($page_id);

    wp_send_json_success([
        'post_title'   => $updated_post ? $updated_post->post_title : '',
        'SEOtarget'    => $target,
        'SEOsynonyms'  => $synonyms,
        'SEOkeywords'  => $keywords,
    ]);
});
