const {
  useState,
  useEffect,
  useMemo,
  useRef
} = React;
function WinGauge({
  p
}) {
  if (p == null) {
    return <div className="gauge idle">
        <div className="seg-blue" style={{
        width: "50%"
      }}>Blue —</div>
        <div className="seg-red">— Red</div>
      </div>;
  }
  const b = Math.round(p * 1000) / 10,
    r = Math.round((1 - p) * 1000) / 10;
  return <div className="gauge">
      <div className="seg-blue" style={{
      width: `${p * 100}%`
    }}>Blue {b}%</div>
      <div className="seg-red" style={{
      width: `${(1 - p) * 100}%`
    }}>{r}% Red</div>
    </div>;
}
function CompBar({
  comp,
  feat
}) {
  const tot = feat.reduce((a, k) => a + Math.abs(comp[k] || 0), 0) || 1;
  const title = feat.map(k => `${FEAT_KR[k]}: ${comp[k] >= 0 ? "+" : ""}${(comp[k] || 0).toFixed(3)}`).join("\n");
  return <div className="compbar" title={title}>
      {feat.map(k => <div key={k} className="seg" style={{
      width: `${Math.abs(comp[k] || 0) / tot * 100}%`,
      background: FEAT_COLORS[k],
      opacity: (comp[k] || 0) >= 0 ? 0.95 : 0.35
    }} />)}
    </div>;
}
function WinExplain({
  eng,
  blue,
  red,
  p,
  assigned
}) {
  const fB = eng.teamScalar(blue),
    fR = eng.teamScalar(red);
  const f = eng.feats(blue, red);
  const contrib = {};
  eng.FEAT.forEach(k => contrib[k] = eng.COEF[k] * f[k]);
  const penOf = picks => POSITIONS.reduce((n, pos) => {
    const k = picks[pos];
    return n + (k && !eng.eligiblePositions(k).includes(pos) ? 1 : 0);
  }, 0);
  const offroleZ = assigned ? OFFROLE_PENALTY * (penOf(red.picks) - penOf(blue.picks)) : 0;
  const insights = [];
  for (const side of ["blue", "red"]) {
    const t = side === "blue" ? blue : red;
    const picks = POSITIONS.filter(pp => t.picks[pp]).map(pp => t.picks[pp]);
    for (let i = 0; i < picks.length; i++) for (let j = i + 1; j < picks.length; j++) {
      const wr = eng.synergyWR(picks[i], picks[j]);
      if (Math.abs(wr - 0.5) >= 0.03) insights.push({
        type: "시너지",
        side,
        a: eng.CH[picks[i]].name,
        b: eng.CH[picks[j]].name,
        wr
      });
    }
  }
  for (const pos of POSITIONS) {
    const b = blue.picks[pos],
      r = red.picks[pos];
    if (b && r) {
      const wr = eng.counterWR(pos, b, r);
      if (Math.abs(wr - 0.5) >= 0.03) insights.push({
        type: "카운터",
        side: "blue",
        a: eng.CH[b].name,
        b: eng.CH[r].name,
        wr,
        pos
      });
    }
  }
  insights.sort((x, y) => Math.abs(y.wr - 0.5) - Math.abs(x.wr - 0.5));
  const top = insights.slice(0, 8);
  const filled = POSITIONS.filter(pp => blue.picks[pp]).length + POSITIONS.filter(pp => red.picks[pp]).length;
  const EPS = 0.02;
  const maxAbs = eng.FEAT.reduce((m, k) => Math.max(m, Math.abs(contrib[k])), 0) || 1;
  const winnerBlue = p >= 0.5;
  const penBlue = penOf(blue.picks),
    penRed = penOf(red.picks);
  return <React.Fragment>
      <div className="panel">
        <div className="panel-title">
          <h3>무엇이 승률을 갈랐나</h3>
          <span className={"why-result " + (winnerBlue ? "fav-blue" : "fav-red")}>
            {winnerBlue ? "Blue" : "Red"} {((winnerBlue ? p : 1 - p) * 100).toFixed(1)}%
          </span>
        </div>
        <div className="small why-intro">막대가 길수록 이번 판에서 크게 작용한 요소예요. 색이 어느 팀 쪽으로 차는지가 그 요소로 유리해진 팀입니다.</div>

        <div className="factor-list">
          {eng.FEAT.map(k => {
          const c = contrib[k];
          const favBlue = c > EPS,
            favRed = c < -EPS;
          const pct = Math.min(100, Math.abs(c) / maxAbs * 100);
          const tag = favBlue ? "Blue 유리" : favRed ? "Red 유리" : "영향 거의 없음";
          const tagCls = favBlue ? "fav-blue" : favRed ? "fav-red" : "fav-zero";
          return <div className="factor" key={k} title={`기여 ${c >= 0 ? "+" : ""}${c.toFixed(3)} (logit)`}>
                <div className="factor-row">
                  <span className="dot" style={{
                background: FEAT_COLORS[k]
              }}></span>
                  <span className="factor-name">{FEAT_KR[k]}</span>
                  <span className={"factor-tag " + tagCls}>{tag}</span>
                </div>
                <div className="small factor-desc">{FEAT_DESC[k]}</div>
                <div className="tug">
                  <span className="tug-end red">Red</span>
                  <span className="tug-half left"><span className="tug-fill red" style={{
                  width: `${favRed ? pct : 0}%`
                }}></span></span>
                  <span className="tug-mid"></span>
                  <span className="tug-half right"><span className="tug-fill blue" style={{
                  width: `${favBlue ? pct : 0}%`
                }}></span></span>
                  <span className="tug-end blue">Blue</span>
                </div>
              </div>;
        })}
        </div>

        <div className="why-sum">
          종합하면 <strong className={winnerBlue ? "fav-blue" : "fav-red"}>{winnerBlue ? "Blue" : "Red"}</strong> 승리 확률 <strong>{((winnerBlue ? p : 1 - p) * 100).toFixed(1)}%</strong>로 예측돼요.
        </div>
        {assigned && penBlue + penRed > 0 && <div className="small why-offrole">※ {penBlue && penRed ? "양 팀 모두 일부" : penBlue ? "Blue의 일부" : "Red의 일부"} 챔피언이 주 포지션이 아닌 자리에 배치돼, 그만큼 승률이 조금 낮게 반영됐어요.</div>}

        <details className="expert">
          <summary>정확한 계산식 보기 (전문가용)</summary>
          <table>
            <thead><tr><th>요소</th><th>Blue</th><th>Red</th><th>가중치</th><th>기여</th></tr></thead>
            <tbody>
              {eng.FEAT.map(k => {
              const bv = k === "counter" ? eng.counterBlue(blue, red) : fB[k];
              const rv = k === "counter" ? null : fR[k];
              return <tr key={k}>
                    <td><span className="dot" style={{
                    background: FEAT_COLORS[k]
                  }}></span>{FEAT_KR[k]}</td>
                    <td>{typeof bv === "number" ? bv.toFixed(3) : "—"}</td>
                    <td>{typeof rv === "number" ? rv.toFixed(3) : "—"}</td>
                    <td>{eng.COEF[k].toFixed(3)}</td>
                    <td className={contrib[k] >= 0 ? "pos" : "neg"}>{contrib[k] >= 0 ? "+" : ""}{contrib[k].toFixed(3)}</td>
                  </tr>;
            })}
            </tbody>
          </table>
          <div className="small gauge-note">
            최종 P(blue) = sigmoid(절편 {eng.INTERCEPT.toFixed(3)} + Σ 기여{offroleZ !== 0 ? ` ${offroleZ >= 0 ? "+" : "−"} 오프롤 ${Math.abs(offroleZ).toFixed(3)}` : ""}) = {(p * 100).toFixed(1)}%
          </div>
        </details>
      </div>

      <div className="panel">
        <div className="panel-title"><h3>감지된 강한 조합 / 상성</h3></div>
        {top.length === 0 ? <div className="small">{filled < 10 ? "챔피언을 더 채우면 표시됩니다." : "강한 시너지·상성이 감지되지 않았습니다 (모두 중립 ±3%p 이내)."}</div> : <table>
              <thead><tr><th>유형</th><th>대상</th><th>승률</th></tr></thead>
              <tbody>{top.map((it, i) => <tr key={i}>
                  <td>{it.type}{it.pos ? ` (${ROLE_KR[it.pos]})` : ` (${it.side === "blue" ? "Blue" : "Red"})`}</td>
                  <td>{it.a} {it.type === "카운터" ? "vs" : "+"} {it.b}</td>
                  <td className={it.wr >= 0.5 ? "pos" : "neg"}>{(it.wr * 100).toFixed(1)}%</td>
                </tr>)}</tbody>
            </table>}
      </div>
    </React.Fragment>;
}
function ChampPortrait({
  champKey,
  name,
  size,
  variant,
  fill
}) {
  const [failed, setFailed] = useState(false);
  const src = champKey ? champImg(champKey) : null;
  const cls = "portrait" + (fill ? " fill" : "") + (variant ? " " + variant : "") + (champKey ? "" : " is-empty");
  const style = fill ? undefined : {
    width: size || 44,
    height: size || 44
  };
  if (src && !failed) {
    return <span className={cls} style={style}>
        <img src={src} alt={name || champKey} onError={() => setFailed(true)} draggable="false" />
      </span>;
  }
  const ini = champKey ? (name || champKey).slice(0, 2) : "";
  return <span className={cls} style={style} title={name || undefined}>
      <span className="portrait-ini">{ini}</span>
    </span>;
}
function ChampPicker({
  kind,
  cat,
  setCat,
  query,
  setQuery,
  rows,
  onPick,
  note,
  pending,
  setPending
}) {
  const pendingRow = pending ? rows.find(r => r.k === pending) : null;
  const verb = kind === "ban" ? "밴 확정" : "선택 완료";
  function pick(r) {
    if (r.banned || r.picked) return;
    setPending(pending === r.k ? null : r.k);
  }
  function confirm() {
    if (!pending) return;
    onPick(pending);
  }
  return <div className="picker-inline">
      {note && <div className={"modal-phase " + kind}>{note}</div>}
      <div className="cat-tabs">
        {CATEGORIES.map(([key, label]) => <button key={key} className={"cat-tab" + (cat === key ? " active" : "")} onClick={() => setCat(key)}>{label}</button>)}
      </div>
      <input className="search picker-search" placeholder="챔피언 검색…" value={query} onChange={e => setQuery(e.target.value)} />
      <div className="picker-scroll">
        <div className={"candgrid " + kind}>
          {rows.length === 0 && <div className="small picker-empty">해당 조건의 후보가 없습니다.</div>}
          {rows.map(r => {
          const disabled = !!(r.banned || r.picked);
          const sel = pending === r.k;
          return <div key={r.k} className={"cand-tile" + (r.banned ? " banned" : r.picked ? " picked" : "") + (sel ? " selected" : "")} onClick={disabled ? undefined : () => pick(r)} title={r.banned ? "이미 밴된 챔피언 — 선택할 수 없습니다" : r.picked ? "이미 선택된 챔피언 — 선택할 수 없습니다" : r.name}>
                <ChampPortrait champKey={r.k} name={r.name} fill variant="cand-portrait" />
                <div className="nm">{r.name}</div>
              </div>;
        })}
        </div>
      </div>
      <div className="picker-confirm">
        <button className={"btn btn-lg " + (kind === "ban" ? "btn-ban" : "btn-primary")} disabled={!pending} onClick={confirm}>
          {pendingRow ? `${pendingRow.name} ${verb} ▶` : `${verb} ▶`}
        </button>
      </div>
    </div>;
}
function EmptyState({
  title,
  children
}) {
  return <div className="empty">
      <h3>{title}</h3>
      <div className="small">{children}</div>
    </div>;
}
function Modal({
  open,
  onClose,
  title,
  children
}) {
  if (!open) return null;
  return <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{title}</h3>
          <button className="modal-close" onClick={onClose} aria-label="닫기">✕</button>
        </div>
        <div className="modal-body">{children}</div>
      </div>
    </div>;
}
