// LongtailIQ app, keyword results table (the centerpiece)
(function init(){
if(!window.LongtailIQDesignSystem_ae8f12){return setTimeout(init,30);}
const React = window.React;
const DS = window.LongtailIQDesignSystem_ae8f12;
const { Checkbox, OpportunityScore, Icon, Badge } = DS;
const { IntentBadge, PlatformBadge, Difficulty, Demand, Score } = window.LTQ;
const t = (k, v) => (window.LTQ.t ? window.LTQ.t(k, v) : k);

// The explainable moat: a plain-English reason behind each opportunity score, derived from the row's signals.
function whyFor(row) {
  const r = [];
  if (row.diff <= 22) r.push(t("results.why_lowcomp"));
  if (["Commercial", "Transactional"].includes(row.intent)) r.push(t("results.why_buyer"));
  if (/Comparison/i.test(row.intent)) r.push(t("results.why_comparison"));
  if (/AI Overview|AI answer/i.test(row.serp)) r.push(t("results.why_aio"));
  if (/Reddit/i.test(row.platform) || /Reddit/i.test(row.intent)) r.push(t("results.why_community"));
  if (row.funnel === "Decision") r.push(t("results.why_decision"));
  if (row.demand >= 2000) r.push(t("results.why_demand"));
  if (!r.length) r.push(t("results.why_solid"));
  return r.slice(0, 2).join(" · ");
}

const COLS = [
  { key: "sel", w: 40 },
  { key: "q", w: 360, align: "left" },
  { key: "intent", w: 150 },
  { key: "funnel", w: 130 },
  { key: "platform", w: 140 },
  { key: "demand", w: 110 },
  { key: "diff", w: 120 },
  { key: "score", w: 200 },
  { key: "why", w: 230, align: "left" },
  { key: "serp", w: 150 },
  { key: "type", w: 150 },
  { key: "actions", w: 132 },
];
// SERP stays a fixed technical label; actions has no header.
const colLabel = (key) => (key === "serp" ? "SERP / GEO" : key === "actions" || key === "sel" ? "" : t("results.col_" + key));

function RowActions({ row, onBrief, onSave }) {
  const copy = async () => { try { await navigator.clipboard.writeText(row.q); window.LTQ.toast && window.LTQ.toast(t("research.copied")); } catch (e) { window.LTQ.toast && window.LTQ.toast(t("settings.copy_manual"), { tone: "warning" }); } };
  const acts = [
    { icon: "bookmark-plus", t: t("research.save_to_list_btn"), on: () => onSave && onSave(row) },
    { icon: "copy", t: t("research.copy_keyword"), on: copy },
    { icon: "file-pen-line", t: t("results.generate_brief"), on: () => onBrief && onBrief(row), hot: true },
  ];
  return (
    <div className="lt-rowacts" style={{ display: "flex", gap: 2, opacity: 0, transition: "opacity var(--dur-base)" }}>
      {acts.map(a => (
        <button key={a.t} title={a.t} onClick={a.on} style={{ width: 28, height: 28, display: "grid", placeItems: "center",
          border: "none", background: "transparent", borderRadius: "var(--r-xs)", cursor: "pointer", color: a.hot ? "var(--accent-600)" : "var(--text-faint)" }}
          onMouseEnter={e=>{e.currentTarget.style.background="var(--ink-100)";e.currentTarget.style.color=a.hot?"var(--accent-700)":"var(--text-strong)";}}
          onMouseLeave={e=>{e.currentTarget.style.background="transparent";e.currentTarget.style.color=a.hot?"var(--accent-600)":"var(--text-faint)";}}>
          <Icon name={a.icon} size={15} />
        </button>
      ))}
    </div>
  );
}

function Cell({ col, row, sel, onSel, onBrief, onSave }) {
  switch (col.key) {
    case "sel": return <Checkbox checked={sel} onChange={onSel} aria-label={t("results.select_row", { q: row.q })} />;
    case "q": return (
      <span style={{ display: "inline-flex", alignItems: "center", gap: 8, lineHeight: 1.35 }}>
        <span style={{ fontSize: 13.5, fontWeight: 600, color: "var(--text-strong)", letterSpacing: "-0.01em" }}>{row.q}</span>
        {row.source === "gsc" && (
          <span title={t("results.gsc_badge_title")} style={{ flex: "none", display: "inline-flex", alignItems: "center", gap: 4, fontSize: 10, fontWeight: 700, letterSpacing: "0.02em", textTransform: "uppercase", color: "var(--accent-600)", background: "var(--accent-50, #ecfdf5)", border: "1px solid var(--accent-100)", borderRadius: 999, padding: "1px 7px" }}>
            <Icon name="radar" size={10} /> Search Console
          </span>
        )}
        {row.source === "google" && (
          <span title={t("results.google_badge_title")} style={{ flex: "none", display: "inline-flex", alignItems: "center", gap: 4, fontSize: 10, fontWeight: 700, letterSpacing: "0.02em", textTransform: "uppercase", color: "var(--viz-blue)", background: "var(--blue-50, #eff6ff)", border: "1px solid var(--border-subtle)", borderRadius: 999, padding: "1px 7px" }}>
            <Icon name="search" size={10} /> Google
          </span>
        )}
      </span>
    );
    case "intent": return <IntentBadge value={row.intent} />;
    case "funnel": return <span style={{ fontSize: 12.5, color: "var(--text-muted)", fontWeight: 600 }}>{window.LTQ.dataLabel("funnel", row.funnel)}</span>;
    case "platform": return <PlatformBadge value={row.platform} />;
    case "demand": return <Demand value={row.demand} />;
    case "diff": return <Difficulty value={row.diff} />;
    case "score": return <Score score={row.score} width={86} />;
    case "why": return (
      <span style={{ display: "inline-flex", alignItems: "center", gap: 7, fontSize: 12.5, color: "var(--text-body)", lineHeight: 1.3 }}>
        <span style={{ width: 5, height: 5, borderRadius: 999, background: "var(--accent-500)", flex: "none" }} />{whyFor(row)}
      </span>
    );
    case "serp": return <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12.5, color: "var(--text-body)", fontWeight: 600 }}><Icon name="target" size={13} style={{ color: "var(--accent-500)" }} />{window.LTQ.dataLabel("serp", row.serp)}</span>;
    case "type": return <span style={{ fontSize: 12.5, color: "var(--text-muted)" }}>{window.LTQ.dataLabel("type", row.type)}</span>;
    case "actions": return <RowActions row={row} onBrief={onBrief} onSave={onSave} />;
    default: return null;
  }
}

const SORTABLE = { q: "q", demand: "demand", diff: "diff", score: "score" };

// Phone rendering (≤ BP.phone): the 12-column table becomes tappable cards —
// keyword + score up top, identity badges beneath, the "why" line, and an
// always-visible action row (hover-reveal doesn't exist on touch).
function MobileRowCard({ row, sel, onSel, onRowClick, onBrief, onSave, last }) {
  const copy = async () => { try { await navigator.clipboard.writeText(row.q); window.LTQ.toast && window.LTQ.toast(t("research.copied")); } catch (e) { window.LTQ.toast && window.LTQ.toast(t("settings.copy_manual"), { tone: "warning" }); } };
  const stop = (e) => e.stopPropagation();
  const act = (label, icon, on, hot) => (
    <button onClick={(e) => { stop(e); on(); }} style={{ display: "inline-flex", alignItems: "center", gap: 6, minHeight: 40, padding: "0 12px",
      border: "1px solid var(--border-subtle)", borderRadius: 9, background: hot ? "var(--ink-900)" : "var(--paper)",
      color: hot ? "#fff" : "var(--text-body)", fontFamily: "var(--font-sans)", fontSize: 12.5, fontWeight: 600, cursor: "pointer" }}>
      <Icon name={icon} size={14} /> {label}
    </button>
  );
  return (
    <div onClick={() => onRowClick && onRowClick(row)} className="lt-press"
      style={{ padding: "14px 14px 12px", borderBottom: last ? "none" : "1px solid var(--border-subtle)",
        background: sel ? "var(--accent-50)" : "transparent", cursor: onRowClick ? "pointer" : "default",
        WebkitTapHighlightColor: "transparent" }}>
      <div style={{ display: "flex", alignItems: "flex-start", gap: 10 }}>
        <span onClick={stop} style={{ flex: "none", paddingTop: 2 }}><Checkbox checked={sel} onChange={onSel} aria-label={t("results.select_row", { q: row.q })} /></span>
        <span style={{ flex: 1, minWidth: 0, fontSize: 14.5, fontWeight: 600, color: "var(--text-strong)", letterSpacing: "-0.01em", lineHeight: 1.35 }}>{row.q}</span>
        <span style={{ flex: "none" }}><Score score={row.score} width={52} /></span>
      </div>
      <div style={{ display: "flex", alignItems: "center", flexWrap: "wrap", gap: "6px 14px", margin: "9px 0 0 30px" }}>
        <IntentBadge value={row.intent} />
        <Demand value={row.demand} />
        <Difficulty value={row.diff} />
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 7, margin: "8px 0 10px 30px", fontSize: 12, color: "var(--text-muted)", lineHeight: 1.35 }}>
        <span style={{ width: 5, height: 5, borderRadius: 999, background: "var(--accent-500)", flex: "none" }} />{whyFor(row)}
      </div>
      <div style={{ display: "flex", gap: 8, marginLeft: 30, flexWrap: "wrap" }}>
        {act(t("research.save_to_list_btn"), "bookmark-plus", () => onSave && onSave(row))}
        {act(t("research.copy_keyword"), "copy", copy)}
        {act(t("results.generate_brief"), "file-pen-line", () => onBrief && onBrief(row), true)}
      </div>
    </div>
  );
}

const MOBILE_SORTS = [
  { key: "score", icon: "trophy" },
  { key: "demand", icon: "trending-up" },
  { key: "diff", icon: "shield" },
  { key: "q", icon: "arrow-down-a-z" },
];

function ResultsTable({ rows, selected, onToggle, onToggleAll, onRowClick, onBrief, onSave }) {
  // Game-feel (phase 8): a NEW dataset (rows prop identity change) pops in
  // staggered; internal re-sorts reuse the same generation so they stay
  // instant — choreography announces new data only. Capped at 14 rows.
  const genRef = React.useRef(0);
  const lastRowsRef = React.useRef(null);
  if (lastRowsRef.current !== rows) { lastRowsRef.current = rows; genRef.current++; }
  const gen = genRef.current;
  const [sort, setSort] = React.useState({ key: "score", dir: "desc" });
  const phone = window.LTQ.usePhone ? window.LTQ.usePhone() : false;
  const clickSort = (key) => setSort((s) => (s.key === key ? { key, dir: s.dir === "asc" ? "desc" : "asc" } : { key, dir: key === "q" ? "asc" : "desc" }));
  const sorted = React.useMemo(() => {
    const arr = [...rows];
    const { key, dir } = sort;
    arr.sort((a, b) => {
      const av = a[key], bv = b[key];
      const cmp = typeof av === "string" ? av.localeCompare(bv) : (av || 0) - (bv || 0);
      return dir === "asc" ? cmp : -cmp;
    });
    return arr;
  }, [rows, sort]);
  rows = sorted;

  if (phone) {
    const allSelP = rows.length > 0 && rows.every(r => selected.has(r.q));
    return (
      <div>
        <div className="lt-scroll-x" style={{ display: "flex", alignItems: "center", gap: 6, paddingBottom: 10 }}>
          <button onClick={onToggleAll} aria-label={t("results.col_sel")} style={{ flex: "none", display: "inline-flex", alignItems: "center", justifyContent: "center", width: 40, minHeight: 36, border: "1px solid var(--border-subtle)", borderRadius: 999, background: allSelP ? "var(--ink-900)" : "var(--paper)", color: allSelP ? "#fff" : "var(--text-muted)", cursor: "pointer" }}>
            <Icon name="check-check" size={15} />
          </button>
          {MOBILE_SORTS.map((s) => {
            const on = sort.key === s.key;
            return (
              <button key={s.key} onClick={() => clickSort(s.key)}
                style={{ flex: "none", display: "inline-flex", alignItems: "center", gap: 6, minHeight: 36, padding: "0 13px",
                  border: "1px solid " + (on ? "var(--ink-900)" : "var(--border-subtle)"), borderRadius: 999,
                  background: on ? "var(--ink-900)" : "var(--paper)", color: on ? "#fff" : "var(--text-muted)",
                  fontFamily: "var(--font-sans)", fontSize: 12.5, fontWeight: 600, cursor: "pointer", whiteSpace: "nowrap" }}>
                <Icon name={s.icon} size={13} />{colLabel(s.key)}{on && <Icon name={sort.dir === "asc" ? "chevron-up" : "chevron-down"} size={13} />}
              </button>
            );
          })}
        </div>
        <div style={{ borderRadius: "var(--r-lg)", border: "1px solid var(--border-subtle)", background: "var(--surface-card)", boxShadow: "var(--shadow-sm)", overflow: "hidden" }}>
          {rows.map((row, ri) => (
            <MobileRowCard key={ri} row={row} sel={selected.has(row.q)} onSel={() => onToggle(row.q)}
              onRowClick={onRowClick} onBrief={onBrief} onSave={onSave} last={ri === rows.length - 1} />
          ))}
        </div>
      </div>
    );
  }
  const allSel = rows.length > 0 && rows.every(r => selected.has(r.q));
  const someSel = rows.some(r => selected.has(r.q));
  const stop = (e) => e.stopPropagation();
  return (
    <div className="lt-scroll" style={{ overflowX: "auto", borderRadius: "var(--r-lg)", border: "1px solid var(--border-subtle)", background: "var(--surface-card)", boxShadow: "var(--shadow-sm)" }}>
      <table style={{ borderCollapse: "collapse", width: "100%", minWidth: 1420 }}>
        <thead>
          <tr style={{ position: "sticky", top: 0, zIndex: 2 }}>
            {COLS.map(c => (
              <th key={c.key} style={{ width: c.w, minWidth: c.w, textAlign: c.align || (c.key==="sel"?"center":"left"),
                padding: c.key==="sel"?"0":"0 14px", height: 44, background: "var(--ink-50)",
                borderBottom: "1px solid var(--border-strong)", fontSize: 11, fontWeight: 700, textTransform: "uppercase",
                letterSpacing: "0.06em", color: "var(--text-faint)", whiteSpace: "nowrap" }}>
                {c.key === "sel"
                  ? <div style={{ display: "grid", placeItems: "center" }}><Checkbox checked={allSel} indeterminate={someSel && !allSel} onChange={onToggleAll} aria-label={t("results.col_sel")} /></div>
                  : SORTABLE[c.key]
                    ? <button onClick={() => clickSort(c.key)} style={{ display: "inline-flex", alignItems: "center", gap: 4, border: "none", background: "transparent", cursor: "pointer", font: "inherit", letterSpacing: "inherit", textTransform: "inherit", color: sort.key === c.key ? "var(--text-strong)" : "var(--text-faint)", fontWeight: 700, padding: 0 }}>
                        {colLabel(c.key)}{sort.key === c.key && <Icon name={sort.dir === "asc" ? "chevron-up" : "chevron-down"} size={13} />}
                      </button>
                    : colLabel(c.key)}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, ri) => {
            const sel = selected.has(row.q);
            return (
              <tr key={gen + ":" + ri} className={ri < 14 ? "lt-row lt-row-in" : "lt-row"} onClick={() => onRowClick && onRowClick(row)}
                style={{ background: sel ? "var(--accent-50)" : "transparent", transition: "background var(--dur-fast)", cursor: onRowClick ? "pointer" : "default", animationDelay: ri < 14 ? (ri * 24) + "ms" : undefined }}
                onMouseEnter={e=>{ if(!sel) e.currentTarget.style.background="var(--ink-50)"; e.currentTarget.querySelector(".lt-rowacts").style.opacity=1; }}
                onMouseLeave={e=>{ if(!sel) e.currentTarget.style.background="transparent"; e.currentTarget.querySelector(".lt-rowacts").style.opacity=0; }}>
                {COLS.map(c => (
                  <td key={c.key} onClick={(c.key==="sel"||c.key==="actions") ? stop : undefined}
                    style={{ padding: c.key==="sel"?"0":"14px", textAlign: c.key==="sel"?"center":"left",
                    borderBottom: ri < rows.length-1 ? "1px solid var(--border-subtle)" : "none", verticalAlign: "middle" }}>
                    <Cell col={c} row={row} sel={sel} onSel={() => onToggle(row.q)} onBrief={onBrief} onSave={onSave} />
                  </td>
                ))}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}
window.LTQ.ResultsTable = ResultsTable;
})();
