// Card loader.
//
// Each slide/card lives as its own JSON file under cards/.
// cards/manifest.json lists them in order.
//
// Markup convention:
//   *text*  →  accent italic (<em>text</em>)
// That's it — no other markup. Newlines (\n) in JSON are preserved in
// long-form text (card-lede on back faces).
//
// Exposes window.loadCards() → Promise<Card[]>. App.jsx awaits this
// before mounting, so CARDS is always populated by the time anything
// renders.

function parseEmphasis(text) {
  if (typeof text !== 'string' || !text.includes('*')) return text;
  const parts = text.split(/(\*[^*]+\*)/g);
  if (parts.length === 1) return text;
  return React.createElement(
    React.Fragment,
    null,
    ...parts.map((p, i) => {
      if (p.length >= 3 && p.startsWith('*') && p.endsWith('*') && !p.slice(1, -1).includes('*')) {
        return React.createElement('em', { key: i }, p.slice(1, -1));
      }
      return p;
    })
  );
}

function parseCard(raw) {
  const card = { ...raw };
  if ('title' in card) card.title = parseEmphasis(card.title);
  if ('name' in card) card.name = parseEmphasis(card.name);
  if ('subtitle' in card) card.subtitle = parseEmphasis(card.subtitle);
  if (Array.isArray(card.stats)) {
    card.stats = card.stats.map(s => ({ ...s, num: parseEmphasis(s.num) }));
  }
  if (Array.isArray(card.channels)) {
    card.channels = card.channels.map(c => ({ ...c, body: parseEmphasis(c.body) }));
  }
  if (card.pullquote && typeof card.pullquote.text === 'string') {
    card.pullquote = { ...card.pullquote, text: parseEmphasis(card.pullquote.text) };
  }
  if (card.back) {
    const b = { ...card.back };
    if ('title' in b) b.title = parseEmphasis(b.title);
    if ('lede' in b) b.lede = parseEmphasis(b.lede);
    if (Array.isArray(b.sections)) {
      b.sections = b.sections.map(s => ({ ...s, body: parseEmphasis(s.body) }));
    }
    card.back = b;
  }
  return card;
}

window.loadCards = async function loadCards() {
  const manifest = await fetch('cards/manifest.json').then(r => {
    if (!r.ok) throw new Error('Failed to load cards/manifest.json: ' + r.status);
    return r.json();
  });
  const files = await Promise.all(
    manifest.order.map(name =>
      fetch('cards/' + name).then(r => {
        if (!r.ok) throw new Error('Failed to load cards/' + name + ': ' + r.status);
        return r.json();
      })
    )
  );
  window.CARDS = files.map(parseCard);
  return window.CARDS;
};
