// pokedex-data.jsx
// 151 original creature entries + procedural pixel-sprite generator.
// All names/designs are original — no real Pokémon references.

const TYPES = [
  { id: 'normal',   name: 'Normal',   color: '#a8a878' },
  { id: 'fire',     name: 'Fire',     color: '#ff5a3c' },
  { id: 'water',    name: 'Water',    color: '#4aa6ff' },
  { id: 'grass',    name: 'Grass',    color: '#62c46b' },
  { id: 'electric', name: 'Electric', color: '#ffce3a' },
  { id: 'psychic',  name: 'Psychic',  color: '#a259ff' },
  { id: 'rock',     name: 'Rock',     color: '#a8927a' },
  { id: 'ground',   name: 'Ground',   color: '#d4b873' },
  { id: 'ghost',    name: 'Ghost',    color: '#7a87b8' },
  { id: 'fairy',    name: 'Fairy',    color: '#ff7ab6' },
  { id: 'dark',     name: 'Dark',     color: '#3d3a55' },
  { id: 'ice',      name: 'Ice',      color: '#9ee6ff' },
  { id: 'bug',      name: 'Bug',      color: '#9bbb3a' },
  { id: 'dragon',   name: 'Dragon',   color: '#7a4dff' },
  { id: 'fighting', name: 'Fighting', color: '#c03028' },
  { id: 'flying',   name: 'Flying',   color: '#a4a3f1' },
  { id: 'poison',   name: 'Poison',   color: '#a040a0' },
  { id: 'steel',    name: 'Steel',    color: '#b8b8d0' },
];
const TYPE_BY_ID = Object.fromEntries(TYPES.map(t => [t.id, t]));

// Canonical Gen 1 type + rarity data, keyed by national dex number.
// Types match PokéAPI exactly. Rarity reflects competitive/lore stature:
// legendary = birds + Mewtwo + Mew; epic = pseudo-legends, starter finals,
// signature mons; rare = strong finals; uncommon = mid evos; common = base.
const POKEMON_DATA = {
  1:['grass,poison','common'],     2:['grass,poison','uncommon'],  3:['grass,poison','epic'],
  4:['fire','common'],             5:['fire','uncommon'],          6:['fire,flying','epic'],
  7:['water','common'],            8:['water','uncommon'],         9:['water','epic'],
  10:['bug','common'],             11:['bug','common'],            12:['bug,flying','uncommon'],
  13:['bug,poison','common'],      14:['bug,poison','common'],     15:['bug,poison','uncommon'],
  16:['normal,flying','common'],   17:['normal,flying','common'],  18:['normal,flying','uncommon'],
  19:['normal','common'],          20:['normal','common'],
  21:['normal,flying','common'],   22:['normal,flying','uncommon'],
  23:['poison','common'],          24:['poison','uncommon'],
  25:['electric','uncommon'],      26:['electric','rare'],
  27:['ground','common'],          28:['ground','uncommon'],
  29:['poison','common'],          30:['poison','uncommon'],       31:['poison,ground','rare'],
  32:['poison','common'],          33:['poison','uncommon'],       34:['poison,ground','rare'],
  35:['fairy','uncommon'],         36:['fairy','rare'],
  37:['fire','common'],            38:['fire','uncommon'],
  39:['normal,fairy','common'],    40:['normal,fairy','uncommon'],
  41:['poison,flying','common'],   42:['poison,flying','uncommon'],
  43:['grass,poison','common'],    44:['grass,poison','uncommon'], 45:['grass,poison','rare'],
  46:['bug,grass','common'],       47:['bug,grass','uncommon'],
  48:['bug,poison','common'],      49:['bug,poison','uncommon'],
  50:['ground','common'],          51:['ground','uncommon'],
  52:['normal','common'],          53:['normal','uncommon'],
  54:['water','common'],           55:['water','uncommon'],
  56:['fighting','common'],        57:['fighting','uncommon'],
  58:['fire','common'],            59:['fire','rare'],
  60:['water','common'],           61:['water','uncommon'],        62:['water,fighting','rare'],
  63:['psychic','common'],         64:['psychic','uncommon'],      65:['psychic','epic'],
  66:['fighting','common'],        67:['fighting','uncommon'],     68:['fighting','epic'],
  69:['grass,poison','common'],    70:['grass,poison','uncommon'], 71:['grass,poison','rare'],
  72:['water,poison','common'],    73:['water,poison','uncommon'],
  74:['rock,ground','common'],     75:['rock,ground','uncommon'],  76:['rock,ground','epic'],
  77:['fire','common'],            78:['fire','rare'],
  79:['water,psychic','common'],   80:['water,psychic','rare'],
  81:['electric,steel','common'],  82:['electric,steel','uncommon'],
  83:['normal,flying','rare'],
  84:['normal,flying','common'],   85:['normal,flying','uncommon'],
  86:['water','common'],           87:['water,ice','uncommon'],
  88:['poison','common'],          89:['poison','uncommon'],
  90:['water','common'],           91:['water,ice','rare'],
  92:['ghost,poison','common'],    93:['ghost,poison','uncommon'], 94:['ghost,poison','epic'],
  95:['rock,ground','rare'],
  96:['psychic','common'],         97:['psychic','uncommon'],
  98:['water','common'],           99:['water','uncommon'],
  100:['electric','common'],       101:['electric','uncommon'],
  102:['grass,psychic','common'],  103:['grass,psychic','rare'],
  104:['ground','common'],         105:['ground','uncommon'],
  106:['fighting','rare'],         107:['fighting','rare'],
  108:['normal','rare'],
  109:['poison','common'],         110:['poison','uncommon'],
  111:['rock,ground','common'],    112:['rock,ground','rare'],
  113:['normal','epic'],
  114:['grass','rare'],
  115:['normal','rare'],
  116:['water','common'],          117:['water','uncommon'],
  118:['water','common'],          119:['water','uncommon'],
  120:['water','common'],          121:['water,psychic','rare'],
  122:['psychic,fairy','rare'],
  123:['bug,flying','rare'],
  124:['ice,psychic','rare'],
  125:['electric','rare'],
  126:['fire','rare'],
  127:['bug','rare'],
  128:['normal','rare'],
  129:['water','common'],          130:['water,flying','epic'],
  131:['water,ice','epic'],
  132:['normal','epic'],
  133:['normal','uncommon'],       134:['water','epic'],           135:['electric','epic'],   136:['fire','epic'],
  137:['normal','rare'],
  138:['rock,water','common'],     139:['rock,water','uncommon'],
  140:['rock,water','common'],     141:['rock,water','uncommon'],
  142:['rock,flying','epic'],
  143:['normal','epic'],
  144:['ice,flying','legendary'],  145:['electric,flying','legendary'], 146:['fire,flying','legendary'],
  147:['dragon','rare'],           148:['dragon','epic'],          149:['dragon,flying','epic'],
  150:['psychic','legendary'],     151:['psychic','legendary'],
};

// Made-up creature name parts
const PREFIXES = ['Spark', 'Flam', 'Aqua', 'Leaf', 'Pyro', 'Glim', 'Mist', 'Volt', 'Crag', 'Drak', 'Wisp', 'Glyph', 'Nebu', 'Frost', 'Hex', 'Ember', 'Tide', 'Bram', 'Pix', 'Lumi', 'Onyx', 'Sol', 'Luna', 'Murk', 'Char', 'Riff', 'Mosk', 'Quill', 'Thorn', 'Glow', 'Zap', 'Crys', 'Slime', 'Bun', 'Cind', 'Ploom', 'Spore', 'Brine', 'Whisk', 'Dross', 'Velve', 'Plink', 'Snug', 'Wyrm'];
const SUFFIXES = ['ling', 'mon', 'zar', 'ipu', 'oth', 'ipu', 'ix', 'ade', 'ari', 'ock', 'orn', 'umb', 'eo', 'ax', 'ynx', 'oro', 'ette', 'oss', 'ee', 'oo', 'ar', 'ick', 'em', 'ant', 'oof', 'us', 'eon', 'ig', 'oss', 'op'];

// Seeded pseudo-random
function srand(seed) {
  let s = seed | 0;
  return () => {
    s = (s * 1664525 + 1013904223) | 0;
    return ((s >>> 0) % 1_000_000) / 1_000_000;
  };
}

function makeName(seed) {
  const r = srand(seed);
  const p = PREFIXES[Math.floor(r() * PREFIXES.length)];
  const s = SUFFIXES[Math.floor(r() * SUFFIXES.length)];
  return p + s;
}

// Build 151 entries — types/rarity from canonical Gen 1 data;
// price, holders, level still procedural (mock market data).
const RARITY_PRICE_BOOST = { common: 0, uncommon: 0.006, rare: 0.018, epic: 0.05, legendary: 0.18 };
const POKEDEX = (() => {
  const out = [];
  for (let i = 1; i <= 151; i++) {
    const r = srand(i * 9301 + 49297);
    const [typeStr, rarity] = POKEMON_DATA[i];
    const types = typeStr.split(',').map(id => TYPE_BY_ID[id]).filter(Boolean);
    const basePrice = 0.0001 + r() * 0.012 + RARITY_PRICE_BOOST[rarity];
    const delta = (r() - 0.45) * 24;
    const supply = 1_000_000_000;
    const holders = Math.floor(200 + r() * (rarity === 'legendary' ? 12000 : rarity === 'epic' ? 8000 : 5000));
    const level = Math.floor(1 + r() * 99);
    out.push({
      n: i,
      name: makeName(i),
      types,
      rarity,
      price: basePrice,
      delta,
      supply,
      holders,
      level,
      seed: i,
    });
  }
  return out;
})();

// ── Sprite renderer ───────────────────────────────────────────────────────
// Procedural symmetric pixel monster on an 8×8 grid mirrored to 16×8.
// If a sprite URL pattern is provided via SpriteSourceContext, renders an
// <img> instead — letting the user point at any external sprite collection.

const SpriteSourceContext = React.createContext({ pattern: '' });

function spriteUrlFor(pattern, n) {
  if (!pattern || !n) return null;
  return pattern
    .replace(/\{n3\}/g, String(n).padStart(3, '0'))
    .replace(/\{n2\}/g, String(n).padStart(2, '0'))
    .replace(/\{n\}/g, String(n));
}

function Sprite({ seed = 1, n = null, primary = '#ff5a3c', secondary = null, size = 96, locked = false, eyeOpen = true }) {
  const cfg = React.useContext(SpriteSourceContext);
  const url = cfg && cfg.pattern ? spriteUrlFor(cfg.pattern, n || seed) : null;

  if (url) {
    // Match procedural sprite's bounding box (slightly wider than tall) so
    // layouts don't reflow when switching modes.
    const w = size * 1.8;
    const h = size * 1.4;
    return (
      <img
        src={url}
        alt=""
        width={w}
        height={h}
        style={{
          width: w,
          height: h,
          imageRendering: 'pixelated',
          objectFit: 'contain',
          display: 'block',
          maxWidth: '100%',
          maxHeight: '100%',
          filter: locked
            ? 'brightness(0) opacity(.5)'
            : 'drop-shadow(2px 3px 0 rgba(0,0,0,.35))',
        }}
        onError={(e) => { e.currentTarget.style.opacity = '0.25'; }}
      />
    );
  }

  const cells = React.useMemo(() => {
    const r = srand(seed);
    const W = 8, H = 8; // half-width
    const grid = Array.from({ length: H }, () => Array(W).fill(0));
    // Body blob: ensure at least row 2-6 has filled cells from col 0
    for (let y = 1; y < H; y++) {
      const filledProb = y < 2 ? 0.3 : y < 5 ? 0.85 : y === H - 1 ? 0.6 : 0.7;
      let extended = false;
      for (let x = 0; x < W; x++) {
        const closeToCenter = (W - 1 - x) / W;
        const p = filledProb * (0.4 + 0.7 * closeToCenter);
        if (r() < p) { grid[y][x] = 1; extended = true; }
        else if (extended && r() < 0.4) grid[y][x] = 1;
      }
    }
    // Limbs / ears
    if (r() > 0.4) { grid[0][1] = 1; grid[0][2] = 1; } // ear
    if (r() > 0.6) { grid[0][0] = 1; }
    // Eye position (row 2-3)
    const eyeRow = r() > 0.5 ? 2 : 3;
    const eyeCol = Math.min(W - 1, 3 + Math.floor(r() * 2));
    grid[eyeRow][eyeCol] = 2; // eye
    // Secondary color spots
    if (secondary) {
      for (let i = 0; i < 6; i++) {
        const y = Math.floor(r() * H);
        const x = Math.floor(r() * W);
        if (grid[y][x] === 1) grid[y][x] = 3;
      }
    }
    // Mouth
    if (r() > 0.4) {
      const my = Math.min(H - 2, eyeRow + 2);
      const mx = Math.min(W - 1, eyeCol);
      if (grid[my][mx] === 1) grid[my][mx] = 4;
    }
    return grid;
  }, [seed, secondary]);

  // Build SVG
  const W = 16, H = 8; // full
  const px = size / W;
  const cellSize = px;
  const cells2 = [];
  for (let y = 0; y < H; y++) {
    for (let x = 0; x < W; x++) {
      const xx = x < 8 ? 7 - x : x - 8;
      const v = cells[y][xx];
      if (v === 0) continue;
      let fill = primary;
      if (v === 2) fill = '#14172b'; // eye
      else if (v === 3) fill = secondary || primary;
      else if (v === 4) fill = '#14172b';
      cells2.push(
        <rect
          key={`${x}-${y}`}
          x={x * cellSize}
          y={y * cellSize}
          width={cellSize + 0.5}
          height={cellSize + 0.5}
          fill={fill}
          stroke={v === 1 || v === 3 ? 'rgba(0,0,0,.18)' : 'none'}
          strokeWidth={cellSize * 0.05}
        />
      );
      // Eye highlight
      if (v === 2 && eyeOpen) {
        cells2.push(
          <rect
            key={`${x}-${y}-hi`}
            x={x * cellSize + cellSize * 0.55}
            y={y * cellSize + cellSize * 0.15}
            width={cellSize * 0.3}
            height={cellSize * 0.3}
            fill="#fff"
          />
        );
      }
    }
  }
  return (
    <svg
      viewBox={`0 0 ${W * cellSize} ${H * cellSize + cellSize}`}
      width={size * 2}
      height={size + cellSize * 0.5}
      style={{
        imageRendering: 'pixelated',
        maxWidth: '100%',
        display: 'block',
        filter: locked ? 'brightness(0) opacity(.45)' : 'drop-shadow(2px 4px 0 rgba(0,0,0,.25))',
      }}
    >
      {cells2}
      {/* Shadow */}
      <ellipse
        cx={W * cellSize / 2}
        cy={H * cellSize + cellSize * 0.4}
        rx={W * cellSize * 0.28}
        ry={cellSize * 0.35}
        fill="rgba(0,0,0,.22)"
      />
    </svg>
  );
}

// helper to format prices
function fmtPrice(p) {
  if (p >= 1)    return p.toFixed(3);
  if (p >= 0.01) return p.toFixed(4);
  return p.toFixed(5);
}
function fmtDelta(d) {
  const s = d >= 0 ? '+' : '';
  return `${s}${d.toFixed(2)}%`;
}

Object.assign(window, { POKEDEX, TYPES, Sprite, SpriteSourceContext, fmtPrice, fmtDelta, srand });
