// =====================================================================
// Theme panel — Task 3 + Task 5
// Top half: theme prevalence bars (clickable filter)
// Bottom half: 行当 × 主题 association heatmap (the cross-link, Task 5)
// =====================================================================

function ThemePanel({ plays, allPlays, allThemes, focusPlay, themeFilter, onSetThemeFilter, selectedRole, onSelectRole, roleThemeMatrix }) {
  const [wrap, size] = useSize();
  const W = size.w || 296, H = size.h || 320;

  // theme counts across visible plays
  const themeCounts = useMemo(() => {
    const c = {};
    allThemes.forEach(t => c[t.id] = 0);
    plays.forEach(p => {
      // weight each play's themes by character count too
      p.themes.forEach(tid => { c[tid] = (c[tid] || 0) + 1; });
      p.characters.forEach(ch => (ch.themes||[]).forEach(tid => { c[tid] = (c[tid]||0) + 0.4; }));
    });
    return c;
  }, [plays, allThemes]);

  // for focused play: theme composition (which themes + intensity)
  const focused = focusPlay ? plays.find(p => p.id === focusPlay) : null;

  // compute filtered role × theme matrix from visible plays
  const matrix = useMemo(() => {
    const m = {};
    ["sheng","dan","jing","chou"].forEach(r => {
      m[r] = {};
      allThemes.forEach(t => m[r][t.id] = 0);
    });
    plays.forEach(p => p.characters.forEach(c => {
      (c.themes||[]).forEach(tid => { if (m[c.role]) m[c.role][tid] = (m[c.role][tid]||0) + 1; });
    }));
    return m;
  }, [plays, allThemes]);

  const sortedThemes = [...allThemes].sort((a,b) => (themeCounts[b.id]||0) - (themeCounts[a.id]||0));
  const maxCount = Math.max(...Object.values(themeCounts), 1);
  const maxCell = Math.max(1, ...["sheng","dan","jing","chou"].flatMap(r => allThemes.map(t => matrix[r][t.id])));

  // layout
  const barH = 14;
  const barGap = 2;
  const barLabelW = 38;
  const barAreaH = sortedThemes.length * (barH + barGap);
  // heatmap geometry
  const cellW = (W - 14 - 26) / allThemes.length;
  const cellH = 14;
  const heatY = 32 + barAreaH + 28;

  return (
    <div className="panel">
      <div className="panel-head">
        <div className="panel-title"><span className="num">05</span>主 题 构 成</div>
        <div className="panel-meta">{plays.length} PLAYS · {allThemes.length} TOPICS</div>
      </div>
      <div className="panel-body" ref={wrap} style={{ overflowY:"auto" }}>
        <div style={{ padding:"10px 14px 4px" }}>
          <div style={{ fontFamily:"var(--f-mono)", fontSize:9, letterSpacing:"0.22em", color:"var(--paper-dim)", textTransform:"uppercase", marginBottom:6 }}>
            {focused ? `《${focused.title}》主题强度` : "主题热度 · 跨剧目"}
          </div>
          {/* theme bars */}
          <div>
            {sortedThemes.map(t => {
              const v = focused
                ? (focused.themes.includes(t.id) ? 1 : 0) + focused.characters.filter(c => (c.themes||[]).includes(t.id)).length * 0.18
                : themeCounts[t.id] || 0;
              const max = focused ? 3 : maxCount;
              const pct = Math.max(0, Math.min(1, v / max));
              const sel = themeFilter === t.id;
              const dim = themeFilter && !sel;
              return (
                <div key={t.id}
                  onClick={() => onSetThemeFilter(sel ? null : t.id)}
                  style={{
                    display:"grid",
                    gridTemplateColumns:`${barLabelW}px 1fr 22px`,
                    alignItems:"center",
                    gap:6,
                    padding:"2px 0",
                    cursor:"pointer",
                    opacity: dim ? 0.32 : 1,
                  }}
                >
                  <div style={{
                    fontFamily:"var(--f-display)",
                    fontSize:13,
                    color: sel ? t.color : "var(--paper)",
                    letterSpacing:"0.1em",
                    textAlign:"right",
                  }}>{t.name}</div>
                  <div style={{ height: 10, background: "var(--ink-2)", position:"relative" }}>
                    <div style={{
                      position:"absolute", left:0, top:0, bottom:0,
                      width:`${pct*100}%`,
                      background: t.color,
                      opacity: sel ? 1 : 0.85,
                      boxShadow: sel ? `0 0 8px ${t.color}` : "none",
                    }}/>
                    {sel && <div style={{ position:"absolute", right:-3, top:-2, bottom:-2, width:2, background:"var(--gold)" }}/>}
                  </div>
                  <div style={{ fontFamily:"var(--f-mono)", fontSize:9, color:"var(--paper-dim)", textAlign:"right", letterSpacing:"0.05em" }}>
                    {v < 1 ? v.toFixed(1) : Math.round(v)}
                  </div>
                </div>
              );
            })}
          </div>

          {/* Task 5: role × theme cross-link heatmap */}
          <div style={{ marginTop: 16, paddingTop: 12, borderTop:"1px dashed var(--ink-4)" }}>
            <div style={{ fontFamily:"var(--f-mono)", fontSize:9, letterSpacing:"0.22em", color:"var(--paper-dim)", textTransform:"uppercase", marginBottom:6 }}>
              行 当 × 主 题 · 关联强度
            </div>
            <svg width="100%" height={cellH * 4 + 32}>
              {/* column labels — short 名 */}
              {allThemes.map((t, i) => (
                <text key={t.id} x={36 + i * cellW + cellW/2} y="12"
                      fontSize="10" textAnchor="middle" fill="var(--paper)" fontFamily="var(--f-display)"
                      style={{ letterSpacing:"0.05em", cursor:"pointer", opacity: themeFilter && themeFilter !== t.id ? 0.4 : 1 }}
                      onClick={() => onSetThemeFilter(themeFilter === t.id ? null : t.id)}>
                  {t.name[0]}
                </text>
              ))}
              {["sheng","dan","jing","chou"].map((r, ri) => (
                <g key={r}>
                  <text x="32" y={20 + ri * cellH + cellH * 0.7}
                        fontSize="11" textAnchor="end" fontFamily="var(--f-display)"
                        fill={selectedRole === r ? "var(--gold)" : "var(--paper)"}
                        style={{ letterSpacing:"0.05em", cursor:"pointer" }}
                        onClick={() => onSelectRole(selectedRole === r ? null : r)}>
                    {roleLabel(r)}
                  </text>
                  {allThemes.map((t, ci) => {
                    const v = matrix[r][t.id] || 0;
                    const op = v === 0 ? 0.06 : 0.15 + 0.85 * (v / maxCell);
                    const sel = (selectedRole === r) || (themeFilter === t.id);
                    return (
                      <rect key={t.id}
                            x={36 + ci * cellW} y={20 + ri * cellH}
                            width={cellW - 1} height={cellH - 1}
                            fill={roleColor(r)} opacity={op}
                            stroke={sel ? "var(--gold)" : "transparent"} strokeWidth="0.5"
                            style={{ cursor:"pointer" }}
                            onClick={() => { onSetThemeFilter(themeFilter === t.id ? null : t.id); }}>
                        <title>{`${roleLabel(r)} × ${t.name}: ${v}`}</title>
                      </rect>
                    );
                  })}
                </g>
              ))}
            </svg>
            <div style={{ marginTop:4, fontFamily:"var(--f-mono)", fontSize:9, letterSpacing:"0.18em", color:"var(--gold-dim)" }}>
              ※ 见旦角主载 爱情·亲情; 净 主载 权谋·清正; 生 跨忠义·智谋
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

window.ThemePanel = ThemePanel;
