/* WPSiteBeam Scanner — Tech/DNS Tab, Recs Tab, ScanModeHelp
   Auto-split from Scanner.jsx.
*/
(function () {
  'use strict';
  const ScanEmptyState = window.ScanEmptyState;
  const Icon = window.Icon;

function ScannerTechTab({ data, payloads }) {
  const tech = data?.tech || null;
  const dns  = data?.dns  || [];

  /* Empty-state: no tech info at all */
  if (!tech || (!tech.platform && !tech.version && (!tech.plugins || !tech.plugins.length))) {
    return <ScanEmptyState tab="tech / DNS" reason="Platform detection requires a successful scan. DNS record lookup is a planned feature." />;
  }

  /* Small italic-helper element for "not detected" placeholders,
     matching Brand Identity's em() pattern exactly. */
  const em = (label) => <span style={{ color:'var(--muted)', fontSize:'.78rem', fontStyle:'italic' }}>— {label}</span>;

  /* "Also Detected" — secondary platforms from signature scan.
     Same logic as Brand Identity used before this split. */
  const alsoDetected = (() => {
    const dp = tech.detectedPlatforms;
    if (!Array.isArray(dp) || dp.length < 2) return null;
    return dp.slice(1, 4).map(p => {
      const name = p.name || p.id || 'unknown';
      const conf = p.confidence != null ? String(p.confidence) : null;
      return conf ? `${name} (${conf})` : name;
    }).join(', ');
  })();

  /* Tech Stack rows — pairs of [leftLabel, leftValue, rightLabel, rightValue]
     rendered in a 4-column grid (label/value/label/value). Same layout as
     the old Brand Identity field grid — moved here so Brand Kit only shows
     brand data, and Tech/DNS is where you actually look for stack info. */
  const techRows = [
    ['Website Builder', tech.platform !== 'Unknown' ? tech.platform : em('not detected'),
     'Platform Version', tech.version || em('not detected')],
    ['Also Detected', alsoDetected || em('no other platforms'),
     'CMS', tech.cms || em('not detected')],
    ['Hosting', tech.hosting || em('not detected'),
     'CDN', tech.cdn || em('not detected')],
    ['Server', tech.serverSoftware || em('not detected'),
     'Server', tech.serverSoftware || em('not detected'),
     'Powered By', (() => {
       /* Header X-Powered-By (PHP/nginx version) */
       if (tech.poweredBy) return tech.poweredBy;
       /* Designer/agency attribution from footer (designed by, built by, etc.) */
       const attrs = Array.isArray(data.designerAttribution) ? data.designerAttribution : [];
       const designerTypes = ['designer','developer','maintainer'];
       const platformTypes = ['platform'];
       const designer = attrs.find(a => designerTypes.includes(a.type));
       const platform = attrs.find(a => platformTypes.includes(a.type));
       if (designer) {
         return designer.url
           ? <a href={designer.url} target="_blank" rel="noopener" style={{ color:'var(--beam)', textDecoration:'none' }}>{designer.name} ({designer.type})</a>
           : <span>{designer.name} <span style={{ color:'var(--dim)', fontSize:'.72rem' }}>({designer.type})</span></span>;
       }
       if (platform) return platform.name;
       return em('not disclosed');
     })()],
    ['SSL', tech.hasSSL ? <span style={{ color:'var(--green)' }}>✓ HTTPS active</span> : <span style={{ color:'var(--warn)' }}>⚠ No SSL</span>,
     'HTTP Status', tech.httpStatus ? String(tech.httpStatus) : em('not captured')],
    ['Migration Complexity', data.migrationComplexity && data.migrationComplexity !== 'Unknown' ? data.migrationComplexity : em('not assessed'),
     'Detection Confidence', tech.confidence || em('not rated')],
  ];

  return (
    <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
      {/* Tech Stack — full width, 2-column grid like Brand Identity */}
      <div className="card">
        <div className="card-head">
          <h2 className="card-title">Tech Stack</h2>
          <div style={{ display:'flex', gap:6, alignItems:'center' }}>
            <span className="tag beam">{tech.platform !== 'Unknown' ? tech.platform : 'Detected'}</span>
            <button className="btn btn-ghost btn-sm"
                    onClick={() => window.wpsbDownload(`${data.site}-tech.json`, JSON.stringify(tech, null, 2), 'application/json')}>
              <Icon name="download" size={12}/>JSON
            </button>
          </div>
        </div>
        <div className="card-body">
          {/* Designer attribution banner — shows when footer attribution detected */}
          {Array.isArray(data.designerAttribution) && data.designerAttribution.length > 0 && (
            <div style={{ marginBottom:12, padding:'10px 14px', borderRadius:7,
              background:'var(--beam-dim)', border:'1px solid var(--beam-dim)',
              display:'flex', gap:16, flexWrap:'wrap', fontSize:'.78rem' }}>
              {data.designerAttribution.map((attr, i) => (
                <div key={i} style={{ display:'flex', gap:6, alignItems:'center' }}>
                  <span style={{ color:'var(--dim)', fontFamily:'var(--font-mono)', fontSize:'.68rem', textTransform:'uppercase' }}>
                    {attr.type === 'designer' ? 'Designed by' :
                     attr.type === 'developer' ? 'Developed by' :
                     attr.type === 'maintainer' ? 'Maintained by' :
                     attr.type === 'platform' ? 'Powered by' : attr.type}:
                  </span>
                  {attr.url
                    ? <a href={attr.url} target="_blank" rel="noopener" style={{ color:'var(--beam)', fontWeight:600, textDecoration:'none' }}>{attr.name}</a>
                    : <span style={{ color:'var(--text)', fontWeight:600 }}>{attr.name}</span>
                  }
                </div>
              ))}
            </div>
          )}
          {/* 4-column grid: label/value/label/value — matches Brand Identity
              original layout, keeps Tech Stack scannable at a glance. */}
          <div style={{
            display:'grid',
            gridTemplateColumns:'auto 1fr auto 1fr',
            gap:'8px 16px',
            fontSize:'.82rem',
            alignItems:'baseline',
          }}>
            {techRows.map(([lLabel, lVal, rLabel, rVal], i) => (
              <React.Fragment key={i}>
                <span style={{ color:'var(--dim)', fontFamily:'var(--font-mono)', fontSize:'.7rem', whiteSpace:'nowrap' }}>{lLabel}:</span>
                <span style={{ color:'var(--text)' }}>{lVal}</span>
                <span style={{ color:'var(--dim)', fontFamily:'var(--font-mono)', fontSize:'.7rem', whiteSpace:'nowrap' }}>{rLabel}:</span>
                <span style={{ color:'var(--text)' }}>{rVal}</span>
              </React.Fragment>
            ))}
          </div>
        </div>
      </div>

      {/* Round 7: removed the duplicate "Detected plugins" card from this
          tab. Plugin enumeration with category, version, vendor link, and
          forms detection lives in the dedicated Plugins & Forms tab.
          Keeping it in two places caused: (a) confusion about which is
          authoritative, (b) drift risk when one renderer was updated and
          the other wasn't. Show a small navigation hint when plugins are
          detected so users discover the dedicated tab. */}
      {tech.plugins && tech.plugins.length > 0 && (
        <div style={{
          padding:'10px 14px', borderRadius:6,
          background:'var(--beam-dim)',
          border:'1px solid var(--beam-dim)',
          fontSize:'.78rem', color:'var(--muted)',
          display:'flex', alignItems:'center', gap:8,
        }}>
          <Icon name="info" size={14}/>
          <span>
            <strong style={{ color:'var(--text)' }}>{tech.plugins.length} plugin{tech.plugins.length === 1 ? '' : 's'} detected</strong>
            {' — see the '}
            <span style={{ color:'var(--beam)', fontFamily:'var(--font-mono)' }}>Plugins &amp; Forms</span>
            {' tab for the full list with versions, categories, and vendor links.'}
          </span>
        </div>
      )}

      {/* DNS records — populated by enrichDnsData() post-scan */}
      {dns.length === 0 ? (
        <div className="card">
          <div className="card-head"><h2 className="card-title">DNS Records</h2></div>
          <div className="card-body" style={{ padding:'24px 20px', color:'var(--muted)', fontSize:'.8rem' }}>
            <div style={{ display:'flex', gap:16, alignItems:'flex-start' }}>
              <div style={{ flexShrink:0, width:48, height:48, borderRadius:'50%', background:'var(--surface-2, rgba(255,255,255,0.04))', border:'1px solid var(--border)', display:'inline-flex', alignItems:'center', justifyContent:'center', color:'var(--dim)' }}>
                <Icon name="server" size={22}/>
              </div>
              <div style={{ flex:1, minWidth:0, textAlign:'left' }}>
                <div style={{ fontSize:'.96rem', fontWeight:600, color:'var(--text)', marginBottom:6 }}>DNS lookup returned no records</div>
                <div style={{ lineHeight:1.6 }}>
                  This can happen if the domain doesn't have public DNS records (uncommon), or the lookup timed out. Re-running the scan usually fixes it.
                </div>
              </div>
            </div>
          </div>
        </div>
      ) : (
        <div className="card">
          <div className="card-head">
            <h2 className="card-title">DNS Records ({dns.length})</h2>
            <div style={{ display:'flex', gap:6, alignItems:'center', flexWrap:'wrap' }}>
              <button className="btn btn-ghost btn-sm"
                      onClick={() => exportDnsForCloudflare(data, dns)}
                      title="Download a BIND zone file for one-click import into Cloudflare"
              >
                <Icon name="download" size={12}/>Export to Cloudflare
              </button>
              <button className="btn btn-ghost btn-sm"
                      onClick={() => window.wpsbDownload(`${data.site}-dns.csv`, payloads.dnsCsv || dnsToCSV(dns), 'text/csv')}>
                <Icon name="download" size={12}/>CSV
              </button>
            </div>
          </div>
          <div className="card-body" style={{ padding:'10px 14px 0' }}>
            <div style={{ fontSize:'.72rem', color:'var(--dim)', marginBottom:10, lineHeight:1.5 }}>
              <strong style={{ color:'var(--text)' }}>Export to Cloudflare:</strong> downloads a BIND zone file you can upload at Cloudflare → DNS → Records → Import (for new domains) or paste record-by-record.
            </div>
          </div>
          <div className="card-body" style={{ padding: 0 }}>
            <table className="table">
              <thead><tr><th scope="col" style={{ width:90 }}>Type</th><th scope="col">Host</th><th scope="col">Value</th><th scope="col" style={{ width:50 }} aria-label="Copy value"></th></tr></thead>
              <tbody>
                {dns.map((r, i) => (
                  <tr key={i}>
                    <td>
                      <span className="tag" style={{
                        background: typeColor(r.type).bg,
                        color: typeColor(r.type).fg,
                        border: `1px solid ${typeColor(r.type).border}`,
                      }}>{r.type}</span>
                    </td>
                    <td className="mono" style={{ fontSize:'.72rem' }}>{r.host}</td>
                    <td className="mono" style={{ fontSize:'.72rem', color:'var(--beam)', wordBreak:'break-all' }}>
                      {r.val}
                    </td>
                    <td>
                      {/* Explicit Copy button — accessible affordance beyond
                          just "value is clickable." Replaces the old prose
                          "Click any value to copy" instruction per ADA best
                          practice (visible affordance > instructional text). */}
                      <button
                        onClick={() => window.wpsbCopy(r.val, `Copied ${r.type} value`)}
                        aria-label={`Copy ${r.type} record value: ${r.val}`}
                        title={`Copy ${r.val}`}
                        style={{
                          background:'var(--surface-2, rgba(255,255,255,0.04))',
                          border:'1px solid var(--border)',
                          borderRadius:4,
                          padding:'4px 8px',
                          cursor:'pointer',
                          color:'var(--dim)',
                          display:'inline-flex',
                          alignItems:'center',
                          gap:4,
                          fontSize:'.7rem',
                          fontFamily:'var(--font-mono)',
                        }}
                        onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--beam)'; e.currentTarget.style.borderColor = 'var(--beam-dim)'; }}
                        onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--dim)'; e.currentTarget.style.borderColor = 'var(--border)'; }}
                      >
                        <Icon name="copy" size={10}/>
                        <span>Copy</span>
                      </button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </div>
  );
}

/* ── DNS helper functions (used by ScannerTechTab) ─────────────────────────
   typeColor: returns color scheme per DNS record type for visual scanning.
   dnsToCSV: fallback CSV builder if payloads.dnsCsv isn't populated.
   exportDnsForCloudflare: builds a BIND zone file and triggers download.
   Cloudflare's import expects BIND format (RFC 1035) — it's the de-facto
   standard and our most reliable portability format. */
function typeColor(type) {
  switch (type) {
    case 'A':     return { bg:'var(--beam-dim)', fg:'var(--beam)',   border:'var(--beam-dim)' };
    case 'AAAA':  return { bg:'var(--beam-dim)', fg:'var(--beam)',   border:'var(--beam-dim)' };
    case 'CNAME': return { bg:'var(--purple-dim)', fg:'var(--purple)',      border:'var(--purple-dim)' };
    case 'MX':    return { bg:'var(--warn-dim)', fg:'var(--warn)',      border:'var(--warn-dim)' };
    case 'NS':    return { bg:'rgba(107,114,128,.12)', fg:'var(--muted)', border:'rgba(107,114,128,.3)' };
    case 'TXT':   return { bg:'var(--green-dim)', fg:'var(--green)',       border:'var(--green-dim)' };
    case 'SPF':   return { bg:'var(--green-dim)', fg:'var(--green)',       border:'var(--green-dim)' };
    case 'DMARC': return { bg:'var(--rose-dim)', fg:'var(--rose)',     border:'var(--rose-dim)' };
    default:      return { bg:'var(--surface-2)', fg:'var(--dim)',       border:'var(--border)' };
  }
}

function dnsToCSV(dns) {
  const rows = [['Type', 'Host', 'Value']];
  dns.forEach(r => rows.push([r.type, r.host, r.val]));
  return rows.map(r => r.map(cell => {
    const s = String(cell || '');
    return /[,"\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
  }).join(',')).join('\n');
}

function exportDnsForCloudflare(data, dns) {
  /* Build a BIND zone file (RFC 1035 format). Cloudflare imports this
     directly at DNS → Records → Import. We include a standard TTL of
     3600 and the origin declaration at the top. */
  const apex = data.site || 'example.com';
  const ttl = 3600;

  const lines = [
    `; BIND zone file for ${apex}`,
    `; Generated by WPSiteBeam scanner on ${new Date().toISOString()}`,
    `; Import at Cloudflare: DNS → Records → Import and Export → Import`,
    `;`,
    `; NOTE: Review before import. Delete or edit any records that differ`,
    `;       from what you want in your new Cloudflare zone. Nameserver`,
    `;       (NS) records are NOT needed — Cloudflare provides its own.`,
    `;`,
    `$ORIGIN ${apex}.`,
    `$TTL ${ttl}`,
    ``,
  ];

  /* A records */
  dns.filter(r => r.type === 'A').forEach(r => {
    lines.push(`${r.host === apex ? '@' : r.host.replace('.' + apex, '')}\t${ttl}\tIN\tA\t${r.val}`);
  });

  /* AAAA records */
  dns.filter(r => r.type === 'AAAA').forEach(r => {
    lines.push(`${r.host === apex ? '@' : r.host.replace('.' + apex, '')}\t${ttl}\tIN\tAAAA\t${r.val}`);
  });

  /* CNAME records */
  dns.filter(r => r.type === 'CNAME').forEach(r => {
    const name = r.host.endsWith('.' + apex) ? r.host.slice(0, -(apex.length + 1)) : r.host;
    const target = r.val.endsWith('.') ? r.val : r.val + '.';
    lines.push(`${name}\t${ttl}\tIN\tCNAME\t${target}`);
  });

  /* MX records — value is "priority host" */
  dns.filter(r => r.type === 'MX').forEach(r => {
    const [priority, mxHost] = r.val.split(/\s+/);
    const target = (mxHost || '').endsWith('.') ? mxHost : (mxHost || '') + '.';
    lines.push(`@\t${ttl}\tIN\tMX\t${priority || 10}\t${target}`);
  });

  /* TXT / SPF — wrap value in quotes */
  dns.filter(r => r.type === 'TXT' || r.type === 'SPF').forEach(r => {
    const safe = r.val.replace(/"/g, '\\"');
    lines.push(`@\t${ttl}\tIN\tTXT\t"${safe}"`);
  });

  /* DMARC — special TXT at _dmarc subdomain */
  dns.filter(r => r.type === 'DMARC').forEach(r => {
    const safe = r.val.replace(/"/g, '\\"');
    lines.push(`_dmarc\t${ttl}\tIN\tTXT\t"${safe}"`);
  });

  /* Skip NS — Cloudflare assigns its own nameservers */

  const zone = lines.join('\n') + '\n';
  const filename = `${apex}-dns-cloudflare.zone`;
  window.wpsbDownload?.(filename, zone, 'text/plain');
  window.wpsbToast?.(`Downloaded ${filename} — upload at Cloudflare DNS Import`, 'ok');
}

/* ScannerMapsTab + ScannerIconsTab removed — content consolidated into
   Contact tab (Maps) and Brand Kit tab (Icon Libraries). See the inline
   blocks in those components. */

/* ── saveRecsToDashboard ─────────────────────────────────────────
   Pushes scan recommendations to the user's dashboard queue via
   Railway endpoint POST /dashboard/recommendations, which inserts
   to Supabase table ai_recommendations.

   Required Supabase schema (run manually — see docs):
     CREATE TABLE ai_recommendations (
       id           UUID PRIMARY KEY DEFAULT gen_random_uuid(),
       account_id   UUID REFERENCES accounts(id),
       site         TEXT NOT NULL,
       message      TEXT NOT NULL,
       category     TEXT NOT NULL,
       priority     TEXT CHECK (priority IN ('low','med','high')) DEFAULT 'med',
       status       TEXT CHECK (status IN ('pending','done','dismissed')) DEFAULT 'pending',
       source       TEXT DEFAULT 'scanner',
       scan_id      TEXT,
       created_at   TIMESTAMPTZ DEFAULT NOW(),
       updated_at   TIMESTAMPTZ DEFAULT NOW()
     );
     CREATE INDEX idx_ai_recs_account_status ON ai_recommendations(account_id, status);

   Required Railway endpoint (pending — see task list):
     POST /dashboard/recommendations
     Auth: requireJWT('wpsb-app')
     Body: { site, recs: [{message, category, priority}] }
     Response: { count, ids: [...] }
*/
async function saveRecsToDashboard(data, recs) {
  if (!recs || recs.length === 0) {
    window.wpsbToast?.('No recommendations to save', 'warn');
    return;
  }

  const RAILWAY = (typeof window !== 'undefined' && window.WPSB_API)
    || 'https://wpsitebeam-railway-api-production.up.railway.app';
  const token = (typeof window !== 'undefined' && window.WPSB?.getToken?.()) || null;

  if (!token) {
    window.wpsbToast?.('Please sign in to save recommendations', 'warn');
    return;
  }

  const payload = {
    site: data?.site || 'unknown',
    scan_id: data?.scanId || null,
    recs: recs.map(([message, category, priority, type]) => ({
      message,
      category,
      priority,
      source: 'scanner',
      type,  /* 'migration' or 'warning' */
    })),
  };

  try {
    window.wpsbToast?.(`Saving ${recs.length} recommendation${recs.length === 1 ? '' : 's'}…`, 'ok');
    const r = await fetch(`${RAILWAY}/dashboard/recommendations`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + token,
      },
      body: JSON.stringify(payload),
    });

    if (r.status === 404) {
      /* Endpoint not deployed yet — honest fallback */
      window.wpsbToast?.('Dashboard integration coming soon — endpoint not yet deployed.', 'warn');
      return;
    }
    if (!r.ok) {
      const errText = await r.text().catch(() => 'Unknown error');
      window.wpsbToast?.(`Save failed (${r.status}): ${errText.substring(0, 100)}`, 'warn');
      return;
    }

    const j = await r.json();
    window.wpsbToast?.(`Saved ${j.count || recs.length} recommendation${(j.count || recs.length) === 1 ? '' : 's'} to your dashboard`, 'ok');
  } catch (e) {
    if (typeof console !== 'undefined') console.warn('[saveRecsToDashboard] Network error:', e);
    window.wpsbToast?.(`Couldn't save: ${e.message}`, 'warn');
  }
}

function ScannerRecsTab({ data }) {
  const { useState } = React;

  /* Build recommendations list from real migration notes + warnings.
     Fallback to a static "no recs yet" state if nothing returned. */
  const realRecs = [];
  (data?.migrationNotes || []).forEach(n => {
    if (!n || !n.message) return;
    const pri = n.severity === 'high' ? 'high'
              : n.severity === 'medium' || n.severity === 'med' ? 'med'
              : 'low';
    realRecs.push([n.message, n.area || 'Migration', pri, 'migration']);
  });
  (data?.warnings || []).forEach(w => {
    const txt = typeof w === 'string' ? w : (w.message || w.text || '');
    if (!txt) return;
    realRecs.push([txt, 'Warning', 'med', 'warning']);
  });

  /* Add AI summary as a "fix plan" if Brain 4 was active */
  const hasAISummary = !!(data?.aiSummary);

  const [expanded, setExpanded] = useState(null);

  if (realRecs.length === 0 && !hasAISummary) {
    return (
      <div className="card">
        <div className="card-head"><h2 className="card-title">AI Recommendations</h2><span className="tag">No issues found</span></div>
        <div className="card-body" style={{ padding:'40px 20px', textAlign:'center', color:'var(--muted)' }}>
          <div style={{ fontSize:'2rem', marginBottom:10 }}>✓</div>
          <div style={{ fontSize:'.9rem', fontWeight:600, color:'var(--text)', marginBottom:6 }}>
            No migration issues detected
          </div>
          <div style={{ fontSize:'.8rem' }}>
            This site has no blockers or warnings flagged by the scanner. Enable AI-powered analysis in your account settings for deeper insights.
          </div>
        </div>
      </div>
    );
  }

  return (
    <>
      {hasAISummary && (
        <div className="card" style={{ marginBottom: 14 }}>
          <div className="card-head">
            <h2 className="card-title">AI Summary</h2>
            <span className="tag beam">AI-POWERED</span>
          </div>
          <div className="card-body" style={{ fontSize:'.88rem', lineHeight:1.6, whiteSpace:'pre-wrap', color:'var(--text-2)' }}>
            {data.aiSummary}
          </div>
        </div>
      )}

      {realRecs.length > 0 && (
        <div className="card">
          <div className="card-head">
            <h2 className="card-title">Migration Notes &amp; Warnings</h2>
            <div style={{ display:'flex', gap:8, alignItems:'center' }}>
              <span className="tag">{realRecs.length} item{realRecs.length === 1 ? '' : 's'}</span>
              {/* Save to Dashboard — pushes recs to Supabase ai_recommendations
                  table as a pending to-do queue. Target endpoint on Railway:
                  POST /dashboard/recommendations { site, recs[] }. See
                  saveRecsToDashboard() below for shape + error handling. */}
              <button className="btn btn-primary btn-sm"
                      onClick={() => saveRecsToDashboard(data, realRecs)}
                      title="Push these recommendations to your account's dashboard queue">
                <Icon name="spark" size={12}/>Save to Dashboard
              </button>
            </div>
          </div>
          <div className="card-body" style={{ padding: 0 }}>
            {realRecs.map(([txt, cat, pri, type], i) => (
              <div key={i}>
                <div style={{ display:'flex', gap:12, padding:'14px 18px', borderBottom: expanded===i ? 'none' : (i<realRecs.length-1 ? '1px solid var(--border)' : 'none'), alignItems:'center' }}>
                  <div style={{ width:28, height:28, borderRadius:6, background: type === 'warning' ? 'var(--warn-dim)' : 'var(--beam-dim)', color: type === 'warning' ? 'var(--warn)' : 'var(--beam)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                    <Icon name={type === 'warning' ? 'warn' : 'spark'} size={14}/>
                  </div>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ fontSize:'.88rem', fontWeight:600 }}>{txt}</div>
                    <div style={{ fontSize:'.72rem', color:'var(--dim)', textTransform:'capitalize' }}>{cat}</div>
                  </div>
                  <span className={`tag ${pri==='high'?'bad':pri==='med'?'warn':''}`}>{pri.toUpperCase()}</span>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}
    </>
  );
}

/* ScannerSeoTab removed — per-page SEO meta is shown inside Pages tab
   (Identity · On-Page SEO · Page Structure sections). Aggregate SEO
   scoring would require server-side changes that aren't in place yet;
   re-add the tab if/when seoPages[] is populated by the scan engine. */


/* ── Scan Mode Help modal ─────────────────────────────────────── */
function ScanModeHelp({ onClose }) {
  const rows = [
    ['Colors · fonts · logos', true, false],
    ['Images · favicon · typography', true, false],
    ['Contact info (emails/phones)', 'opt', false],
    ['SEO meta · per-page data', 'opt', false],
    ['Maps · icon libraries', 'opt', false],
    ['Platform detection (WP / Joomla / Drupal)', false, true],
    ['Platform version fingerprint', false, true],
    ['URL inventory (full crawl)', false, true],
    ['XML sitemap parsing', false, true],
    ['Navigation menu extraction', false, true],
    ['Document discovery (PDFs, Office)', false, true],
    ['Migration complexity score', false, true],
    ['Migration time estimate', false, true],
    ['CMS extensions / plugins', false, true],
    ['Counts against monthly scan limit', false, true],
  ];
  const mark = v => v === true ? <span style={{ color:'var(--green)' }}>✓</span>
                   : v === 'opt' ? <span style={{ color:'var(--dim)', fontFamily:'var(--font-mono)', fontSize:'.66rem' }}>opt</span>
                   : <span style={{ color:'var(--dimmer, #4a6080)' }}>—</span>;

  return (
    <div onClick={onClose}
         style={{ position:'fixed', inset:0, background:'rgba(0,0,0,.6)', backdropFilter:'blur(4px)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }}>
      <div onClick={e => e.stopPropagation()}
           style={{ background:'var(--surface)', border:'1px solid var(--border2, var(--border))', borderRadius:10, maxWidth:720, width:'100%', maxHeight:'90vh', overflow:'auto' }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', padding:'14px 18px', borderBottom:'1px solid var(--border)' }}>
          <strong style={{ fontSize:'.92rem' }}>What's included in each scan type?</strong>
          <button onClick={onClose} style={{ background:'none', border:'none', color:'var(--dim)', fontSize:'1.2rem', cursor:'pointer' }}>✕</button>
        </div>
        <div style={{ padding:18 }}>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12, marginBottom:14 }}>
            <div style={{ padding:14, background:'var(--green-dim)', border:'1px solid var(--green-dim)', borderRadius:8 }}>
              <div style={{ display:'flex', gap:6, alignItems:'center', marginBottom:6 }}>
                <strong>Brand Extraction</strong>
                <span style={{ fontFamily:'var(--font-mono)', fontSize:'.58rem', padding:'2px 7px', borderRadius:4, background:'var(--gdim)', border:'1px solid var(--green-dim)', color:'var(--green)' }}>FREE</span>
              </div>
              <div style={{ fontSize:'.72rem', color:'var(--dim)', lineHeight:1.5 }}>
                Browser-side · ~10 sec. Extracts visual brand assets from the homepage. Always free on every plan.
              </div>
            </div>
            <div style={{ padding:14, background:'var(--beam-dim)', border:'1px solid var(--beam-dim)', borderRadius:8 }}>
              <div style={{ display:'flex', gap:6, alignItems:'center', marginBottom:6 }}>
                <strong>Platform &amp; Migration</strong>
                <span style={{ fontFamily:'var(--font-mono)', fontSize:'.58rem', padding:'2px 7px', borderRadius:4, background:'var(--beam-dim)', border:'1px solid var(--beam-dim)', color:'var(--beam)' }}>1 SCAN</span>
              </div>
              <div style={{ fontSize:'.72rem', color:'var(--dim)', lineHeight:1.5 }}>
                Server-side · ~30-90 sec. Deep platform analysis, URL inventory, migration scoping. Uses 1 scan from your monthly quota.
              </div>
            </div>
          </div>

          <div style={{ padding:12, background:'rgba(155,109,255,.06)', border:'1px solid rgba(155,109,255,.3)', borderRadius:8, marginBottom:14, fontSize:'.74rem', color:'var(--text-2)' }}>
            <strong style={{ color:'var(--purple)' }}>Run both together</strong> — they execute in parallel and merge into a unified report. Best for migration scoping from brand-new prospects.
          </div>

          <table className="table" style={{ fontSize:'.76rem' }}>
            <thead>
              <tr>
                <th scope="col">Feature</th>
                <th scope="col" style={{ textAlign:'center', width:120, color:'var(--green)' }}>Brand</th>
                <th scope="col" style={{ textAlign:'center', width:120, color:'var(--beam)' }}>Platform</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(([label, b, p]) => (
                <tr key={label}>
                  <td>{label}</td>
                  <td style={{ textAlign:'center' }}>{mark(b)}</td>
                  <td style={{ textAlign:'center' }}>{mark(p)}</td>
                </tr>
              ))}
            </tbody>
          </table>
          <div style={{ fontSize:'.66rem', color:'var(--dim)', marginTop:10, fontFamily:'var(--font-mono)' }}>
            ✓ included   ·   opt = via Advanced options checkbox   ·   — not available
          </div>
        </div>
      </div>
    </div>
  );
}


window.ScannerTechTab = ScannerTechTab;
window.ScannerRecsTab = ScannerRecsTab;
window.ScanModeHelp = ScanModeHelp;
})();
