/* global React, window */
const { useState: useStateTM, useMemo: useMemoTM } = React;
const { VERTICALS, CONF } = window;

// Squarified-ish treemap: split largest-first into alternating H/V.
function layout(items, x, y, w, h, horizontal = true) {
  if (items.length === 0) return [];
  if (items.length === 1) return [{ ...items[0], x, y, w, h }];
  const total = items.reduce((s, i) => s + i.tam, 0);
  const half = total / 2;
  let running = 0, splitIdx = 1;
  for (let i = 0; i < items.length; i++) {
    running += items[i].tam;
    if (running >= half) { splitIdx = i + 1; break; }
  }
  const first = items.slice(0, splitIdx);
  const second = items.slice(splitIdx);
  const firstTotal = first.reduce((s, i) => s + i.tam, 0);
  const ratio = firstTotal / total;

  if (horizontal) {
    const w1 = w * ratio;
    return [
      ...layout(first, x, y, w1, h, false),
      ...layout(second, x + w1, y, w - w1, h, false),
    ];
  } else {
    const h1 = h * ratio;
    return [
      ...layout(first, x, y, w, h1, true),
      ...layout(second, x, y + h1, w, h - h1, true),
    ];
  }
}

function TAMTreemap({ onOpen }) {
  // Normalize: two unit systems (bbl and tons). To make visual comparison fair
  // we scale to a common "economic footprint" — rough conversion. Simpler: show
  // each but weight bbl at 0.15 tons-equivalent for visual share.
  const normalized = useMemoTM(() =>
    VERTICALS.map(v => ({ ...v, tam: v.u.includes('bbl') ? v.tam * 0.15 : v.tam }))
      .sort((a, b) => b.tam - a.tam),
    []
  );

  const [hovered, setHovered] = useStateTM(null);
  const rects = useMemoTM(() => layout(normalized, 0, 0, 100, 100, true), [normalized]);

  const active = hovered != null ? VERTICALS[hovered] : null;

  return (
    <div>
      <div className="treemap-layout">
        <div>
          <div className="treemap" style={{ aspectRatio: '1.6 / 1' }}>
            {rects.map((r, i) => {
              const v = VERTICALS.find(x => x.k === r.k);
              const idx = VERTICALS.indexOf(v);
              const isActive = hovered === idx;
              const area = r.w * r.h;
              const tiny = r.w < 8 || r.h < 8 || area < 50;
              const small = area < 140 || r.w < 12 || r.h < 10;
              return (
                <div
                  key={r.k}
                  className="tm-cell"
                  onMouseEnter={() => setHovered(idx)}
                  onMouseLeave={() => setHovered(null)}
                  onClick={() => onOpen && onOpen(v)}
                  style={{
                    left: `${r.x}%`,
                    top: `${r.y}%`,
                    width: `${r.w}%`,
                    height: `${r.h}%`,
                    background: v.c,
                    opacity: hovered == null || isActive ? 1 : 0.55,
                    zIndex: isActive ? 3 : 1,
                  }}
                >
                  {tiny ? null : small ? (
                    <div>
                      <div className="tm-name" style={{ fontSize: 10, lineHeight: 1.1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{v.k}</div>
                    </div>
                  ) : (
                    <>
                      <div style={{ minWidth: 0 }}>
                        <div className="tm-name" style={{ fontSize: r.w > 30 ? 14 : 11, overflow: 'hidden', textOverflow: 'ellipsis', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical' }}>{v.n}</div>
                        {r.h > 14 && <div className="tm-val" style={{ fontSize: 9, marginTop: 3, textTransform: 'uppercase', letterSpacing: '0.06em' }}>{v.stage}</div>}
                      </div>
                      {r.h > 20 && <div className="tm-val">{v.tam >= 1000 ? (v.tam / 1000).toFixed(1) + 'B' : v.tam} {v.u.split('/')[0].replace('M ','')}</div>}
                    </>
                  )}
                </div>
              );
            })}
          </div>
          <div style={{ marginTop: 12, display: 'flex', justifyContent: 'space-between', fontSize: 10, color: 'var(--fg-3)', fontFamily: 'var(--mono)' }}>
            <span>Area ∝ estimated annual market volume. Bbl units visually normalized for mass-equivalent scale.</span>
            <span style={{ color: 'var(--accent)' }}>◉ Click any cell for full vertical dossier →</span>
          </div>
        </div>

        <div>
          <div className="card-label" style={{ marginBottom: 12 }}>Vertical Detail</div>
          <div style={{
            background: 'var(--bg-1)',
            border: '1px solid var(--line)',
            borderLeft: `3px solid ${active ? active.c : 'var(--line)'}`,
            borderRadius: 6,
            padding: 20,
            minHeight: 280,
          }}>
            {active ? (
              <>
                <div style={{ fontSize: 10, fontFamily: 'var(--mono)', color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>{active.k}</div>
                <div style={{ fontSize: 22, color: 'var(--fg-0)', fontFamily: 'var(--serif)', marginTop: 4, letterSpacing: '-0.015em' }}>{active.n}</div>
                <button className="btn primary" style={{ marginTop: 10, fontSize: 11 }} onClick={() => onOpen && onOpen(active)}>Open full dossier →</button>
                <div style={{ marginTop: 16, display: 'flex', gap: 16, paddingBottom: 16, borderBottom: '1px solid var(--line)' }}>
                  <div>
                    <div className="card-label">TAM</div>
                    <div className="num" style={{ fontSize: 20, color: 'var(--fg-0)', marginTop: 2 }}>{active.tam >= 1000 ? (active.tam / 1000).toFixed(1) + 'B' : active.tam}</div>
                    <div style={{ fontSize: 10, color: 'var(--fg-3)', fontFamily: 'var(--mono)' }}>{active.u}</div>
                  </div>
                  <div>
                    <div className="card-label">Stage</div>
                    <div className="chip" style={{ marginTop: 4, borderColor: active.c, color: active.c, background: `${active.c}14` }}>{active.stage}</div>
                  </div>
                </div>
                <div style={{ fontSize: 12, color: 'var(--fg-1)', marginTop: 14, lineHeight: 1.6 }}>
                  {detailFor(active.k)}
                </div>
              </>
            ) : (
              <div style={{ color: 'var(--fg-3)', fontSize: 13, fontStyle: 'italic' }}>
                Hover a vertical to explore. The six colored cells at stages Pilot/Bench/Lab represent the initial addressable markets; Proxy/Disclosed/Testing are adjacent verticals already demonstrated or in active evaluation.
              </div>
            )}
          </div>

          <div style={{ marginTop: 20 }}>
            <div className="card-label" style={{ marginBottom: 10 }}>Validation Stage Legend</div>
            <div className="treemap-legend">
              {Object.entries(CONF).map(([k, c]) => (
                <div key={k} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 11, color: 'var(--fg-2)' }}>
                  <div style={{ width: 10, height: 10, background: c.color, borderRadius: 2 }} />
                  <span>{c.label}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function detailFor(k) {
  const m = {
    HPU: "Mixed plastic waste that mechanical recycling and pyrolysis cannot handle: multi-layer films, contaminated packaging, agricultural films, textiles. EU PPWR mandates recycled content by 2030.",
    BIT: "Extra-heavy bitumen (API <15) from Alberta and Venezuela. Currently requires costly cokers with 20–25% char waste. HCT upgrades directly with 75%+ yield and ~$15–23/bbl uplift.",
    SOUR: "Heavy/sour crude (API 15–25, >1% sulfur). Saudi Arabia, Mexico, Iraq, Russia. HCT removes sulfur and breaks long chains simultaneously, delivering $6–11/bbl uplift.",
    HRU: "Renewable oils for SAF production: used cooking oil, animal fats, crude diesel oil. ReFuelEU mandates 6% SAF by 2030, 70% by 2050. Existing hydrotreating cannot meet demand.",
    PCO: "Waxy paraffinic crude that conventional pipelines struggle to transport. ~16–27M bbl/day globally. Aduro proved HCT works on this feedstock class in 2026.",
    TIRE: "~1B end-of-life tires annually. HCT recovers rubber as liquid hydrocarbons while separating carbon black and steel. Tipping fees add to royalty revenue.",
    TURF: "6,000–10,000 synthetic turf fields reach end-of-life each year, triggering a PFAS-driven disposal crisis. HCT is the only technology that processes the infill.",
    XLPE: "Crosslinked polymers (PEX plumbing, XLPE cable insulation) have zero existing recycling technology. HCT achieves 84% yield in bench tests.",
    REF: "Refinery bottom-of-barrel residue. ~50–60% of the world's 280 refineries lack cokers. HCT offers a licensable bolt-on unit.",
    TCD: "Bio-oils and crude diesel oil via a separately patented thermochemical route. ~50M tons/yr addressable.",
    PU: "Polyurethane from mattresses, automotive seating, building foam. ~26M tons/yr. Currently in active testing with TotalEnergies.",
    AGRI: "Agricultural plastic waste — films, mulches, twine. ~12M/yr production plus stockpile. Partnership with Cleanfarms (2,000+ Canadian sites) and ECOCE (Mexico).",
    MFG: "Manufacturer in-house waste streams — 8–10% of the 400M ton/yr plastic production. Small modular factory units deployed at point of manufacture.",
  };
  return m[k] || "";
}

window.TAMTreemap = TAMTreemap;
