/* global React, window */
// =========================================================
// QualityCheck — one audit engine, two surfaces.
//   buildBriefAudit(ctx)  -> { issues, sections, stats }  (single source of truth)
//   <ConfidenceNav>       -> Concept 1: ambient left rail flagging inferred/at-risk
//   <SecConfChip>         -> per-section header chip mirroring the rail
//   <FieldFlag>           -> inline flag pinned to a specific wrong field
//   <InspectionReport>    -> Concept 2: the gate punch-list MakerLabs runs on Build
// Both surfaces read the SAME audit + the SAME in-session `resolved` set, so
// fixing a thing in one place calms the other.
// =========================================================
const { useState: useStateQC } = React;

// Sections as they actually stack in the brief (superset of INTAKE.SECTIONS).
const QC_SECTIONS = [
  { id: "goals",       label: "Objectives" },
  { id: "decision",    label: "Decision context" },
  { id: "audience",    label: "Questions" },
  { id: "morecontext", label: "Additional context" },
];
// How much of each section MakerLabs drafted for you (the "inferred" signal).
const QC_INFERRED = { goals: 3, decision: 3, audience: 4, morecontext: 1 };

// Severity vocabulary. wrong = likely-wrong (contradiction). check = an
// inference worth confirming. gap = missing / optional.
const SEV = {
  wrong: { rank: 0, label: "Likely wrong", cls: "wrong",
    icon: <path d="M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z" /> },
  check: { rank: 1, label: "Worth a look", cls: "check",
    icon: <><circle cx="12" cy="12" r="9" /><path d="M9.2 9a2.8 2.8 0 0 1 5.4 1c0 1.8-2.6 2.5-2.6 2.5M12 17h.01" /></> },
  gap:   { rank: 2, label: "Missing", cls: "gap",
    icon: <><circle cx="12" cy="12" r="9" strokeDasharray="3 3" /><path d="M12 8v8M8 12h8" /></> },
};
function SevIcon({ sev, size = 16 }) {
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">{(SEV[sev] || SEV.check).icon}</svg>;
}

// ---- the engine: derive issues from the live brief ------------------------
function buildBriefAudit(ctx) {
  ctx = ctx || {};
  const fp = ctx.firstPass || {};
  const mc = ctx.moreContext || (window.INTAKE && window.INTAKE.FALLBACK.moreContext) || {};
  const hay = ((fp.name || "") + " " + (fp.audience || "") + " " + ((fp.goals || []).join(" ")) + " " + (fp.situation || "")).toLowerCase();
  const womens = /wom(a|e)n|female|ladies|her\b/.test(hay);
  const issues = [];

  // 1) Category contradicts the audience — reads LIVE ctx, so fixing it clears.
  const cat = (mc.category || "").trim();
  const catMens = /\bmen'?s?\b|\bmale\b|\bboys?\b/i.test(cat) && !/wom|female|girl|unisex/i.test(cat);
  if (cat && womens && catMens) {
    issues.push({ id: "cat-gender", sev: "wrong", section: "decision", anchor: "decision", field: "category",
      title: "Category says “" + cat + "” — but this is a women’s study",
      detail: "The goals and audience are all women’s lifestyle. This tag will mis-file the study and its products downstream.",
      cta: "Fix category", clearLabel: "Ignore" });
  }

  // 2) You'll read by retailer account, but nothing captures it.
  if (/retailer e|retailer f|retailer|\baccount\b/.test(hay)) {
    issues.push({ id: "retailer-cut", sev: "check", section: "audience", anchor: "audience",
      title: "You plan to read results by retailer account",
      detail: "Goals cut by Retailer E & Retailer F shoppers — but no screener or filter records which account a respondent shops.",
      cta: "Review audience", clearLabel: "It’s covered" });
  }

  // 3) Markets were assumed, not stated.
  issues.push({ id: "geo-assumed", sev: "check", section: "audience", anchor: "audience",
    title: "Markets were assumed, not stated",
    detail: "You didn’t name markets, so Geo defaulted to your three contract markets (US, Canada, UK). Confirm or change.",
    cta: "Review markets", clearLabel: "Confirm markets" });

  // 4) Income screener is an inference that narrows recruitment.
  issues.push({ id: "income-assumed", sev: "check", section: "audience", anchor: "audience",
    title: "Household-income screener is an inference",
    detail: "Income was skewed to $75k+ from the premium sell-in goal — that narrows recruitment. Confirm it’s intended.",
    cta: "Review screener", clearLabel: "Confirm skew" });

  // 5) Optional gap.
  if (!(mc.notes || "").trim()) {
    issues.push({ id: "notes-gap", sev: "gap", section: "morecontext", anchor: "morecontext",
      title: "No additional notes",
      detail: "Optional — internal constraints or things to revisit. Fine to leave blank.",
      cta: "Add a note", clearLabel: "Skip" });
  }

  issues.sort((a, b) => SEV[a.sev].rank - SEV[b.sev].rank);

  // per-section rollup
  const sections = QC_SECTIONS.map(s => {
    const mine = issues.filter(i => i.section === s.id);
    const hasWrong = mine.some(i => i.sev === "wrong");
    const openish = mine.filter(i => i.sev !== "gap").length;
    return { ...s, inferred: QC_INFERRED[s.id] || 0, issues: mine, hasWrong, checkCount: openish };
  });
  return { issues, sections };
}

// state of a section, given which issues the user has cleared this session
function secState(sec, resolved) {
  const open = sec.issues.filter(i => !resolved.has(i.id));
  if (open.some(i => i.sev === "wrong")) return "flag";
  if (open.some(i => i.sev === "check")) return "check";
  if (sec.inferred > 0) return "inf";
  return "ok";
}

// ============================ Concept 1: ambient nav ============================
function ConfidenceNav({ audit, resolved, onJump }) {
  const open = audit.issues.filter(i => !resolved.has(i.id));
  const wrong = open.filter(i => i.sev === "wrong").length;
  const toCheck = open.filter(i => i.sev === "check").length;
  const inferred = audit.sections.reduce((n, s) => n + s.inferred, 0);
  return (
    <nav className="ix-cnav" aria-label="Brief review">
      <div className="ix-cnav__hd">
        <span className="ix-cnav__ey">✦ MakerLabs drafted this</span>
        <div className="ix-cnav__stat">{inferred}<i> fields inferred</i></div>
        <div className="ix-cnav__sub">
          {wrong > 0 && <span className="ix-cnav__flagn">{wrong} looks off</span>}
          {wrong > 0 && toCheck > 0 && <span className="ix-cnav__dot">·</span>}
          {toCheck > 0 && <span>{toCheck} worth a check</span>}
          {wrong === 0 && toCheck === 0 && <span className="ix-cnav__clear">Nothing flagged</span>}
        </div>
      </div>
      <div className="ix-cnav__list">
        {audit.sections.map(sec => {
          const st = secState(sec, resolved);
          const checks = sec.issues.filter(i => !resolved.has(i.id) && i.sev === "check").length;
          return (
            <button key={sec.id} className="ix-cnav__item" data-state={st} onClick={() => onJump && onJump(sec.id)}>
              <span className="ix-cnav__pip" />
              <span className="ix-cnav__lbl">{sec.label}</span>
              <span className="ix-cnav__meta">
                {st === "flag" && <span className="ix-cnav__flag"><SevIcon sev="wrong" size={13} /> check</span>}
                {st === "check" && <span className="ix-cnav__amber">{checks} to check</span>}
                {st === "inf" && <span className="ix-cnav__inf">{sec.inferred} inferred</span>}
                {st === "ok" && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg>}
              </span>
            </button>
          );
        })}
      </div>
      <div className="ix-cnav__foot">Click a section to jump to it. Confirm inferences in the build check.</div>
    </nav>
  );
}

// per-section header chip (mirrors the rail state on the card itself)
function SecConfChip({ audit, resolved, secId }) {
  const sec = audit.sections.find(s => s.id === secId);
  if (!sec) return null;
  const st = secState(sec, resolved);
  const checks = sec.issues.filter(i => !resolved.has(i.id) && i.sev === "check").length;
  if (st === "flag") return <span className="ix-secconf ix-secconf--flag"><SevIcon sev="wrong" size={12} /> Needs a look</span>;
  if (st === "check") return <span className="ix-secconf ix-secconf--review">✦ {checks} to check</span>;
  if (st === "inf") return <span className="ix-secconf ix-secconf--inf">✦ {sec.inferred} inferred</span>;
  return <span className="ix-secconf ix-secconf--ok"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg> Reviewed</span>;
}

// inline flag pinned under a specific wrong field (e.g. Category)
function FieldFlag({ issue, onJump }) {
  if (!issue) return null;
  return (
    <div className="ix-fflag" data-sev={issue.sev}>
      <span className="ix-fflag__ic"><SevIcon sev={issue.sev} size={14} /></span>
      <div className="ix-fflag__tx">
        <span className="ix-fflag__t">{issue.title}</span>
        <span className="ix-fflag__d">{issue.detail}</span>
      </div>
    </div>
  );
}

// ============================ Concept 2: gate inspection ============================
function InspectionReport({ audit, resolved, onResolve, onJump, onBuild, locked, loading }) {
  const issues = audit.issues;
  const open = issues.filter(i => !resolved.has(i.id));
  const wrong = open.filter(i => i.sev === "wrong").length;
  const checks = open.filter(i => i.sev === "check").length;
  const cleared = issues.length - open.length;

  if (loading) {
    return (
      <div className="ix-insp ix-insp--loading">
        <div className="ix-insp__hd"><span className="ix-insp__ey">✦ Brief inspection</span></div>
        <div className="ix-insp__scanning">
          <span className="ix-think"><span /><span /><span /></span>
          Checking goals, audience and context against your brief…
        </div>
      </div>
    );
  }
  if (locked) {
    return (
      <div className="ix-insp ix-insp--done">
        <span className="ix-insp__doneic"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg></span>
        Inspection passed — building the study
      </div>
    );
  }

  const verdict = wrong > 0
    ? <><b className="ix-insp__wrong">{wrong} looks wrong</b>{checks > 0 ? <> and {checks} {checks === 1 ? "is" : "are"} worth a glance</> : null} before I build.</>
    : checks > 0
      ? <>Nothing looks wrong — but {checks} {checks === 1 ? "inference is" : "inferences are"} worth confirming before I build.</>
      : <>Everything checks out. Ready to build.</>;

  return (
    <div className="ix-insp">
      <div className="ix-insp__hd">
        <span className="ix-insp__ey">✦ Brief inspection</span>
        <span className="ix-insp__scan">checked {audit.sections.reduce((n, s) => n + s.inferred, 0)} fields against your goals</span>
      </div>
      <div className="ix-insp__verdict">{verdict}</div>
      <div className="ix-insp__rows">
        {issues.map(iss => {
          const done = resolved.has(iss.id);
          return (
            <div key={iss.id} className={"ix-insp__row" + (done ? " is-done" : "")} data-sev={iss.sev}>
              <span className="ix-insp__ic">
                {done ? <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg> : <SevIcon sev={iss.sev} />}
              </span>
              <div className="ix-insp__main">
                <div className="ix-insp__title">{iss.title}</div>
                {!done && <div className="ix-insp__detail">{iss.detail}</div>}
                {!done ? (
                  <div className="ix-insp__acts">
                    <button className="ix-insp__jump" onClick={() => onJump && onJump(iss.anchor, iss.field)}>
                      {iss.cta}
                      <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" /></svg>
                    </button>
                    <button className="ix-insp__clear" onClick={() => onResolve && onResolve(iss.id, true)}>{iss.clearLabel || "Mark resolved"}</button>
                  </div>
                ) : (
                  <button className="ix-insp__undo" onClick={() => onResolve && onResolve(iss.id, false)}>Undo</button>
                )}
              </div>
            </div>
          );
        })}
      </div>
      <div className="ix-insp__foot">
        <span className="ix-insp__prog">{cleared} of {issues.length} cleared</span>
        <button className={"ix-insp__build" + (open.length === 0 ? " is-clear" : "")} onClick={() => onBuild && onBuild()}>
          {open.length === 0 ? "Build study" : "Build anyway"}
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" /></svg>
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { buildBriefAudit, secState, ConfidenceNav, SecConfChip, FieldFlag, InspectionReport, QC_SECTIONS, BriefNav });

// Plain section navigator — labels that jump, no stats, no flags.
function BriefNav({ sections, active, onJump }) {
  return (
    <nav className="ix-bnav" aria-label="Brief sections">
      {(sections || []).map(s => (
        <button key={s.id} className={"ix-bnav__item" + (active === s.id ? " on" : "")} onClick={() => onJump && onJump(s.id)}>
          {s.label}
        </button>
      ))}
    </nav>
  );
}
