// council-cards.jsx — Roster grid + Agent card.
// 25 NFT cards in a 5-column grid (4 on smaller screens). Each card reads
// like a passport: token id, sigil, name, role, stake, accuracy, vote history,
// TBA address, link to Basescan.

function AgentCard({ agent, dim = false, onClick, sigilSize = 88, spacious = false }) {
  const spec     = SPEC[agent.specialty];
  const s        = statsFor(agent.id);
  const tba      = tbaFor(agent.id);
  const active   = s.lastVoteSec < 600;
  const accPct   = (s.accuracy * 100).toFixed(1);

  // Per-agent palette resolution — pulls from the Quantum Palette.
  // `palColor` is the a11y-corrected text/accent hex (legible on dark surface)
  // `palVisual` is the raw hex for sigil shape rendering (full saturation)
  // `palField` is the duotone partner color for constellation lines
  const palEntry = agentPaletteEntry(agent);
  const palColor = agentPaletteColor(agent, 'surface');
  const palVisual = agentPaletteRaw(agent);
  const palField = agentFieldColor(agent) || palColor;
  const palSoft  = palVisual + '1a';
  const accent   = palColor;
  const accentSoft = palSoft;

  return (
    <button
      onClick={onClick}
      style={{
        textAlign: 'left', cursor: onClick ? 'pointer' : 'default',
        background: T.ink, color: T.textInv,
        border: `1px solid ${T.inkBorder}`,
        padding: 0, position: 'relative',
        opacity: dim ? 0.32 : 1,
        transition: 'opacity .25s ease, transform .2s ease, border-color .2s ease, box-shadow .2s ease',
      }}
      onMouseEnter={e => {
        if (dim) return;
        e.currentTarget.style.borderColor = accent;
        e.currentTarget.style.transform = 'translateY(-2px)';
        e.currentTarget.style.boxShadow = `0 16px 40px -16px ${accent}55`;
      }}
      onMouseLeave={e => {
        e.currentTarget.style.borderColor = T.inkBorder;
        e.currentTarget.style.transform = 'translateY(0)';
        e.currentTarget.style.boxShadow = 'none';
      }}
    >
      <CornerMark where="tl" color={T.inkBorder}/>
      <CornerMark where="tr" color={T.inkBorder}/>
      <CornerMark where="bl" color={T.inkBorder}/>
      <CornerMark where="br" color={T.inkBorder}/>

      {/* top bar — token id + status pulse */}
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '10px 14px', borderBottom: `1px solid ${T.inkBorder}`,
        background: 'rgba(244,244,240,0.02)',
      }}>
        <Mono color={accent} weight={500} size={11}>#{String(agent.id).padStart(2, '0')} · {spec.tag}</Mono>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
          <span style={{
            width: 6, height: 6, borderRadius: '50%',
            background: active ? T.allow : T.muteInv,
            boxShadow: active ? `0 0 0 2px ${T.allow}33` : 'none',
            animation: active ? 'pulse-soft 1.8s ease-out infinite' : 'none',
          }}/>
          <Mono color={active ? T.allow : T.muteInv} size={9.5} weight={500}>
            {active ? 'ACTIVE' : 'IDLE'}
          </Mono>
        </span>
      </div>

      {/* Sigil + name */}
      <div style={{
        padding: spacious ? '36px 18px 22px' : '22px 14px 14px',
        display: 'flex', flexDirection: 'column', alignItems: 'center',
        background: accentSoft,
      }}>
        <Sigil id={agent.id} color={palVisual} fieldColor={palField} size={sigilSize}/>
        <div style={{
          marginTop: spacious ? 18 : 12,
          fontFamily: GMONO, fontSize: spacious ? 20 : 16, fontWeight: 600,
          letterSpacing: spacious ? 1.8 : 1.4, color: T.textInv,
        }}>{agent.name}</div>
        <div style={{
          marginTop: spacious ? 6 : 4, fontFamily: GEIST, fontSize: spacious ? 13 : 11.5,
          color: 'rgba(244,244,240,0.6)', letterSpacing: -0.05, textAlign: 'center',
          lineHeight: 1.4, maxWidth: spacious ? 260 : 200,
        }}>{agent.role}</div>
      </div>

      {/* Palette quantum claim — advantage + multiplier from the brand JSON */}
      {palEntry && (
        <div style={{
          padding: '10px 14px', borderTop: `1px solid ${T.inkBorder}`,
          background: 'rgba(244,244,240,0.015)',
        }}>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 8 }}>
            <Mono color={accent} size={9} weight={600}>{palEntry.advantage.toUpperCase()}</Mono>
            <span style={{
              fontFamily: GMONO, fontSize: 13, fontWeight: 500,
              color: accent, letterSpacing: 0.3,
            }}>{palEntry.mLabel}</span>
          </div>
          <Mono color={T.muteInv} size={9} style={{ display: 'block', marginTop: 4, letterSpacing: 0.4 }}>
            {palEntry.name.toUpperCase()}
          </Mono>
        </div>
      )}

      {/* stats */}
      <div style={{
        padding: '14px 14px 8px',
        borderTop: `1px solid ${T.inkBorder}`,
        display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 12,
      }}>
        <Stat k="STAKE" v={`${s.stakeEth} ETH`}/>
        <Stat k="ACCURACY" v={`${accPct}%`} color={s.accuracy > 0.88 ? accent : T.textInv}/>
        <Stat k="CLEARED" v={s.cleared.toLocaleString()}/>
        <Stat k="REFUSED" v={s.refused.toLocaleString()}/>
      </div>

      {/* accuracy bar */}
      <div style={{
        margin: '0 14px 12px', position: 'relative',
        height: 4, background: 'rgba(244,244,240,0.06)',
      }}>
        <div style={{
          position: 'absolute', inset: 0, width: `${accPct}%`,
          background: accent, opacity: 0.85,
        }}/>
      </div>

      {/* TBA address footer */}
      <div style={{
        padding: '12px 14px', borderTop: `1px solid ${T.inkBorder}`,
        background: 'rgba(244,244,240,0.015)',
      }}>
        <Mono color={T.muteInv} size={9}>TOKEN-BOUND ACCOUNT</Mono>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 4 }}>
          <span style={{
            fontFamily: GMONO, fontSize: 11.5, letterSpacing: 0.3,
            color: T.textInv,
          }}>{fmtAddr(tba, 6, 4)}</span>
          <a href={basescanAddr(tba)} target="_blank" rel="noopener"
             style={{
               fontFamily: GMONO, fontSize: 9.5, letterSpacing: 0.8,
               color: accent, textTransform: 'uppercase',
             }}
             onClick={e => e.stopPropagation()}
          >BASESCAN ↗</a>
        </div>
        <Mono color={T.muteInv} size={9.5} style={{ display: 'block', marginTop: 8 }}>
          LAST VOTE · {timeAgo(s.lastVoteSec)}
          {s.slashCount > 0 && (
            <span style={{ color: T.refuse, marginLeft: 8 }}>· {s.slashCount} SLASH{s.slashCount > 1 ? 'ES' : ''}</span>
          )}
        </Mono>
      </div>

      {/* Genesis — real on-chain mint receipt */}
      {(() => {
        const g = (typeof genesisFor === 'function') ? genesisFor(agent.id) : null;
        if (!g) return null;
        const date = genesisDate(agent.id);
        const time = genesisTimeOfDay(agent.id);
        return (
          <a href={basescanTx(g.tx)} target="_blank" rel="noopener"
             onClick={e => e.stopPropagation()}
             style={{
               display: 'block', padding: '10px 14px',
               borderTop: `1px solid ${T.inkBorder}`,
               background: 'rgba(244,244,240,0.03)',
               transition: 'background .15s',
             }}
             onMouseEnter={e => e.currentTarget.style.background = accentSoft}
             onMouseLeave={e => e.currentTarget.style.background = 'rgba(244,244,240,0.03)'}
          >
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
              <Mono color={accent} size={9} weight={600}>GENESIS · BORN</Mono>
              <Mono color={T.muteInv} size={9} style={{ letterSpacing: 0.4 }}>BLOCK #{g.block.toLocaleString()}</Mono>
            </div>
            <div style={{
              marginTop: 5, fontFamily: GMONO, fontSize: 11, letterSpacing: 0.3,
              color: T.textInv,
            }}>{date}<span style={{ color: T.muteInv, marginLeft: 8 }}>{time}</span></div>
            <Mono color={T.muteInv} size={9} style={{ display: 'block', marginTop: 4 }}>
              TX {g.tx.slice(0, 10)}…{g.tx.slice(-6)} ↗
            </Mono>
          </a>
        );
      })()}
    </button>
  );
}

function Stat({ k, v, color }) {
  return (
    <div>
      <Mono color={T.muteInv} size={9}>{k}</Mono>
      <div style={{
        fontFamily: GMONO, fontSize: 13, marginTop: 3,
        color: color || T.textInv, letterSpacing: 0.3, lineHeight: 1.1,
      }}>{v}</div>
    </div>
  );
}

// ── Filter chips ──────────────────────────────────────────────
function SpecFilter({ active, onChange }) {
  const counts = Object.fromEntries(ALL_SPECS.map(k => [k, agentsBySpec(k).length]));
  const items = [
    { key: 'all', label: 'All 25', color: T.allow, count: 25 },
    ...ALL_SPECS.map(k => ({ key: k, label: SPEC[k].label, color: SPEC[k].color, count: counts[k] })),
  ];
  return (
    <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
      <Mono color={T.muteInv} size={10}>FILTER</Mono>
      {items.map(it => {
        const on = active === it.key;
        return (
          <button key={it.key} onClick={() => onChange(it.key)} style={{
            background: on ? it.color : 'transparent',
            color: on ? T.ink : T.textInv,
            border: `1px solid ${on ? it.color : T.inkBorder}`,
            padding: '7px 12px', cursor: 'pointer',
            fontFamily: GMONO, fontSize: 10, letterSpacing: 1, fontWeight: 500,
            textTransform: 'uppercase',
            display: 'inline-flex', alignItems: 'center', gap: 6,
            transition: 'all .15s ease',
          }}>
            {it.label}
            <span style={{
              fontSize: 9, opacity: 0.6,
              background: on ? 'rgba(10,11,14,0.18)' : 'rgba(244,244,240,0.06)',
              padding: '1px 5px',
            }}>{it.count}</span>
          </button>
        );
      })}
    </div>
  );
}

// ── The roster grid ───────────────────────────────────────────
function Roster({ onPick, layout = 'compact' }) {
  const [filter, setFilter] = React.useState('all');
  const layoutConfig = {
    compact:  { cols: 5, sigil: 88,  gap: 16 },
    comfort:  { cols: 4, sigil: 112, gap: 20 },
    showcase: { cols: 3, sigil: 152, gap: 24 },
  }[layout] || { cols: 5, sigil: 88, gap: 16 };
  const filtered = filter === 'all' ? AGENTS : agentsBySpec(filter);
  return (
    <div>
      <div style={{
        display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
        gap: 16, marginBottom: 22, flexWrap: 'wrap',
      }}>
        <div>
          <Mono color={T.allow} weight={500}>§ 02 · THE ROSTER</Mono>
          <h2 style={{
            fontFamily: GEIST, fontWeight: 600, fontSize: 36, letterSpacing: -1.2, lineHeight: 1.05,
            margin: '10px 0 6px', color: T.textInv,
          }}>Twenty-five agents. Twenty-five names.</h2>
          <p style={{
            margin: 0, maxWidth: 560, fontSize: 15, lineHeight: 1.55,
            color: T.muteInv, letterSpacing: -0.1,
          }}>
            Each card below is a real NFT on Base. Click any agent to inspect its token-bound account on Basescan — wallet balance, vote history, transaction trail. No backend trust required.
          </p>
        </div>
        <SpecFilter active={filter} onChange={setFilter}/>
      </div>

      <div style={{
        display: 'grid', gap: layoutConfig.gap,
        gridTemplateColumns: `repeat(${layoutConfig.cols}, minmax(0, 1fr))`,
      }}>
        {AGENTS.map(a => (
          <AgentCard key={a.id}
            agent={a}
            sigilSize={layoutConfig.sigil}
            spacious={layout === 'showcase'}
            dim={filter !== 'all' && a.specialty !== filter}
          />
        ))}
      </div>

      {/* Legend / aggregate strip */}
      <RosterAggregate/>
    </div>
  );
}

function RosterAggregate() {
  const agg = aggregateStats();
  const cells = [
    { k: 'AGENTS',          v: `${agg.totalAgents} / 25` },
    { k: 'TOTAL STAKE',     v: `${agg.totalStake} ETH` },
    { k: 'AVG ACCURACY',    v: `${(agg.avgAccuracy * 100).toFixed(1)}%` },
    { k: 'VOTES CAST',      v: agg.totalVotes.toLocaleString() },
    { k: 'ORDERS CLEARED',  v: agg.totalCleared.toLocaleString() },
    { k: 'HISTORICAL SLASHES', v: agg.totalSlashes },
  ];
  return (
    <div style={{
      marginTop: 24, display: 'grid', gridTemplateColumns: `repeat(${cells.length}, 1fr)`,
      border: `1px solid ${T.inkBorder}`, background: 'rgba(244,244,240,0.02)',
    }}>
      {cells.map((c, i) => (
        <div key={c.k} style={{
          padding: '18px 22px',
          borderLeft: i === 0 ? 'none' : `1px solid ${T.inkBorder}`,
        }}>
          <Mono color={T.allow} weight={500} size={10}>{c.k}</Mono>
          <div style={{
            marginTop: 6, fontFamily: GMONO, fontSize: 18, fontWeight: 500,
            color: T.textInv, letterSpacing: 0.3,
          }}>{c.v}</div>
        </div>
      ))}
    </div>
  );
}

Object.assign(window, { AgentCard, Roster, SpecFilter, Stat });
