// OPT-QC-07 · Threshold breach warning (inline state on the DM/FFA entry list)
const QcBreach = ({ t, go }) => {
  const { Btn, Stepper, Banner } = window.Op;
  const Ic = window.Icons, QD = window.QD;
  const state = t.breach; // single | multiSame | mixed | across
  const E = QD.EVENT, m = QD.matrixFor(E.variety, E.stage), dm = m.dm;
  const [why, setWhy] = useState(false);

  // value sets per state
  let vals = [22.4, 19.2, 23.6]; // single (S2 below)
  if (state === "multiSame") vals = [19.4, 18.8, 19.9];        // all below
  if (state === "mixed") vals = [19.4, 23.6, 29.4];            // S1 below, S3 above
  if (state === "across") vals = [22.4, 19.2, 23.6];           // DM breach + FFA breach
  const ffaVals = state === "across" ? [0.42, 2.45, 0.48] : null;

  const evals = vals.map(v => QD.evalDM(v, dm));
  const below = evals.filter(e => e.dir === "below").length;
  const above = evals.filter(e => e.dir === "above").length;
  const breachN = evals.filter(e => e.state === "out").length;

  let bannerTitle = "";
  if (state === "single") bannerTitle = "1 sample breaches the DM threshold (below 21%)";
  else if (state === "multiSame") bannerTitle = `${breachN} of ${vals.length} samples below DM threshold (target ≥ ${dm.min}%)`;
  else if (state === "mixed") bannerTitle = `${below} sample below, ${above} above the DM threshold`;
  else bannerTitle = "Breaches in both DM and FFA";

  const Chip = ({ e }) => (
    <span className={`badge ${e.tone === "green" ? "badge-approved" : e.tone === "amber" ? "badge-pending" : e.tone === "red" ? "badge-rejected" : "badge-closed"}`} style={{ whiteSpace: "nowrap" }}>
      {e.tone === "green" ? <Ic.Check size={12}/> : e.tone === "red" ? <Ic.Warning size={12}/> : null} {e.label}
    </span>
  );

  const breachIdx = evals.findIndex(e => e.state === "out");

  return (
    <div className="op-body" style={{ display: "flex", flexDirection: "column" }}>
      <div className="op-pad" style={{ flex: 1 }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", margin: "2px 0 16px" }}>
          <Stepper steps={["Start", "Sampling", "Parameters", "Decision"]} current={2}/>
          <div className="op-tabs">
            <button className="on">DM{state === "across" && " ⚠"}</button>
            <button>FFA{state === "across" && " ⚠"}</button>
            <button>External</button>
          </div>
        </div>

        {/* (1) Banner treatment */}
        <div style={{ marginBottom: 14 }}>
          <Banner tone="danger" icon={Ic.Warning} title={bannerTitle}
            desc={<>The breach is advisory here — you can keep entering values. The block (if any) happens at the decision step. <button className="op-scan-link" style={{ color: "var(--destructive)", fontSize: 13 }} onClick={() => setWhy(true)}>Why?</button></>}/>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1.55fr 1fr", gap: 18, alignItems: "start" }}>
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "11px 16px", borderRadius: "var(--radius-lg)", border: "1px solid var(--border)", background: "var(--card)", marginBottom: 12 }}>
              <Ic.Thermometer size={18} style={{ color: "var(--avocado-fg)" }}/>
              <div style={{ flex: 1 }}><div style={{ fontSize: 13.5, fontWeight: 600 }}>{E.variety} · {E.stage} — Dry Matter</div><div className="op-muted" style={{ fontSize: 12 }}>Accept {dm.min}–{dm.max}% · target {dm.target}%</div></div>
            </div>

            {/* (2) Row + (3) field treatment */}
            <div className="op-card flush">
              {vals.map((v, i) => {
                const e = evals[i];
                const bad = e.state === "out";
                return (
                  <div key={i} style={{ display: "grid", gridTemplateColumns: "46px 150px 1fr", gap: 14, alignItems: "center", padding: "14px 16px", borderBottom: i < vals.length - 1 ? "1px solid var(--border)" : "none", background: bad ? "oklch(from var(--destructive) l c h / 0.08)" : "transparent" }}>
                    <span className="op-check-num" style={{ background: bad ? "var(--destructive)" : "var(--foreground)" }}>{E.samples[i].id}</span>
                    <div style={{ display: "flex", alignItems: "center", height: 50, border: `2px solid ${bad ? "var(--destructive)" : "var(--input)"}`, borderRadius: "var(--radius-lg)", background: "var(--card)", overflow: "hidden", boxShadow: bad ? "0 0 0 3px oklch(from var(--destructive) l c h / 0.14)" : "none" }}>
                      <input className="op-num-input" style={{ fontSize: 24, height: "100%", color: bad ? "var(--destructive)" : "var(--foreground)" }} defaultValue={v.toFixed(1)} inputMode="decimal"/>
                      <span style={{ fontSize: 13, color: "var(--muted-foreground)", padding: "0 12px", fontWeight: 600 }}>%</span>
                    </div>
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <Chip e={e}/>
                      <input className="op-input" style={{ height: 40, fontSize: 13, flex: 1, borderColor: bad ? "oklch(from var(--destructive) l c h / 0.5)" : undefined }} placeholder={bad ? "Remark required for approve-despite-breach…" : "Remark (optional)"}/>
                    </div>
                  </div>
                );
              })}
            </div>

            {state === "across" && (
              <div className="op-card flush" style={{ marginTop: 12 }}>
                <div className="op-card-head" style={{ paddingBottom: 8 }}><div className="op-card-title" style={{ fontSize: 13.5, color: "var(--destructive)" }}>FFA — 1 sample over limit</div></div>
                {ffaVals.map((v, i) => {
                  const e = QD.evalFFA(v, m.ffa); const bad = e.state === "out";
                  return (
                    <div key={i} style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 16px", borderTop: "1px solid var(--border)", background: bad ? "oklch(from var(--destructive) l c h / 0.08)" : "transparent" }}>
                      <span className="op-check-num" style={{ width: 22, height: 22, fontSize: 11, background: bad ? "var(--destructive)" : "var(--foreground)" }}>{E.samples[i].id}</span>
                      <span style={{ fontSize: 15, fontWeight: 700, fontVariantNumeric: "tabular-nums", width: 70, color: bad ? "var(--destructive)" : "inherit" }}>{v.toFixed(3)}%</span>
                      <Chip e={e}/>
                    </div>
                  );
                })}
              </div>
            )}
          </div>

          {/* Decision support panel with elevated Reject */}
          <div className="op-card op-card-pad">
            <div style={{ fontSize: 14.5, fontWeight: 600, marginBottom: 6 }}>Decision support</div>
            <div className="op-muted" style={{ fontSize: 12.5, lineHeight: 1.5, marginBottom: 14 }}>The breach signal elevates the reject path. Approve is still available but tones down — and requires a supervisor PIN.</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              <Btn variant="destructive" block icon={Ic.X} style={{ background: "var(--destructive)", color: "#fff", borderColor: "var(--destructive)", height: 56 }} onClick={() => go("decision")}>Reject</Btn>
              <Btn variant="outline" block icon={Ic.Check} style={{ height: 56, opacity: 0.7 }} onClick={() => go("decision")}>Approve (needs supervisor)</Btn>
            </div>
            <div className="op-divider"/>
            <div className="op-muted" style={{ fontSize: 11.5, lineHeight: 1.5 }}>Every breach signal raised is logged for analytics, independent of the final decision.</div>
          </div>
        </div>
      </div>

      <div className="op-actionbar">
        <Btn variant="ghost" onClick={() => go("dmParam")}>Re-enter values</Btn>
        <div className="op-ab-grow"/>
        <Btn variant="primary" icon={Ic.ArrowRight} onClick={() => go("decision")}>Continue to decision</Btn>
      </div>

      {/* Why? bottom-sheet explainer */}
      {why && (
        <div className="op-modal-scrim" style={{ alignItems: "flex-end", padding: 0 }} onClick={(e) => { if (e.target === e.currentTarget) setWhy(false); }}>
          <div style={{ width: "100%", background: "var(--card)", borderTopLeftRadius: 22, borderTopRightRadius: 22, borderTop: "1px solid var(--border)", padding: "20px 28px 28px", animation: "op-pop .2s ease", maxHeight: "70%", overflowY: "auto" }}>
            <div style={{ width: 44, height: 5, borderRadius: 3, background: "var(--border)", margin: "0 auto 18px" }}/>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14 }}>
              <div style={{ fontSize: 18, fontWeight: 700 }}>Why is this a breach?</div>
              <button className="op-iconbtn ghost" onClick={() => setWhy(false)}><Ic.X size={18}/></button>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 14, marginBottom: 18 }}>
              {[["Matrix range", `${dm.min}–${dm.max}%`, "Accept window for " + E.variety + " at " + E.stage], ["This sample", `${vals[breachIdx].toFixed(1)}%`, "Recorded reading"], ["Distance", `${(dm.min - vals[breachIdx]).toFixed(1)}%`, "Below the lower boundary"]].map(([k, v, s]) => (
                <div key={k} style={{ padding: "14px 16px", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid var(--border)" }}>
                  <div className="op-muted" style={{ fontSize: 11.5, fontWeight: 600 }}>{k}</div>
                  <div style={{ fontSize: 24, fontWeight: 700, fontVariantNumeric: "tabular-nums", margin: "4px 0 2px" }}>{v}</div>
                  <div className="op-muted" style={{ fontSize: 11.5, lineHeight: 1.4 }}>{s}</div>
                </div>
              ))}
            </div>
            <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 8 }}>Common causes of low Dry Matter</div>
            <ul style={{ margin: 0, paddingLeft: 18, fontSize: 13, color: "var(--muted-foreground)", lineHeight: 1.7 }}>
              <li>Fruit harvested before reaching maturity (immature oil content).</li>
              <li>Heavy rains in the days before harvest dilute dry matter.</li>
              <li>Sampling bias — pieces drawn from one shaded part of the load.</li>
            </ul>
          </div>
        </div>
      )}
    </div>
  );
};

window.OptPages = Object.assign(window.OptPages || {}, {
  breach: { chrome: "flow", title: "Parameters — GPN-…0041", sub: "Step 3 of 4 · Threshold breach", back: "sampling", render: (ctx) => <QcBreach {...ctx}/> },
});
