// Program Studio — Pipeline (enhanced)
// Adds: case-flow visualization (12,847 → N at each stage), hover-impact tooltips,
// smart suggestion card, animated case dots flowing through the pipeline.

function StudioPipeline({ rules, lib, selectedRuleIdx, onSelect, onMove, previewTrace, showLibrary, setShowLibrary, addRule, caseImpacts }) {
  const byCat = {};
  rules.forEach((r, i) => {
    const meta = lib.find((l) => l.id === r.ruleId);
    const cat = meta?.category || "Other";
    (byCat[cat] = byCat[cat] || []).push({ rule: r, idx: i, meta });
  });
  const lanes = ["Identity", "Affordability", "Housing History", "Documents", "Eligibility Gate", "Logic", "Other"]
    .filter((c) => byCat[c]);

  const { impacts, total, surviving } = caseImpacts;
  const passRate = (surviving / total);

  return (
    <div className="studio-pipeline">
      <div className="pipeline-head">
        <div>
          <div className="label-eyebrow">Decision pipeline</div>
          <div className="title" style={{fontSize:16, marginTop:4}}>How {total.toLocaleString()} cases flow through ISKAN</div>
          <div className="muted text-13" style={{marginTop:2}}>
            Auto-laid-out by category. Click a rule to configure · drag to reorder · the engine runs them in this exact order.
          </div>
        </div>
        <div className="row" style={{gap:6}}>
          <div className="pipe-funnel-stat">
            <span className="pipe-funnel-num">{Math.round(passRate * 100)}%</span>
            <span className="tiny muted">pass-through</span>
          </div>
          <button className="btn ghost sm"><Icon name="search" size={12}/></button>
          <button className="btn ghost sm"><Icon name="refresh" size={12}/> Auto-arrange</button>
        </div>
      </div>

<div className="pipeline-canvas">
        <div className="pipeline-source-card">
          <div className="ps-icon"><Icon name="user" size={18}/></div>
          <div style={{flex:1}}>
            <div className="text-13" style={{fontWeight:600}}>Incoming applications · last 90 days</div>
            <div className="tiny muted">National ID lookup · 7 attributes · 4 documents</div>
          </div>
          <div className="ps-count">
            <span className="ps-count-num">{total.toLocaleString()}</span>
            <span className="tiny muted">cases</span>
          </div>
        </div>

        <PipelineConnector animate/>

        {lanes.map((cat, laneIdx) => (
          <PipelineLane
            key={cat}
            category={cat}
            items={byCat[cat]}
            selectedIdx={selectedRuleIdx}
            onSelect={onSelect}
            previewTrace={previewTrace}
            laneIdx={laneIdx}
            impacts={impacts}
          />
        ))}

        <div className="pipeline-add-lane">
          <button className="add-rule-btn" onClick={() => setShowLibrary(true)}>
            <Icon name="plus" size={16}/> Add a rule
          </button>
          {showLibrary && <RuleLibrary lib={lib} onClose={() => setShowLibrary(false)} addRule={addRule} rules={rules}/>}
        </div>

        <PipelineConnector animate/>

        <div className="pipeline-output-card">
          <div className="po-card-head">
            <div>
              <div className="label-eyebrow">Outcomes</div>
              <div className="title" style={{marginTop:2, fontSize:14}}>{surviving.toLocaleString()} of {total.toLocaleString()} cases reach a final outcome</div>
            </div>
          </div>
          <div className="po-card-grid">
            <OutcomeBox kind="eligible" pct={71} count={Math.round(surviving * 0.71)} total={total} label="Eligible · STP" sub="Auto-route to chosen bank"/>
            <OutcomeBox kind="review" pct={22} count={Math.round(surviving * 0.22)} total={total} label="Needs review · Non-STP" sub="Assigned to analyst queue"/>
            <OutcomeBox kind="rejected" pct={7} count={Math.round(surviving * 0.07)} total={total} label="Not eligible" sub="Alternatives surfaced"/>
          </div>
        </div>
      </div>
    </div>
  );
}

function PipelineConnector() {
  return (
    <svg className="pipeline-connector" viewBox="0 0 20 36" preserveAspectRatio="none">
      <line x1="10" y1="0" x2="10" y2="36" stroke="var(--hairline)" strokeWidth="2" strokeDasharray="3 4"/>
    </svg>
  );
}

function OutcomeBox({ kind, pct, count, label, sub, total }) {
  return (
    <div className={`po-box outcome-${kind}`}>
      <div className="po-box-pct">{pct}<span className="po-box-pctsign">%</span></div>
      <div className="po-box-label">{label}</div>
      <div className="po-box-sub">{count.toLocaleString()} cases · {sub}</div>
    </div>
  );
}

function PipelineLane({ category, items, selectedIdx, onSelect, previewTrace, laneIdx, impacts }) {
  const tone = window.laneTone(category);
  return (
    <div className="pipe-lane">
      <div className="pipe-lane-head" style={{color: tone}}>
        <span className="pipe-lane-dot" style={{background: tone}}/>
        <span>{category}</span>
        <span className="muted tiny">· {items.length} rule{items.length !== 1 ? "s" : ""}</span>
      </div>
      <div className="pipe-lane-grid">
        {items.map(({ rule, idx, meta }) => {
          const traceItem = previewTrace.find((t) => t.ruleId === rule.ruleId);
          const passed = traceItem?.status;
          const imp = impacts[rule.ruleId];
          return (
            <button key={idx} className={`pipe-node ${selectedIdx === idx ? "selected" : ""} ${rule.enabled ? "" : "disabled"} status-${passed || "neutral"}`}
              onClick={() => onSelect(idx)}>
              <div className="pipe-node-bar" style={{background: tone}}/>
              <div className="pipe-node-head">
                <Icon name={meta?.icon || "doc"} size={14}/>
                <span className="pipe-node-title">{meta?.name || rule.ruleId}</span>
                {traceItem && (
                  <span className={`pipe-node-status ${passed}`}>
                    <Icon name={passed === "passed" ? "check" : passed === "warning" ? "alert" : "x"} size={11}/>
                  </span>
                )}
              </div>
              <div className="pipe-node-source">{meta?.source || "—"}</div>
              <div className="pipe-node-params">
                <ParamSummary ruleId={rule.ruleId} params={rule.params}/>
              </div>

              {/* NEW: case-flow indicator */}
              {imp && imp.wouldBlock > 0 && rule.enabled && (
                <div className="pipe-node-impact">
                  <Icon name="alert" size={10}/>
                  <span>blocks <strong>{imp.wouldBlock.toLocaleString()}</strong></span>
                  <span className="muted">of {imp.cumulative.toLocaleString()}</span>
                </div>
              )}
              {imp && imp.wouldBlock === 0 && rule.enabled && (
                <div className="pipe-node-impact ok">
                  <Icon name="check" size={10}/>
                  <span>all <strong>{imp.cumulative.toLocaleString()}</strong> pass</span>
                </div>
              )}

              <div className="pipe-node-sev">
                {meta?.severity === "reject" && <span className="pill bad" style={{height:18, fontSize:10}}>Hard</span>}
                {meta?.severity === "manual_review" && <span className="pill warn" style={{height:18, fontSize:10}}>Soft</span>}
                {meta?.severity === "info" && <span className="pill ghost" style={{height:18, fontSize:10}}>Logic</span>}
              </div>
            </button>
          );
        })}
      </div>
    </div>
  );
}

function SmartSuggestions({ rules, lib, caseImpacts, onApply }) {
  // Synthesize 2 contextual suggestions based on rule config
  const dtiRule = rules.find(r => r.ruleId === "dti");
  const incomeRule = rules.find(r => r.ruleId === "income-band");
  const dtiIdx = rules.findIndex(r => r.ruleId === "dti");

  const suggestions = [];
  if (dtiRule && dtiRule.params.max <= 60) {
    suggestions.push({
      kind: "policy",
      title: "Raise DTI threshold to 65%",
      reason: "847 cases failed only on DTI in the last 90 days. Bank of Oman raised theirs to 65% in Q2.",
      impact: "+12% STP rate",
      apply: dtiIdx,
    });
  }
  suggestions.push({
    kind: "anomaly",
    title: "12 Sohar cases blocked on income-band but earn above local median",
    reason: "Income band hasn't been re-calibrated for Sohar's wage growth (Q1 2026).",
    impact: "Sohar STP +6%",
    apply: rules.findIndex(r => r.ruleId === "income-band"),
  });

  return (
    <div className="smart-suggestions">
      <div className="suggest-head">
        <Icon name="sparkles" size={14} style={{color:"var(--brand-copper)"}}/>
        <span className="label-eyebrow" style={{color:"var(--brand-copper-deep)"}}>Smart suggestions</span>
        <span className="tiny muted">· based on the last 90 days of historical decisions</span>
      </div>
      <div className="suggest-row">
        {suggestions.map((s, i) => (
          <div key={i} className="suggest-card">
            <div className="suggest-tag">{s.kind === "policy" ? "Policy" : "Anomaly"}</div>
            <div className="suggest-title">{s.title}</div>
            <div className="suggest-reason">{s.reason}</div>
            <div className="suggest-foot">
              <span className="pill ok tiny">{s.impact}</span>
              <button className="btn ghost sm" onClick={() => onApply(s.apply)}>
                <Icon name="edit" size={11}/> Inspect
              </button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function ParamSummary({ ruleId, params }) {
  switch (ruleId) {
    case "nationality": return <>= <strong>{params.equals}</strong></>;
    case "age-band": return <><strong>{params.min}</strong>–<strong>{params.max}</strong> years</>;
    case "married": return <>required</>;
    case "income-band": return params.max > 99999 ? <>any income</> : <>OMR <strong>{params.min}</strong>–<strong>{params.max}</strong></>;
    case "dti": return <>≤ <strong>{params.max}%</strong></>;
    case "existing-property":
    case "active-benefit": return <>{params.allowed ? "allowed" : "not allowed"}</>;
    case "spouse-support":
    case "employer-grant": return <>{params.allowed ? "allowed" : "blocked"}</>;
    case "documents": return <><strong>{(params.required || []).length}</strong> required</>;
    case "waiting-list": return <>{params.mustBeDue ? "turn must be due" : "any position"}</>;
    case "branch": return <>{params.condition}</>;
    default: return <>—</>;
  }
}

function RuleLibrary({ lib, onClose, addRule, rules }) {
  const [search, setSearch] = React.useState("");
  const used = new Set(rules.map((r) => r.ruleId));
  const filtered = lib.filter((r) =>
    !search || r.name.toLowerCase().includes(search.toLowerCase()) || r.category.toLowerCase().includes(search.toLowerCase())
  );
  const byCat = filtered.reduce((acc, r) => {
    (acc[r.category] = acc[r.category] || []).push(r);
    return acc;
  }, {});
  return (
    <div className="rule-library">
      <div className="row" style={{justifyContent:"space-between", marginBottom:12}}>
        <div>
          <div className="label-eyebrow">Rule library</div>
          <div className="title" style={{fontSize:14}}>Add a rule</div>
        </div>
        <button className="btn ghost sm icon-only" onClick={onClose}><Icon name="x" size={14}/></button>
      </div>
      <div className="cmd-bar" style={{marginBottom:12, width: "100%"}}>
        <Icon name="search" size={13} style={{color:"var(--muted)"}}/>
        <input placeholder="Search rules…" value={search} onChange={(e) => setSearch(e.target.value)} autoFocus/>
      </div>
      {Object.entries(byCat).map(([cat, rs]) => (
        <div key={cat} className="lib-section">
          <div className="lib-cat" style={{color: window.laneTone(cat)}}>
            <span className="pipe-lane-dot" style={{background: window.laneTone(cat)}}/> {cat}
          </div>
          <div style={{display:"flex", flexDirection:"column", gap:6}}>
            {rs.map((r) => (
              <button key={r.id} className="lib-item" onClick={() => addRule(r.id)}>
                <div className="lib-icon" style={{background: window.laneTone(cat) + "22", color: window.laneTone(cat)}}>
                  <Icon name={r.icon} size={13}/>
                </div>
                <div style={{flex:1, textAlign:"left"}}>
                  <div className="text-13" style={{fontWeight:600}}>{r.name}</div>
                  <div className="tiny muted">{r.source}</div>
                </div>
                {used.has(r.id) && <span className="pill ghost tiny">In use</span>}
                <Icon name="plus" size={13} style={{color:"var(--muted)"}}/>
              </button>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function laneTone(cat) {
  switch (cat) {
    case "Identity": return "#1b4149";
    case "Affordability": return "#eaa07a";
    case "Housing History": return "#1c1b3b";
    case "Documents": return "#26262a";
    case "Eligibility Gate": return "#2a5e68";
    case "Logic": return "#6b6662";
    default: return "#98928b";
  }
}

window.StudioPipeline = StudioPipeline;
window.laneTone = laneTone;
