// Alternate atlas views — Bar chart (descending) + Treemap (population-weighted).
// Each component receives the same props as the choropleth so the control bar
// can swap them without dragging different prop shapes.
{
const { LENSES, STATES, STATE_POPULATION, scoreFor, lensMetaFor } = window.PL_DATA;

const NAME_FOR = Object.fromEntries(STATES.map(s => [s[0], s[1]]));

// ============================================================================
// BAR CHART VIEW — sorted descending, all scored states
// ============================================================================

function BarChartView({ lensId, mode = "passed", onSelect, activeState }) {
  // Only states with actual data for this lens
  const rows = STATES
    .map(s => s[0])
    .filter(code => {
      const meta = lensMetaFor && lensMetaFor(code, lensId);
      return meta && meta.bill_count > 0;
    })
    .map(code => {
      const meta = lensMetaFor(code, lensId);
      return {
        code,
        name: NAME_FOR[code] || code,
        score: scoreFor(code, lensId, mode),
        bills: meta?.bill_count || 0,
        passed: meta?.n_passed || 0,
      };
    })
    .sort((a, b) => b.score - a.score);

  if (rows.length === 0) {
    return <NoDataView text={`No states have scored bills for this lens yet.`} />;
  }

  return (
    <div style={{
      width: "100%", height: "100%",
      padding: "32px clamp(24px, 4vw, 64px)",
      overflowY: "auto",
      background: "var(--bg-2)",
    }}>
      <div className="eyebrow" style={{ marginBottom: 16 }}>
        Sorted descending — {rows.length} states with data
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 4, maxWidth: 980 }}>
        {rows.map((r, i) => {
          const color = window.PL_COLOR(r.score).color;
          const isActive = activeState === r.code;
          return (
            <button key={r.code}
              onClick={() => onSelect && onSelect(r.code)}
              style={{
                display: "grid",
                gridTemplateColumns: "32px 64px minmax(140px, 1.4fr) minmax(0, 4fr) 60px",
                gap: 14, alignItems: "center",
                padding: "8px 10px",
                background: isActive ? "var(--bg-3)" : "transparent",
                border: "1px solid transparent",
                borderColor: isActive ? "var(--ink)" : "transparent",
                cursor: "pointer",
                textAlign: "left", color: "inherit", fontFamily: "inherit",
                width: "100%",
              }}>
              <span className="mono tnum" style={{ color: "var(--ink-3)", fontSize: 11 }}>
                {String(i + 1).padStart(2, "0")}
              </span>
              <span className="mono" style={{ fontWeight: 600, fontSize: 13 }}>{r.code}</span>
              <span style={{ fontSize: 14, fontFamily: "var(--display)", fontWeight: 500,
                whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                {r.name}
              </span>
              <div style={{ height: 18, background: "var(--bg-3)", position: "relative" }}>
                <div style={{
                  position: "absolute", left: 0, top: 0, bottom: 0,
                  width: `${r.score}%`, background: color,
                  transition: "width 220ms ease",
                }}></div>
              </div>
              <span className="mono tnum" style={{ fontSize: 14, fontWeight: 600, textAlign: "right",
                color }}>
                {r.score.toFixed(0)}
              </span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ============================================================================
// TREEMAP VIEW — population-weighted (large states get larger areas)
// ============================================================================

function TreemapView({ lensId, mode = "passed", onSelect, activeState }) {
  const wrapRef = React.useRef(null);
  const [size, setSize] = React.useState({ w: 1000, h: 600 });

  React.useLayoutEffect(() => {
    if (!wrapRef.current) return;
    const update = () => {
      const r = wrapRef.current.getBoundingClientRect();
      setSize({ w: Math.max(400, r.width), h: Math.max(360, r.height) });
    };
    update();
    const ro = new ResizeObserver(update);
    ro.observe(wrapRef.current);
    return () => ro.disconnect();
  }, []);

  // Build treemap leaves — every scored state, area = population, color = score
  const leaves = STATES
    .map(s => s[0])
    .filter(code => STATE_POPULATION[code])
    .filter(code => {
      const meta = lensMetaFor && lensMetaFor(code, lensId);
      return meta && meta.bill_count > 0;
    })
    .map(code => ({
      code,
      name: NAME_FOR[code] || code,
      pop: STATE_POPULATION[code],
      score: scoreFor(code, lensId, mode),
      bills: lensMetaFor(code, lensId)?.bill_count || 0,
    }));

  if (leaves.length === 0) {
    return <NoDataView text="No states have scored bills for this lens yet." />;
  }

  // d3.treemap layout
  const root = window.d3.hierarchy({ children: leaves }).sum(d => d.pop);
  const treemap = window.d3.treemap()
    .size([size.w, size.h])
    .paddingInner(2)
    .round(true);
  treemap(root);

  return (
    <div ref={wrapRef} style={{
      width: "100%", height: "100%",
      padding: 16,
      background: "var(--bg-2)",
      position: "relative",
    }}>
      <div className="eyebrow" style={{
        position: "absolute", top: 24, left: 24, zIndex: 2,
        background: "var(--bg)", padding: "5px 10px", border: "1px solid var(--rule)",
      }}>
        Sized by population · {leaves.length} states
      </div>
      <svg width={size.w} height={size.h} style={{ display: "block" }}>
        {root.leaves().map(node => {
          const w = node.x1 - node.x0;
          const h = node.y1 - node.y0;
          const showLabel = w > 60 && h > 36;
          const color = window.PL_COLOR(node.data.score).color;
          const isActive = activeState === node.data.code;
          return (
            <g key={node.data.code}
              transform={`translate(${node.x0}, ${node.y0})`}
              style={{ cursor: "pointer" }}
              onClick={() => onSelect && onSelect(node.data.code)}>
              <rect width={w} height={h} fill={color}
                stroke={isActive ? "var(--ink)" : "rgba(0,0,0,0.15)"}
                strokeWidth={isActive ? 2.5 : 1} />
              {showLabel && (
                <>
                  <text x={10} y={20}
                    style={{ fontFamily: "var(--display)", fontWeight: 600, fontSize: Math.min(20, w/6),
                      fill: "#fff", letterSpacing: "-0.01em" }}>
                    {node.data.code}
                  </text>
                  <text x={10} y={36}
                    style={{ fontFamily: "var(--mono)", fontSize: 11, fill: "rgba(255,255,255,0.85)",
                      letterSpacing: "0.04em" }}>
                    {node.data.score.toFixed(0)} · {node.data.pop.toFixed(1)}M
                  </text>
                </>
              )}
              <title>{node.data.name} · score {node.data.score.toFixed(1)} · pop {node.data.pop}M · {node.data.bills} bills</title>
            </g>
          );
        })}
      </svg>
    </div>
  );
}

// ============================================================================
// Shared "no data" view
// ============================================================================

function NoDataView({ text }) {
  return (
    <div style={{
      width: "100%", height: "100%",
      display: "flex", alignItems: "center", justifyContent: "center",
      background: "var(--bg-2)",
      fontFamily: "var(--mono)", fontSize: 12, letterSpacing: "0.06em",
      color: "var(--ink-3)", textTransform: "uppercase",
    }}>
      {text}
    </div>
  );
}

window.PL_BarChartView = BarChartView;
window.PL_TreemapView = TreemapView;
}
