// app.jsx — Top-level composition + state

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "edition": "red",
  "scanlines": true,
  "shake": true,
  "tagline": "CATCH 'EM. TRADE 'EM. FLEX 'EM.",
  "spritePattern": "",
  "namesList": ""
}/*EDITMODE-END*/;

const EDITIONS = {
  red:  { name: 'RED',  red: '#e53935', accent: '#ffce3a', bg: '#0c0f1e',  bg2: '#141934' },
  blue: { name: 'BLUE', red: '#2746c3', accent: '#5ad8ff', bg: '#0a1024',  bg2: '#0f1a3a' },
  gold: { name: 'GOLD', red: '#c08020', accent: '#ffce3a', bg: '#1a1408',  bg2: '#2a1f0e' },
  pink: { name: 'PINK', red: '#ff5a9c', accent: '#ffce3a', bg: '#1a0a18',  bg2: '#2a1230' },
};

// Common community sprite URL patterns — paste one of these into the
// "Sprite URL pattern" field. {n} = dex number, {n3} = zero-padded 3-digit.
const SPRITE_PRESETS = {
  procedural: '',
  // Example placeholder; user can plug in any provider they trust.
  custom: '',
};

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [caught, setCaught] = React.useState(() => new Set([1, 4, 7, 25, 50, 94, 130, 144, 150]));
  const [marketCap, setMarketCap] = React.useState(8.42);
  const [dexVersion, setDexVersion] = React.useState(0);

  // Auto-fetch Gen 1 names + sprites on first load (so users see real data
  // without having to open the Tweaks panel). Once they've set anything,
  // we don't override.
  React.useEffect(() => {
    if (t.spritePattern || t.namesList) return;  // already configured
    let cancelled = false;
    (async () => {
      try {
        const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=151');
        if (!res.ok) return;
        const data = await res.json();
        if (cancelled) return;
        const names = data.results.map(p => p.name)
          .map(n => n.charAt(0).toUpperCase() + n.slice(1));
        setTweak({
          namesList: names.join(', '),
          spritePattern: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{n}.png',
        });
      } catch (e) { /* keep procedural */ }
    })();
    return () => { cancelled = true; };
  }, []);

  // Tick the market cap
  React.useEffect(() => {
    const i = setInterval(() => {
      setMarketCap(m => Math.max(1, m + (Math.random() - 0.45) * 0.18));
    }, 1800);
    return () => clearInterval(i);
  }, []);

  // Apply edition theme via CSS vars
  React.useEffect(() => {
    const e = EDITIONS[t.edition] || EDITIONS.red;
    const r = document.documentElement;
    r.style.setProperty('--pd-red', e.red);
    r.style.setProperty('--pd-yellow', e.accent);
    r.style.setProperty('--pd-bg', e.bg);
    r.style.setProperty('--pd-bg-2', e.bg2);
    document.body.style.background = e.bg;
  }, [t.edition]);

  // Scanlines toggle
  React.useEffect(() => {
    document.body.classList.toggle('no-scan', !t.scanlines);
  }, [t.scanlines]);

  // Names override: mutate POKEDEX in place when the list changes
  React.useEffect(() => {
    const raw = (t.namesList || '').trim();
    if (raw) {
      const list = raw.split(/[\n,]/).map(s => s.trim()).filter(Boolean);
      list.forEach((name, i) => {
        if (i < POKEDEX.length && name) POKEDEX[i] = { ...POKEDEX[i], name };
      });
    } else {
      // Re-seed original names? Easiest: do nothing — original names remain.
      // (Reload to fully reset.)
    }
    setDexVersion(v => v + 1);
  }, [t.namesList]);

  function catchOne(entry) {
    setCaught(s => {
      const next = new Set(s);
      next.add(entry.n);
      return next;
    });
  }

  const spriteCfg = React.useMemo(() => ({ pattern: t.spritePattern || '' }), [t.spritePattern]);

  return (
    <SpriteSourceContext.Provider value={spriteCfg}>
      <Nav t={{ connected: false }} onConnect={() => {}} />
      <Hero key={`hero-${dexVersion}`} t={t} marketCap={marketCap} onCatch={catchOne} />
      <MarqueeTicker key={`tick-${dexVersion}`} />
      <Mechanic key={`mech-${dexVersion}`} />
      <PlayerTiers />
      <DivBanner text={t.tagline} />
      <DexGridSection key={`dex-${dexVersion}`} caught={caught} onCatch={catchOne} />
      <Battle key={`battle-${dexVersion}`} />
      <TournamentsLineup />
      <Gacha key={`gacha-${dexVersion}`} onCatch={catchOne} />
      <Arena key={`arena-${dexVersion}`} caught={caught} />
      <Footer />

      <TweaksPanel>
        <TweakSection label="Edition" />
        <TweakRadio
          label="Theme"
          value={t.edition}
          options={['red', 'blue', 'gold', 'pink']}
          onChange={v => setTweak('edition', v)}
        />

        <TweakSection label="FX" />
        <TweakToggle label="CRT scanlines" value={t.scanlines} onChange={v => setTweak('scanlines', v)} />
        <TweakToggle label="Idle shake"   value={t.shake}     onChange={v => setTweak('shake', v)} />

        <TweakSection label="Copy" />
        <TweakText label="Marquee tagline" value={t.tagline} onChange={v => setTweak('tagline', v)} />

        <TweakSection label="External Sprites" />
        <TweakText
          label="Sprite URL pattern"
          placeholder="e.g. /sprites/{n3}.png  or  https://.../{n}.png"
          value={t.spritePattern}
          onChange={v => setTweak('spritePattern', v)}
        />
        <PresetRow setTweak={setTweak} />
        <NamesTextarea value={t.namesList} onChange={v => setTweak('namesList', v)} />
        <HintBox />
      </TweaksPanel>
    </SpriteSourceContext.Provider>
  );
}

function PresetRow({ setTweak }) {
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState('');

  async function fetchFromPokeAPI() {
    setLoading(true);
    setError('');
    try {
      const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=151');
      if (!res.ok) throw new Error('Network');
      const data = await res.json();
      const names = data.results
        .map(p => p.name)
        .map(n => n.charAt(0).toUpperCase() + n.slice(1));
      setTweak('namesList', names.join(', '));
      // Community-mirrored Gen-1 sprite repo. {n} = dex number.
      setTweak('spritePattern', 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{n}.png');
    } catch (e) {
      setError('Fetch failed — check your network');
    } finally {
      setLoading(false);
    }
  }

  return (
    <>
      <div style={{ display: 'flex', gap: 6, marginTop: 4 }}>
        <button onClick={() => setTweak('spritePattern', '')} style={presetBtn}>
          Procedural
        </button>
        <button onClick={() => setTweak('spritePattern', 'sprites/{n3}.png')} style={presetBtn}>
          Local folder
        </button>
      </div>
      <button
        onClick={fetchFromPokeAPI}
        disabled={loading}
        style={{
          ...presetBtn,
          background: loading ? 'rgba(0,0,0,.05)' : '#ffce3a',
          border: '1px solid rgba(0,0,0,.18)',
          fontWeight: 600,
          marginTop: 6,
          padding: '8px 10px',
          fontSize: 11.5,
        }}
      >
        {loading ? '◌ FETCHING…' : '⚡ Fetch names + sprites (Gen 1)'}
      </button>
      {error && <div style={{ fontSize: 10, color: '#b71c1c', marginTop: 4 }}>{error}</div>}
    </>
  );
}
const presetBtn = {
  flex: 1,
  padding: '6px 8px',
  fontSize: 11,
  fontFamily: 'inherit',
  background: 'rgba(0,0,0,.05)',
  border: '1px solid rgba(0,0,0,.12)',
  borderRadius: 4,
  cursor: 'pointer',
  color: 'inherit',
};

function NamesTextarea({ value, onChange }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
      <div style={{
        fontSize: 11, color: 'rgba(41,38,27,.72)', fontWeight: 500,
      }}>Names list <span style={{ opacity: .55, fontWeight: 400 }}>(comma or newline; in dex order)</span></div>
      <textarea
        value={value}
        placeholder="Name1, Name2, Name3, ..."
        onChange={e => onChange(e.target.value)}
        style={{
          width: '100%',
          minHeight: 80,
          maxHeight: 200,
          padding: '6px 8px',
          fontSize: 11,
          lineHeight: 1.4,
          fontFamily: 'ui-monospace, monospace',
          background: '#fff',
          border: '1px solid rgba(0,0,0,.18)',
          borderRadius: 4,
          resize: 'vertical',
          color: '#29261b',
          boxSizing: 'border-box',
        }}
      />
    </div>
  );
}

function HintBox() {
  return (
    <div style={{
      fontSize: 10.5,
      lineHeight: 1.45,
      color: 'rgba(41,38,27,.6)',
      padding: '8px 10px',
      background: 'rgba(255,206,58,.18)',
      borderLeft: '3px solid #ffce3a',
      borderRadius: 2,
      marginTop: 4,
    }}>
      <b>Personal use only.</b> Click "Fetch names + sprites" to pull Gen-1 data from the
      public PokéAPI community mirror. Or drop your own files into a <code style={{ background: 'rgba(0,0,0,.06)', padding: '0 3px' }}>sprites/</code> folder and use the local preset.
    </div>
  );
}

function DivBanner({ text }) {
  const items = [text, '◉', text, '◉', text, '◉'];
  return (
    <div className="divider-banner">
      <div className="divider-banner__inner">
        {[...items, ...items].map((s, i) => (
          <span key={i}>{s}</span>
        ))}
      </div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
