// =====================================================================
// 行当 Sunburst — Task 1: role-type classification
// Inner ring: 生 旦 净 丑 ; Outer ring: 老生/小生/...
// Selection brushes across to network + theme heatmap
// =====================================================================

function RoleSunburst({ plays, focusPlay, selectedRole, onSelectRole, hoverChar, characterIndex }) {
  const [wrap, size] = useSize();
  // collect chars matching filter
  const chars = useMemo(() => {
    const list = [];
    plays.forEach(p => {
      if (focusPlay && p.id !== focusPlay) return;
      p.characters.forEach(c => list.push({ ...c, playId: p.id, playTitle: p.title, genre: p.genre }));
    });
    return list;
  }, [plays, focusPlay]);

  // aggregate
  const tree = useMemo(() => {
    const t = {};
    chars.forEach(c => {
      if (!t[c.role]) t[c.role] = { total: 0, subs: {} };
      t[c.role].total++;
      if (!t[c.role].subs[c.sub]) t[c.role].subs[c.sub] = { total: 0, chars: [] };
      t[c.role].subs[c.sub].total++;
      t[c.role].subs[c.sub].chars.push(c);
    });
    return t;
  }, [chars]);

  const roleOrder = ["sheng","dan","jing","chou"];
  const totalChars = chars.length || 1;

  const W = size.w || 360;
  const H = size.h || 280;
  const cx = W / 2, cy = H / 2 + 4;
  const rInner = 28;
  const rMid = Math.min(W, H) * 0.30;
  const rOuter = Math.min(W, H) * 0.46;

  // build arcs
  let acc = 0;
  const innerArcs = [];
  const outerArcs = [];
  roleOrder.forEach(role => {
    if (!tree[role]) return;
    const span = tree[role].total / totalChars;
    const a0 = acc * Math.PI * 2 - Math.PI / 2;
    const a1 = (acc + span) * Math.PI * 2 - Math.PI / 2;
    innerArcs.push({ role, a0, a1, count: tree[role].total });

    let subAcc = acc;
    Object.entries(tree[role].subs).forEach(([sub, info]) => {
      const subSpan = info.total / totalChars;
      const sa0 = subAcc * Math.PI * 2 - Math.PI / 2;
      const sa1 = (subAcc + subSpan) * Math.PI * 2 - Math.PI / 2;
      outerArcs.push({ role, sub, a0: sa0, a1: sa1, count: info.total, chars: info.chars });
      subAcc += subSpan;
    });
    acc += span;
  });

  function arcPath(a0, a1, rIn, rOut) {
    const sx0 = cx + rOut * Math.cos(a0), sy0 = cy + rOut * Math.sin(a0);
    const sx1 = cx + rOut * Math.cos(a1), sy1 = cy + rOut * Math.sin(a1);
    const ex0 = cx + rIn  * Math.cos(a1), ey0 = cy + rIn  * Math.sin(a1);
    const ex1 = cx + rIn  * Math.cos(a0), ey1 = cy + rIn  * Math.sin(a0);
    const large = (a1 - a0) > Math.PI ? 1 : 0;
    return `M ${sx0} ${sy0} A ${rOut} ${rOut} 0 ${large} 1 ${sx1} ${sy1} L ${ex0} ${ey0} A ${rIn} ${rIn} 0 ${large} 0 ${ex1} ${ey1} Z`;
  }

  return (
    <div className="panel">
      <div className="panel-head">
        <div className="panel-title"><span className="num">02</span>行 当 分 类</div>
        <div className="panel-meta">SUNBURST · {chars.length} ROLES</div>
      </div>
      <div className="panel-body" ref={wrap} style={{ display:"flex", alignItems:"center", justifyContent:"center" }}>
        <svg width={W} height={H} className="no-select">
          {/* outer ring */}
          {outerArcs.map((a,i) => {
            const dim = selectedRole && selectedRole !== a.role && selectedRole !== a.role + ":" + a.sub;
            const active = selectedRole === a.role + ":" + a.sub;
            const hoverMatch = hoverChar && a.chars.some(c => c.id === hoverChar.id && c.playId === hoverChar.playId);
            return (
              <path key={i}
                d={arcPath(a.a0, a.a1, rMid + 4, rOuter)}
                fill={roleColor(a.role)}
                opacity={dim ? 0.22 : (active || hoverMatch ? 1 : 0.78)}
                stroke="var(--ink)" strokeWidth="0.5"
                style={{ cursor:"pointer", transition:"opacity 0.15s" }}
                onClick={() => onSelectRole(selectedRole === a.role + ":" + a.sub ? null : a.role + ":" + a.sub)}
              />
            );
          })}
          {/* inner ring */}
          {innerArcs.map((a,i) => {
            const dim = selectedRole && !(selectedRole === a.role || (selectedRole.startsWith(a.role + ":")));
            const active = selectedRole === a.role;
            return (
              <g key={i}>
                <path
                  d={arcPath(a.a0, a.a1, rInner, rMid)}
                  fill={roleColor(a.role)}
                  opacity={dim ? 0.18 : (active ? 1 : 0.95)}
                  stroke="var(--ink)" strokeWidth="0.5"
                  style={{ cursor:"pointer" }}
                  onClick={() => onSelectRole(selectedRole === a.role ? null : a.role)}
                />
                {/* big role char */}
                <text
                  x={cx + ((rInner + rMid)/2) * Math.cos((a.a0 + a.a1)/2)}
                  y={cy + ((rInner + rMid)/2) * Math.sin((a.a0 + a.a1)/2) + 7}
                  fontSize="20"
                  fontFamily="var(--f-display)"
                  textAnchor="middle"
                  fill={a.role === "jing" ? "var(--paper)" : "var(--ink)"}
                  style={{ pointerEvents:"none", letterSpacing:"0.05em" }}
                >{roleLabel(a.role)}</text>
              </g>
            );
          })}
          {/* outer labels */}
          {outerArcs.map((a,i) => {
            const mid = (a.a0 + a.a1)/2;
            const tr = rOuter + 11;
            const tx = cx + tr * Math.cos(mid);
            const ty = cy + tr * Math.sin(mid);
            const anchor = Math.cos(mid) > 0.15 ? "start" : Math.cos(mid) < -0.15 ? "end" : "middle";
            const dim = selectedRole && selectedRole !== a.role && selectedRole !== a.role + ":" + a.sub;
            return (
              <text key={i} x={tx} y={ty + 3} fontSize="10" textAnchor={anchor}
                    fill={dim ? "var(--paper-dim)" : "var(--paper)"}
                    fontFamily="var(--f-serif)"
                    style={{ letterSpacing:"0.05em" }}
              >{a.sub}<tspan className="mono label-dim" fontSize="8" dx="3">{a.count}</tspan></text>
            );
          })}
          {/* center hub */}
          <circle cx={cx} cy={cy} r={rInner-3} fill="var(--ink-2)" stroke="var(--gold-dim)" strokeDasharray="2 2" />
          <text x={cx} y={cy-2} fontSize="9" textAnchor="middle" className="mono label-dim" style={{ letterSpacing:"0.2em" }}>ROLES</text>
          <text x={cx} y={cy+12} fontSize="14" textAnchor="middle" fill="var(--gold)" fontFamily="var(--f-mono)" style={{ letterSpacing:"0.05em" }}>{chars.length}</text>
        </svg>
      </div>
    </div>
  );
}

window.RoleSunburst = RoleSunburst;
