/* Seed profitability calculator — v2 elevated layout.
   Same data model as before; only the visual layer changes. */

const { useState: useStateSd, useMemo: useMemoSd, useEffect: useEffectSd } = React;

// ─── Hardcoded seed catalogues ───────────────────────────────────────────
const SEEDS_GOLD = [
  { name: 'Azalea',                   costSilver: 1.5,  climate: 'Temperate', growHr: 0.333, yield: 3,   harvest: 'Azalea',             labor: 1 },
  { name: 'Potato Eyes',              costSilver: 1.5,  climate: 'Any',       growHr: 0.167, yield: 3,   harvest: 'Potato',             labor: 1 },
  { name: 'Cucumber',                 costSilver: 1.5,  climate: 'Any',       growHr: 0.167, yield: 3,   harvest: 'Cucumber',           labor: 1 },
  { name: 'Barley',                   costSilver: 1.5,  climate: 'Temperate', growHr: 0.5,   yield: 3,   harvest: 'Barley',             labor: 1 },
  { name: 'Carrot',                   costSilver: 1.5,  climate: 'Temperate', growHr: 0.5,   yield: 3,   harvest: 'Carrot',             labor: 1 },
  { name: 'Onion',                    costSilver: 1.5,  climate: 'Temperate', growHr: 0.5,   yield: 3,   harvest: 'Onion',              labor: 1 },
  { name: 'Clover',                   costSilver: 1.5,  climate: 'Any',       growHr: 1,     yield: 3,   harvest: 'Clover',             labor: 1 },
  { name: 'Iris',                     costSilver: 1.5,  climate: 'Temperate', growHr: 1,     yield: 3,   harvest: 'Iris',               labor: 1 },
  { name: 'Narcissus',                costSilver: 1.5,  climate: 'Temperate', growHr: 1,     yield: 3,   harvest: 'Narcissus',          labor: 1 },
  { name: 'Rose',                     costSilver: 1.5,  climate: 'Temperate', growHr: 1,     yield: 3,   harvest: 'Rose',               labor: 1 },
  { name: 'Lavender',                 costSilver: 1.5,  climate: 'Temperate', growHr: 1,     yield: 3,   harvest: 'Lavender',           labor: 1 },
  { name: 'Garlic',                   costSilver: 1.5,  climate: 'Temperate', growHr: 1,     yield: 3,   harvest: 'Garlic',             labor: 2 },
  { name: 'Tomato',                   costSilver: 1.5,  climate: 'Temperate', growHr: 1,     yield: 3,   harvest: 'Tomato',             labor: 2 },
  { name: 'Corn',                     costSilver: 1.5,  climate: 'Temperate', growHr: 2,     yield: 3,   harvest: 'Corn',               labor: 1 },
  { name: 'Millet',                   costSilver: 1.5,  climate: 'Temperate', growHr: 2,     yield: 3,   harvest: 'Millet',             labor: 1 },
  { name: 'Rice',                     costSilver: 1.5,  climate: 'Temperate', growHr: 2,     yield: 3,   harvest: 'Rice',               labor: 1 },
  { name: 'Cotton',                   costSilver: 1.5,  climate: 'Tropical',  growHr: 2,     yield: 8.5, harvest: 'Cotton',             labor: 2 },
  { name: 'Mushroom Spore',           costSilver: 1.5,  climate: 'Any',       growHr: 2,     yield: 3,   harvest: 'Mushroom',           labor: 1 },
  { name: 'Thistle',                  costSilver: 1.5,  climate: 'Temperate', growHr: 4,     yield: 3,   harvest: 'Thistle',            labor: 1 },
  { name: 'Red Coral Polyp',          costSilver: 7,    climate: null,        growHr: 8,     yield: 3.5, harvest: 'Red Coral',          labor: 2 },
  { name: 'Green Coral Polyp',        costSilver: 7,    climate: null,        growHr: 8,     yield: 3.5, harvest: 'Green Coral',        labor: 2 },
  { name: 'Orange Plate Coral Polyp', costSilver: 11,   climate: null,        growHr: 10,    yield: 3,   harvest: 'Orange Plate Coral', labor: 3 },
  { name: 'Yellow Plate Coral Polyp', costSilver: 11,   climate: null,        growHr: 10,    yield: 3,   harvest: 'Yellow Plate Coral', labor: 3 },
];

const SEEDS_VOC = [
  { name: 'Lily',               costVoc: 45,  climate: 'Temperate', growHr: 2,    yield: 3,   harvest: 'Lily',                    labor: 2 },
  { name: 'Oat',                costVoc: 45,  climate: 'Temperate', growHr: 3,    yield: 3,   harvest: 'Oats',                    labor: 2 },
  { name: 'Pumpkin',            costVoc: 45,  climate: 'Temperate', growHr: 3,    yield: 3,   harvest: 'Pumpkin',                 labor: 2 },
  { name: 'Strawberry',         costVoc: 45,  climate: 'Temperate', growHr: 3,    yield: 3,   harvest: 'Strawberry',              labor: 2 },
  { name: 'Wheat',              costVoc: 45,  climate: 'Temperate', growHr: 3,    yield: 3,   harvest: 'Wheat',                   labor: 2 },
  { name: 'Yam',                costVoc: 45,  climate: 'Temperate', growHr: 3,    yield: 3,   harvest: 'Yam',                     labor: 2 },
  { name: 'Mint',               costVoc: 45,  climate: 'Arid',      growHr: 3,    yield: 3,   harvest: 'Mint',                    labor: 2 },
  { name: 'Rosemary',           costVoc: 45,  climate: 'Any',       growHr: 3,    yield: 3,   harvest: 'Rosemary',                labor: 2 },
  { name: 'Cornflower',         costVoc: 45,  climate: 'Temperate', growHr: 4,    yield: 3,   harvest: 'Cornflower',              labor: 2 },
  { name: 'Lotus',              costVoc: 45,  climate: 'Any',       growHr: 4,    yield: 3,   harvest: 'Lotus',                   labor: 2 },
  { name: 'Sunflower',          costVoc: 45,  climate: 'Any',       growHr: 4,    yield: 3,   harvest: 'Sunflower',               labor: 3 },
  { name: 'Peanut',             costVoc: 45,  climate: 'Tropical',  growHr: 8,    yield: 3,   harvest: 'Peanut',                  labor: 2 },
  { name: 'Rye',                costVoc: 45,  climate: 'Temperate', growHr: 8,    yield: 3,   harvest: 'Rye',                     labor: 2 },
  { name: 'Aloe',               costVoc: 45,  climate: 'Arid',      growHr: 10,   yield: 3.5, harvest: 'Aloe',                    labor: 2 },
  { name: 'White Coral Polyp',  costVoc: 45,  climate: null,        growHr: 18,   yield: 3.5, harvest: 'White Coral',             labor: 4 },
  { name: 'Pearl Oyster',       costVoc: 45,  climate: null,        growHr: 24,   yield: 2,   harvest: 'Pearl',                   labor: 5 },
  { name: 'Blue Coral Polyp',   costVoc: 45,  climate: null,        growHr: 24,   yield: 3.5, harvest: 'Blue Coral',              labor: 5 },
  { name: 'Antler Coral Polyp', costVoc: 45,  climate: null,        growHr: 26,   yield: 3.5, harvest: 'Antler Coral',            labor: 4 },
  { name: 'Cactus',             costVoc: 90,  climate: 'Arid',      growHr: 4,    yield: 3,   harvest: 'Cactus',                  labor: 2 },
  { name: 'Turmeric',           costVoc: 90,  climate: 'Arid',      growHr: 4,    yield: 3,   harvest: 'Turmeric',                labor: 3 },
  { name: 'Chili Pepper',       costVoc: 90,  climate: 'Arid',      growHr: 10,   yield: 3,   harvest: 'Chili Pepper',            labor: 3 },
  { name: 'Bean',               costVoc: 90,  climate: 'Temperate', growHr: 18,   yield: 3.5, harvest: 'Bean',                    labor: 3 },
  { name: 'Quinoa',             costVoc: 90,  climate: 'Temperate', growHr: 18,   yield: 3.5, harvest: 'Quinoa',                  labor: 3 },
  { name: 'Cultivated Ginseng', costVoc: 90,  climate: 'Temperate', growHr: 24,   yield: 3,   harvest: 'Cultivated Ginseng Root', labor: 3 },
  { name: 'Poppy',              costVoc: 90,  climate: 'Temperate', growHr: 24,   yield: 3,   harvest: 'Poppy',                   labor: 5 },
  { name: 'Saffron',             costVoc: 90,  climate: 'Arid',      growHr: 24,   yield: 3.5, harvest: 'Saffron',                 labor: 5 },
  { name: 'Blueberry',          costVoc: 180, climate: 'Temperate', growHr: 4.9,  yield: 2,   harvest: 'Blueberry',               labor: 5 },
  { name: 'Vanilla',            costVoc: 180, climate: 'Tropical',  growHr: 14.3, yield: 3,   harvest: 'Vanilla Bean',            labor: 5 },
  { name: 'Black Pepper',       costVoc: 180, climate: 'Tropical',  growHr: 14.3, yield: 3,   harvest: 'Black Pepper',            labor: 5 },
];

// ─── localStorage keys ───────────────────────────────────────────────────
const SEED_PLANTED_KEY   = 'craft.seedsPlanted.v1';
const SEED_GPV_KEY       = 'craft.seedsGoldPer1000Voc.v1';
const SEED_GOLD_SORT_KEY = 'craft.seedsGoldSort.v1';
const SEED_VOC_SORT_KEY  = 'craft.seedsVocSort.v1';
const SEED_MODE_KEY      = 'craft.seedsMode.v1';

function loadNum(key, fallback) {
  try {
    const raw = localStorage.getItem(key);
    if (raw == null) return fallback;
    const v = parseFloat(raw);
    return Number.isFinite(v) && v >= 0 ? v : fallback;
  } catch (e) { return fallback; }
}

// ─── Format helpers ──────────────────────────────────────────────────────
function fmtHr(h) {
  if (!Number.isFinite(h)) return '—';
  if (h < 1) {
    const m = Math.round(h * 60);
    return `${m}m`;
  }
  if (Number.isInteger(h)) return `${h}h`;
  const hr = Math.floor(h);
  const mn = Math.round((h - hr) * 60);
  return mn === 0 ? `${hr}h` : `${hr}h ${mn}m`;
}

function climateClass(c) {
  if (!c) return 'none';
  return c.toLowerCase();
}
// Climate sigil: a single-glyph mark that pairs with the colored pill.
function climateGlyph(c) {
  if (!c) return '≋';        // water — no climate
  if (c === 'Temperate') return '☘';
  if (c === 'Tropical')  return '☀';
  if (c === 'Arid')      return '⌇';
  return '∞';                // Any
}
function ClimateMark({ climate }) {
  return (
    <span className={`climate-sigil ${climateClass(climate)}`} title={climate || 'Water — no climate'}>
      {climateGlyph(climate)}
    </span>
  );
}

// ─── Main panel ──────────────────────────────────────────────────────────
function SeedsPanel({ ctx, laborValue, currency }) {
  const [seedsPlanted, setSeedsPlanted]     = useStateSd(() => loadNum(SEED_PLANTED_KEY, 100));
  const [goldPer1000Voc, setGoldPer1000Voc] = useStateSd(() => loadNum(SEED_GPV_KEY, 2.5));
  const [goldSort, setGoldSort] = useStateSd(() => localStorage.getItem(SEED_GOLD_SORT_KEY) || 'profitPerLp');
  const [vocSort,  setVocSort]  = useStateSd(() => localStorage.getItem(SEED_VOC_SORT_KEY)  || 'profitPerLp');
  const [mode, setMode] = useStateSd(() => {
    const v = localStorage.getItem(SEED_MODE_KEY);
    return v === 'voc' || v === 'gold' ? v : 'gold';
  });
  const [expanded, setExpanded] = useStateSd({});

  useEffectSd(() => { try { localStorage.setItem(SEED_PLANTED_KEY, String(seedsPlanted)); } catch (e) {} }, [seedsPlanted]);
  useEffectSd(() => { try { localStorage.setItem(SEED_GPV_KEY,    String(goldPer1000Voc)); } catch (e) {} }, [goldPer1000Voc]);
  useEffectSd(() => { try { localStorage.setItem(SEED_GOLD_SORT_KEY, goldSort); } catch (e) {} }, [goldSort]);
  useEffectSd(() => { try { localStorage.setItem(SEED_VOC_SORT_KEY,  vocSort);  } catch (e) {} }, [vocSort]);
  useEffectSd(() => { try { localStorage.setItem(SEED_MODE_KEY, mode); } catch (e) {} }, [mode]);

  const nameIndex = useMemoSd(() => {
    const m = new Map();
    if (ctx && ctx.itemNames) {
      for (const [id, name] of ctx.itemNames) {
        const k = String(name || '').toLowerCase();
        if (!m.has(k)) m.set(k, { id, name });
      }
    }
    return m;
  }, [ctx]);

  function lookupHarvest(name) {
    const entry = nameIndex.get(String(name).toLowerCase());
    if (!entry) return { id: null, displayName: name, price: null, found: false };
    const price = ctx.prices[entry.id];
    return { id: entry.id, displayName: entry.name, price: price ?? null, found: price != null };
  }

  function computeRow(seed, isVoc) {
    const lookup = lookupHarvest(seed.harvest);
    const revenue = lookup.price != null ? seed.yield * lookup.price : null;
    const seedCostGold = isVoc
      ? (seed.costVoc / 1000) * goldPer1000Voc
      : seed.costSilver / 100;
    const cost = seedCostGold;
    const profit       = revenue != null ? revenue - cost : null;
    const profitPerLp  = profit  != null && seed.labor > 0 ? profit / seed.labor : null;
    const profitPerHr  = profit  != null && seed.growHr > 0 ? (profit * (seedsPlanted || 0)) / seed.growHr : null;
    const profitPer1kV = isVoc && profit != null && seed.costVoc > 0 ? profit / (seed.costVoc / 1000) : null;
    return { seed, lookup, revenue, seedCostGold, cost, profit, profitPerLp, profitPerHr, profitPer1kV };
  }

  const goldRows = useMemoSd(() => SEEDS_GOLD.map(s => computeRow(s, false)),
    [ctx, laborValue, nameIndex, seedsPlanted]);
  const vocRows  = useMemoSd(() => SEEDS_VOC.map(s => computeRow(s, true)),
    [ctx, laborValue, goldPer1000Voc, nameIndex, seedsPlanted]);

  function sortRows(rows, key) {
    const arr = rows.slice();
    arr.sort((a, b) => {
      const av = a[key], bv = b[key];
      const aMissing = a.lookup.price == null;
      const bMissing = b.lookup.price == null;
      if (aMissing !== bMissing) return aMissing ? 1 : -1;
      if (av == null && bv == null) return 0;
      if (av == null) return 1;
      if (bv == null) return -1;
      return bv - av;
    });
    return arr;
  }

  const sortedGold = useMemoSd(() => sortRows(goldRows, goldSort), [goldRows, goldSort]);
  const sortedVoc  = useMemoSd(() => sortRows(vocRows,  vocSort),  [vocRows,  vocSort]);

  const priceCount     = useMemoSd(() => Object.keys(ctx.prices).length, [ctx.prices]);
  const goldPriced     = goldRows.filter(r => r.lookup.price != null).length;
  const vocPriced      = vocRows.filter(r  => r.lookup.price != null).length;

  const isVocMode = mode === 'voc';
  const activeRows  = isVocMode ? sortedVoc : sortedGold;
  const activeCount = isVocMode ? SEEDS_VOC.length : SEEDS_GOLD.length;
  const activePriced = isVocMode ? vocPriced : goldPriced;
  const activeSort  = isVocMode ? vocSort  : goldSort;
  const setActiveSort = isVocMode ? setVocSort : setGoldSort;

  // Hero metric values
  const topRow = activeRows.find(r => r.profit != null);
  const totalProfitAtScale = activeRows.reduce((s, r) => s + (r.profit != null ? r.profit : 0), 0) * (seedsPlanted || 0) / activeCount;
  const bestProfitPerHr = activeRows.reduce((m, r) => (r.profitPerHr != null && r.profitPerHr > m ? r.profitPerHr : m), 0);
  const profitableCount = activeRows.filter(r => r.profit != null && r.profit > 0).length;

  return (
    <main className="detail wisp-view seeds-view v2">
      <div className="fade-in">

        {/* ── Page hero ─────────────────────────────────────────────── */}
        <div className="page-hero">
          <div className="page-hero-crest" aria-hidden>{isVocMode ? '⚜' : '⚘'}</div>
          <div className="page-hero-meta">
            <div className="page-hero-eyebrow">Farming Ledger</div>
            <h1 className="page-hero-title">
              <em>{isVocMode ? 'Vocation' : 'Gold'}</em> Seeds · Profitability
            </h1>
            <div className="page-hero-tags">
              <span><strong style={{color:'var(--parch)'}}>{activePriced}</strong>/{activeCount}&nbsp;seeds priced</span>
              <span className="dot" />
              <span style={{color: 'var(--labor)'}}>{laborValue}{currency}/labor <span style={{opacity: 0.6, fontSize: 10}}>· LP only</span></span>
              {isVocMode && (
                <>
                  <span className="dot" />
                  <span style={{color: 'var(--amethyst)'}}>{window.fmtG(goldPer1000Voc)}{currency}/1000 voc</span>
                </>
              )}
              <span className="dot" />
              <span style={{color: 'var(--muted)'}}>{priceCount.toLocaleString()} live prices loaded</span>
            </div>
          </div>
          <div className="page-hero-aside">
            <div className="hero-aside-card">
              <div className="hero-aside-label">Top performer</div>
              <div className="hero-aside-sub-label">
                {topRow ? topRow.seed.name : '—'}
                {topRow && <ClimateMark climate={topRow.seed.climate} />}
              </div>
              <div className="hero-aside-value">
                {topRow && topRow.profitPerLp != null
                  ? <><span>{topRow.profitPerLp >= 0 ? '+' : '−'}{window.fmtG(Math.abs(topRow.profitPerLp))}</span><span className="unit">{currency}/lp</span></>
                  : <span style={{color:'var(--muted)', fontSize:16, fontStyle:'italic'}}>no priced seeds</span>}
              </div>
              {topRow && topRow.profitPerHr != null && (
                <div className={`hero-aside-foot ${topRow.profitPerHr >= 0 ? 'pos' : 'neg'}`}>
                  {topRow.profitPerHr >= 0 ? '+' : '−'}{window.fmtG(Math.abs(topRow.profitPerHr))}{currency}/hr @ {seedsPlanted} planted
                </div>
              )}
            </div>
          </div>
        </div>

        {/* ── Hero metric strip ────────────────────────────────────── */}
        <div className="metric-strip">
          <div className="metric-cell hero accent">
            <div className="ms-label">Top seed</div>
            <div className="ms-value">
              {topRow
                ? <span style={{fontSize: 22, fontWeight: 500}}>{topRow.seed.name}</span>
                : <span style={{fontSize:16, color:'var(--muted)', fontStyle:'italic'}}>—</span>}
            </div>
            <div className="ms-sub">
              {topRow
                ? <>{topRow.profitPerLp >= 0 ? '+' : '−'}{window.fmtG(Math.abs(topRow.profitPerLp))}{currency}/lp · {topRow.seed.climate || 'water'}</>
                : 'awaiting prices'}
            </div>
          </div>
          <div className={`metric-cell ${profitableCount > 0 ? 'pos' : ''}`}>
            <div className="ms-label">Profitable</div>
            <div className="ms-value">
              <span>{profitableCount}</span>
              <span className="unit">/&thinsp;{activeCount}</span>
            </div>
            <div className="ms-sub">net gold positive</div>
          </div>
          <div className="metric-cell">
            <div className="ms-label">Best profit / hr</div>
            <div className="ms-value">
              {bestProfitPerHr > 0
                ? <><span>{window.fmtG(bestProfitPerHr)}</span><span className="unit">{currency}/hr</span></>
                : <span style={{color:'var(--muted)', fontSize:16, fontStyle:'italic'}}>—</span>}
            </div>
            <div className="ms-sub">@ {seedsPlanted} seeds planted</div>
          </div>
          <div className="metric-cell">
            <div className="ms-label">Catalogue</div>
            <div className="ms-value">
              <span>{activeCount}</span>
              <span className="unit">seeds</span>
            </div>
            <div className="ms-sub">{isVocMode ? 'paid in vocation badges' : 'paid in silver'}</div>
          </div>
        </div>

        {/* ── Mode bar + inputs ────────────────────────────────────── */}
        <div className="modebar-v2">
          <div className="toggle-stack">
            <div className="toggle-stack-label">Currency</div>
            <div className="toggle-group">
              <button
                className={mode === 'gold' ? 'on' : ''}
                onClick={() => { setMode('gold'); setExpanded({}); }}
              >
                <span className="gl">⛁</span> Gold seeds
              </button>
              <button
                className={mode === 'voc' ? 'on' : ''}
                onClick={() => { setMode('voc'); setExpanded({}); }}
              >
                <span className="gl">⚜</span> Vocation seeds
              </button>
            </div>
          </div>
          <div style={{flex: 1}} />
          {isVocMode && (
            <div className="stepper">
              <div className="stepper-label">Gold per 1000 voc</div>
              <div className="stepper-field">
                <button onClick={() => setGoldPer1000Voc(Math.max(0, +((goldPer1000Voc || 0) - 0.1).toFixed(4)))}>−</button>
                <input
                  type="number"
                  step="0.1"
                  min="0"
                  value={goldPer1000Voc}
                  onChange={(e) => setGoldPer1000Voc(e.target.value === '' ? 0 : Math.max(0, Number(e.target.value)))}
                />
                <span className="unit">{currency}</span>
                <button onClick={() => setGoldPer1000Voc(+((goldPer1000Voc || 0) + 0.1).toFixed(4))}>+</button>
              </div>
              <div className="stepper-hint">Opportunity cost weight</div>
            </div>
          )}
          <div className="stepper">
            <div className="stepper-label">Seeds planted</div>
            <div className="stepper-field">
              <button onClick={() => setSeedsPlanted(Math.max(0, Math.round((seedsPlanted || 0) - 10)))}>−</button>
              <input
                type="number"
                step="10"
                min="0"
                value={seedsPlanted}
                onChange={(e) => setSeedsPlanted(e.target.value === '' ? 0 : Math.max(0, Math.round(Number(e.target.value))))}
              />
              <span className="unit">plots</span>
              <button onClick={() => setSeedsPlanted(Math.round((seedsPlanted || 0) + 10))}>+</button>
            </div>
            <div className="stepper-hint">Scales Profit/Hr</div>
          </div>
        </div>

        {/* ── Ranked table ─────────────────────────────────────────── */}
        <div className="framed-section">
          <div className="framed-section-head">
            <span className="fs-eyebrow">Ledger</span>
            <span className="fs-title">{isVocMode ? 'Vocation Seeds' : 'Gold Seeds'} · sorted by {activeSort === 'profit' ? 'Profit' : activeSort === 'profitPerLp' ? 'Profit/LP' : activeSort === 'profitPerHr' ? 'Profit/Hr' : 'Profit/1k Voc'}</span>
            <span className="fs-rule" />
            <span className="fs-aside">{activeCount} rows</span>
          </div>

          {/* Sort chips */}
          <div style={{padding: '12px 18px', borderBottom: '1px solid var(--line)', background: 'rgba(20,28,48,0.35)'}}>
            <div className="chip-row">
              <span style={{fontSize:10, letterSpacing:'0.22em', textTransform:'uppercase', color:'var(--muted)', marginRight:4, fontWeight:600}}>Sort</span>
              {(isVocMode
                ? [
                    { id: 'profit',       label: 'Profit' },
                    { id: 'profitPerLp',  label: 'Profit / LP' },
                    { id: 'profitPerHr',  label: 'Profit / Hr' },
                    { id: 'profitPer1kV', label: 'Profit / 1k Voc' },
                  ]
                : [
                    { id: 'profit',      label: 'Profit' },
                    { id: 'profitPerLp', label: 'Profit / LP' },
                    { id: 'profitPerHr', label: 'Profit / Hr' },
                  ]
              ).map(o => (
                <button
                  key={o.id}
                  className={`chip ${activeSort === o.id ? 'on' : ''}`}
                  onClick={() => setActiveSort(o.id)}
                >{o.label}</button>
              ))}
            </div>
          </div>

          <SeedTableBody
            rows={activeRows}
            isVoc={isVocMode}
            sort={activeSort}
            expanded={expanded}
            setExpanded={setExpanded}
            prefix={isVocMode ? 'v' : 'g'}
            currency={currency}
            laborValue={laborValue}
            seedsPlanted={seedsPlanted}
            goldPer1000Voc={goldPer1000Voc}
            volumes={ctx.volumes || {}}
          />
        </div>

        {/* ── Notes ────────────────────────────────────────────────── */}
        <div className="notes-panel">
          <div className="notes-label">How to read this</div>
          Revenue = avg yield × AH price of harvested item. Cost is out-of-pocket gold to purchase the seed (vocation seeds converted at your <strong style={{color: 'var(--amethyst)'}}>g/1000 voc</strong> rate). <strong>Labor is tracked as LP only</strong> and is not added into gold cost — use <strong>Profit/LP</strong> to compare against your labor bottleneck, and <strong>Profit/1k Voc</strong> when vocation badges are the binding constraint. Rows with no AH price sink to the bottom and are tagged so you know what's missing.
        </div>
      </div>
    </main>
  );
}

// ─── Sortable table body ────────────────────────────────────────────────
function SeedTableBody({
  rows, isVoc, sort, expanded, setExpanded,
  prefix, currency, laborValue, seedsPlanted, goldPer1000Voc, volumes,
}) {
  const cols = isVoc ? 'seeds-row voc' : 'seeds-row gold';

  return (
    <div className="wisp-table seeds-table" style={{border: 0, borderRadius: 0, background: 'transparent'}}>
      <div className={`${cols} seeds-head`}>
        <div className="num">#</div>
        <div>Seed</div>
        <div>Climate</div>
        <div className="num">Grow</div>
        <div className="num">Labor</div>
        <div className="num">Avg yield</div>
        <div className="num">Revenue</div>
        <div className="num">Cost</div>
        <div className="num">Profit</div>
        <div className={`num ${sort === 'profitPerLp' ? 'sort-on' : ''}`}>Profit/LP</div>
        <div className={`num ${sort === 'profitPerHr' ? 'sort-on' : ''}`}>Profit/Hr</div>
        {isVoc && <div className={`num voc-col ${sort === 'profitPer1kV' ? 'sort-on' : ''}`} title="Gold profit per 1000 vocation badges spent">Profit / 1k Voc</div>}
      </div>
      {rows.map((r, i) => {
        const key = `${prefix}:${r.seed.name}`;
        const isOpen = !!expanded[key];
        const missing = r.lookup.price == null;
        const isLoss = r.profit != null && r.profit < 0;
        const isProfit = r.profit != null && r.profit > 0;
        const isTopProfitable = i === 0 && isProfit;
        return (
          <React.Fragment key={key}>
            <div
              className={`${cols} ${isOpen ? 'open' : ''} ${missing ? 'missing' : ''} ${isTopProfitable ? `best best-${isVoc ? 'voc' : 'gold'}` : ''}`}
              onClick={() => setExpanded(e => ({ ...e, [key]: !isOpen }))}
              style={{cursor: 'pointer'}}
            >
              <div className="num mono">{i + 1}</div>
              <div>
                <div className="wb-method" style={{display: 'flex', alignItems:'center', gap: 8}}>
                  <window.ItemIcon itemType={r.lookup.id} name={r.lookup.displayName} size="sm" />
                  <span style={{fontFamily:'var(--serif)', fontSize:15, color:'var(--parch)'}}>{r.seed.name}</span>
                  {isTopProfitable && <span className="best-ribbon">Top</span>}
                </div>
                <div className="wb-method-sub" style={{display:'flex', alignItems:'center', gap:8, marginTop:3}}>
                  {missing
                    ? <span className="missing-tag">missing: {r.seed.harvest} price</span>
                    : <span>→ {r.seed.harvest}</span>}
                  {(() => {
                    const vol = r.lookup.id != null && volumes ? volumes[r.lookup.id] : null;
                    if (!vol) return null;
                    const unit  = vol.p === 'week' ? '/wk' : '/day';
                    const label = vol.p === 'week' ? 'Weekly' : 'Daily';
                    return (
                      <span
                        className={`vol-tag mini ${vol.p === 'week' ? 'weekly' : ''}`}
                        title={`${label} auction volume: ${window.fmtInt(vol.v)} units${unit === '/wk' ? '/week' : '/day'}`}
                      >
                        <span className="vol-ico">↻</span>{window.fmtCompact(vol.v)}{unit}
                      </span>
                    );
                  })()}
                </div>
              </div>
              <div style={{display: 'flex', alignItems: 'center', gap: 6}}>
                <ClimateMark climate={r.seed.climate} />
                <span style={{fontSize: 11, color: 'var(--muted)', letterSpacing: '0.04em'}}>{r.seed.climate || 'water'}</span>
              </div>
              <div className="num mono" style={{color: 'var(--parch-3)'}}>{fmtHr(r.seed.growHr)}</div>
              <div className="num mono" style={{color: 'var(--labor)'}}>{r.seed.labor}</div>
              <div className="num mono" style={{color: 'var(--parch-3)'}}>×{r.seed.yield}</div>
              <div className="num mono" style={{color: r.revenue != null ? 'var(--gold)' : 'var(--muted)'}}>
                {r.revenue != null ? `${window.fmtG(r.revenue)}${currency}` : '—'}
              </div>
              <div className="num mono" style={{color: 'var(--parch-3)'}}>{window.fmtG(r.cost)}{currency}</div>
              <div className={`num mono best-profit ${isProfit ? 'pos' : isLoss ? 'neg' : ''}`}>
                {r.profit != null
                  ? `${r.profit >= 0 ? '+' : '−'}${window.fmtG(Math.abs(r.profit))}${currency}`
                  : '—'}
              </div>
              <div className={`num mono ${r.profitPerLp != null && r.profitPerLp >= 0 ? 'pos' : r.profitPerLp != null ? 'neg' : ''}`}>
                {r.profitPerLp != null
                  ? `${r.profitPerLp >= 0 ? '+' : '−'}${window.fmtG(Math.abs(r.profitPerLp))}`
                  : '—'}
              </div>
              <div className={`num mono ${r.profitPerHr != null && r.profitPerHr >= 0 ? 'pos' : r.profitPerHr != null ? 'neg' : ''}`}>
                {r.profitPerHr != null
                  ? `${r.profitPerHr >= 0 ? '+' : '−'}${window.fmtG(Math.abs(r.profitPerHr))}`
                  : '—'}
              </div>
              {isVoc && (
                <div className={`num mono voc-col ${r.profitPer1kV != null && r.profitPer1kV >= 0 ? 'pos' : r.profitPer1kV != null ? 'neg' : ''}`}>
                  {r.profitPer1kV != null
                    ? `${r.profitPer1kV >= 0 ? '+' : '−'}${window.fmtG(Math.abs(r.profitPer1kV))}`
                    : '—'}
                </div>
              )}
            </div>
            {isOpen && (
              <SeedBreakdown
                row={r}
                isVoc={isVoc}
                currency={currency}
                laborValue={laborValue}
                seedsPlanted={seedsPlanted}
                goldPer1000Voc={goldPer1000Voc}
              />
            )}
          </React.Fragment>
        );
      })}
    </div>
  );
}

// ─── Per-row inline breakdown ────────────────────────────────────────────
function SeedBreakdown({ row, isVoc, currency, laborValue, seedsPlanted, goldPer1000Voc }) {
  const { seed, lookup, revenue, seedCostGold, cost, profit, profitPerLp, profitPerHr, profitPer1kV } = row;
  const missing = lookup.price == null;
  return (
    <div className="wisp-breakdown one-col seeds-breakdown">
      <div className="wb-panel">
        <div className="wb-title" style={{display:'flex', alignItems:'center', gap:10}}>
          <ClimateMark climate={seed.climate} />
          <span>{seed.name} Seed → {seed.harvest}</span>
        </div>
        <div className="seeds-bd-grid">
          <div className="seeds-bd-col">
            <div className="seeds-bd-col-head">Revenue</div>
            <div className="wb-totals">
              <div className="wb-totals-row">
                <span>Avg yield</span>
                <span className="mono">×{seed.yield} {seed.harvest}</span>
              </div>
              <div className="wb-totals-row">
                <span>{seed.harvest} unit price</span>
                <span className="mono">{lookup.price != null ? `${window.fmtG(lookup.price)}${currency}` : <span className="missing-tag">missing</span>}</span>
              </div>
              <div className="wb-totals-row total">
                <span>Revenue</span>
                <span className="mono" style={{color: 'var(--gold)'}}>{revenue != null ? `${window.fmtG(revenue)}${currency}` : '—'}</span>
              </div>
            </div>
          </div>
          <div className="seeds-bd-col">
            <div className="seeds-bd-col-head">Cost</div>
            <div className="wb-totals">
              <div className="wb-totals-row">
                <span>Seed cost</span>
                <span className="mono">
                  {isVoc
                    ? <>{seed.costVoc} voc × {window.fmtG(goldPer1000Voc/1000)}{currency}/voc = {window.fmtG(seedCostGold)}{currency}</>
                    : <>{seed.costSilver}s = {window.fmtG(seedCostGold)}{currency}</>}
                </span>
              </div>
              <div className="wb-totals-row">
                <span style={{color: 'var(--labor)'}}>Labor</span>
                <span className="mono" style={{color: 'var(--labor)'}}>{seed.labor} lp <span style={{opacity: 0.6}}>(not priced)</span></span>
              </div>
              <div className="wb-totals-row total">
                <span>Total gold cost</span>
                <span className="mono">{window.fmtG(cost)}{currency}</span>
              </div>
            </div>
          </div>
          <div className="seeds-bd-col">
            <div className="seeds-bd-col-head">Profit</div>
            <div className="wb-totals">
              <div className="wb-totals-row">
                <span>Per craft</span>
                <span className={`mono ${profit != null && profit >= 0 ? 'pos' : profit != null ? 'neg' : ''}`} style={{fontWeight: 600}}>
                  {profit != null ? `${profit >= 0 ? '+' : '−'}${window.fmtG(Math.abs(profit))}${currency}` : '—'}
                </span>
              </div>
              <div className="wb-totals-row">
                <span>Profit / LP</span>
                <span className={`mono ${profitPerLp != null && profitPerLp >= 0 ? 'pos' : profitPerLp != null ? 'neg' : ''}`}>
                  {profitPerLp != null ? `${profitPerLp >= 0 ? '+' : '−'}${window.fmtG(Math.abs(profitPerLp))}${currency}/lp` : '—'}
                </span>
              </div>
              <div className="wb-totals-row">
                <span>Profit / Hr <span style={{color: 'var(--muted)', fontSize: 11}}>(× {seedsPlanted} planted)</span></span>
                <span className={`mono ${profitPerHr != null && profitPerHr >= 0 ? 'pos' : profitPerHr != null ? 'neg' : ''}`}>
                  {profitPerHr != null ? `${profitPerHr >= 0 ? '+' : '−'}${window.fmtG(Math.abs(profitPerHr))}${currency}/hr` : '—'}
                </span>
              </div>
              {isVoc && (
                <div className="wb-totals-row total">
                  <span style={{color: 'var(--amethyst)'}}>Profit / 1000 voc</span>
                  <span className={`mono ${profitPer1kV != null && profitPer1kV >= 0 ? 'pos' : profitPer1kV != null ? 'neg' : ''}`} style={{fontWeight: 600}}>
                    {profitPer1kV != null ? `${profitPer1kV >= 0 ? '+' : '−'}${window.fmtG(Math.abs(profitPer1kV))}${currency}` : '—'}
                  </span>
                </div>
              )}
            </div>
          </div>
        </div>
        {missing && (
          <div className="wb-chain-missing" style={{marginTop: 12}}>
            <strong>Missing AH price:</strong> {seed.harvest}. The row is sorted to the bottom until the price feed picks it up.
          </div>
        )}
      </div>
    </div>
  );
}

window.SeedsPanel = SeedsPanel;
