/* App root: ticket modal, tweaks panel, router */
const { useState: useStateApp, useEffect: useEffectApp } = React;
const {
  Icon, WandLogo, EventPosterPlaceholder,
  Nav, Footer, useHashRoute,
  HomePage, AboutPage, EventsPage, VenuesPage, GalleryPage, FAQPage, ContactPage, PrivacyPage,
  useTweaks, TweaksPanel, TweakSection, TweakSelect, TweakRadio,
} = window;

/* ===== Ticket Modal ===== */
function TicketModal({ event, onClose }) {
  const [step, setStep] = useStateApp('select'); // select | review | confirm
  const [tier, setTier] = useStateApp(null);
  const [qty, setQty] = useStateApp(2);

  useEffectApp(() => {
    const k = (e) => e.key === 'Escape' && onClose();
    window.addEventListener('keydown', k);
    return () => window.removeEventListener('keydown', k);
  }, [onClose]);

  if (!event) return null;

  const total = tier ? parseInt(tier.price.replace('$', '')) * qty : 0;

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <button className="modal-close" onClick={onClose} aria-label="Close"><Icon name="close" size={18} /></button>
        <div className="modal-poster">
          <div style={{ position: 'relative', width: '100%', height: '100%' }}>
            {event.photo
              ? <img src={event.photo} alt={event.title} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />
              : <EventPosterPlaceholder style={event.posterStyle} title={event.title} />}
          </div>
        </div>
        <div className="modal-body">
          {step === 'select' && (
            <div>
              <div className="eyebrow-ink">{event.type} · {event.date.month} {event.date.day}</div>
              <h3>{event.title}</h3>
              <div className="row"><Icon name="calendar" size={16} /> {event.dow}, {event.date.month} {event.date.day}, {event.date.year}</div>
              <div className="row"><Icon name="clock" size={16} /> {event.time}</div>
              <div className="row"><Icon name="pin" size={16} /> {event.venue}</div>
              <p>{event.description}</p>

              <div style={{ marginTop: 22, fontSize: 12, fontWeight: 800, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-700)', marginBottom: 12 }}>Choose Your Seats</div>
              {event.tiers.map((t) => {
                const availClass = t.availability === 'good' ? 'avail-good' : t.availability === 'selling-fast' ? 'avail-fast' : 'avail-few';
                const availLabel = t.availability === 'good' ? 'Available' : t.availability === 'selling-fast' ? 'Selling Fast' : 'Few Left';
                const sel = tier?.name === t.name;
                return (
                  <button
                    key={t.name}
                    onClick={() => setTier(t)}
                    className="tier-row"
                    style={{
                      width: '100%',
                      cursor: 'pointer',
                      background: sel ? 'rgba(212,166,66,0.12)' : 'transparent',
                      borderColor: sel ? 'var(--gold-500)' : 'rgba(20,30,60,0.12)',
                      textAlign: 'left',
                    }}
                  >
                    <div>
                      <div style={{ fontFamily: 'var(--f-display)', fontSize: 16, fontWeight: 600, color: 'var(--ink-900)' }}>{t.name}</div>
                      <div className={`availability ${availClass}`} style={{ marginTop: 4 }}>{availLabel}</div>
                    </div>
                    <div className="price">{t.price}</div>
                  </button>
                );
              })}

              <div className="modal-actions">
                <button className="btn btn-primary" disabled={!tier} onClick={() => setStep('review')} style={{ opacity: tier ? 1 : 0.5 }}>
                  Continue <Icon name="chevronRight" size={14} stroke={2.4} />
                </button>
                <button className="btn btn-ghost" style={{ color: 'var(--ink-700)', borderColor: 'rgba(20,30,60,0.18)' }} onClick={onClose}>Cancel</button>
              </div>
            </div>
          )}

          {step === 'review' && tier && (
            <div>
              <div className="eyebrow-ink">Review Order</div>
              <h3>{event.title}</h3>
              <div className="row"><Icon name="calendar" size={16} /> {event.dow}, {event.date.month} {event.date.day} · {event.time}</div>
              <div className="row"><Icon name="pin" size={16} /> {event.venue}</div>

              <div style={{ background: '#fff', padding: 18, borderRadius: 8, marginTop: 22 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
                  <div>
                    <div style={{ fontFamily: 'var(--f-display)', fontSize: 18, fontWeight: 600 }}>{tier.name}</div>
                    <div style={{ fontSize: 13, color: 'var(--ink-500)' }}>{tier.price} each</div>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                    <button onClick={() => setQty(Math.max(1, qty - 1))} style={{ width: 32, height: 32, borderRadius: 6, background: 'rgba(20,30,60,0.08)' }}>−</button>
                    <span style={{ minWidth: 24, textAlign: 'center', fontWeight: 700 }}>{qty}</span>
                    <button onClick={() => setQty(Math.min(8, qty + 1))} style={{ width: 32, height: 32, borderRadius: 6, background: 'rgba(20,30,60,0.08)' }}>+</button>
                  </div>
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', borderTop: '1px solid rgba(20,30,60,0.1)', paddingTop: 14, fontSize: 14 }}>
                  <span>Subtotal</span><span>${total}</span>
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 14, marginTop: 6 }}>
                  <span>Fees</span><span>${Math.round(total * 0.08)}</span>
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', borderTop: '1px solid rgba(20,30,60,0.1)', marginTop: 12, paddingTop: 12, fontFamily: 'var(--f-display)', fontSize: 22, fontWeight: 600 }}>
                  <span>Total</span><span>${total + Math.round(total * 0.08)}</span>
                </div>
              </div>

              <div className="modal-actions">
                <button className="btn btn-primary" onClick={() => setStep('confirm')}>Checkout <Icon name="chevronRight" size={14} stroke={2.4} /></button>
                <button className="btn btn-ghost" style={{ color: 'var(--ink-700)', borderColor: 'rgba(20,30,60,0.18)' }} onClick={() => setStep('select')}>Back</button>
              </div>
            </div>
          )}

          {step === 'confirm' && tier && (
            <div style={{ textAlign: 'center', padding: '20px 0' }}>
              <div style={{ width: 64, height: 64, borderRadius: 999, background: 'var(--gold-500)', color: 'var(--navy-900)', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 20px' }}>
                <Icon name="check" size={32} stroke={3} />
              </div>
              <h3 style={{ textAlign: 'center' }}>You're In!</h3>
              <p style={{ textAlign: 'center', color: 'var(--ink-700)' }}>
                We'll send your tickets to your email. See you on <strong>{event.dow}, {event.date.month} {event.date.day}</strong>.
              </p>
              <div className="modal-actions" style={{ justifyContent: 'center' }}>
                <button className="btn btn-primary" onClick={onClose}>Done</button>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

/* ===== Tweaks panel ===== */
const PALETTES = [
  // [bg, bg-alt, cream, accent, name]
  { name: 'Theater Gold (default)', vars: { '--bg': '#0B1635', '--bg-alt': '#101E45', '--bg-cream': '#F5EEDC', '--accent': '#D4A642', '--accent-bright': '#E0B656', '--navy-900': '#08112C' }, swatch: ['#0B1635', '#F5EEDC', '#D4A642'] },
  { name: 'Velvet & Brass',         vars: { '--bg': '#2A0E1D', '--bg-alt': '#3A1428', '--bg-cream': '#F4EBD8', '--accent': '#C9A24F', '--accent-bright': '#E0B86E', '--navy-900': '#1B0813' }, swatch: ['#2A0E1D', '#F4EBD8', '#C9A24F'] },
  { name: 'Midnight Plum',          vars: { '--bg': '#1E1238', '--bg-alt': '#2A1A4A', '--bg-cream': '#F3ECDB', '--accent': '#E5BB6B', '--accent-bright': '#F1CE85', '--navy-900': '#140929' }, swatch: ['#1E1238', '#F3ECDB', '#E5BB6B'] },
  { name: 'Spotlight Charcoal',     vars: { '--bg': '#121417', '--bg-alt': '#1B1E22', '--bg-cream': '#F0EBE0', '--accent': '#D4A642', '--accent-bright': '#EAC15A', '--navy-900': '#0A0B0D' }, swatch: ['#121417', '#F0EBE0', '#D4A642'] },
];

const TYPE_PAIRS = [
  { name: 'Playfair + Manrope',          display: 'Playfair Display',    sans: 'Manrope',        script: 'Pinyon Script' },
  { name: 'Cormorant + Inter',           display: 'Cormorant Garamond',  sans: 'Inter',          script: 'Allura' },
  { name: 'DM Serif + DM Sans',          display: 'DM Serif Display',    sans: 'DM Sans',        script: 'Great Vibes' },
  { name: 'Fraunces + Manrope',          display: 'Fraunces',            sans: 'Manrope',        script: 'Pinyon Script' },
  { name: 'Bodoni + Jost',               display: 'Bodoni Moda',         sans: 'Jost',           script: 'Tangerine' },
  { name: 'Libre Baskerville + Work Sans', display: 'Libre Baskerville', sans: 'Work Sans',      script: 'Dancing Script' },
  { name: 'EB Garamond + Mulish',        display: 'EB Garamond',         sans: 'Mulish',         script: 'Parisienne' },
  { name: 'Prata + Outfit',              display: 'Prata',               sans: 'Outfit',         script: 'Sacramento' },
  { name: 'Marcellus + Nunito Sans',     display: 'Marcellus',           sans: 'Nunito Sans',    script: 'Italianno' },
  { name: 'Lora + Karla',                display: 'Lora',                sans: 'Karla',          script: 'Petit Formal Script' },
  { name: 'Spectral + Figtree',          display: 'Spectral',            sans: 'Figtree',        script: 'Yellowtail' },
  { name: 'Cardo + Source Sans',         display: 'Cardo',               sans: 'Source Sans 3',  script: 'Alex Brush' },
  { name: 'Bricolage + Hanken',          display: 'Bricolage Grotesque', sans: 'Hanken Grotesk', script: 'Pinyon Script' },
  { name: 'Domine + Albert Sans',        display: 'Domine',              sans: 'Albert Sans',    script: 'Mr Dafoe' },
  { name: 'Newsreader + Poppins',        display: 'Newsreader',          sans: 'Poppins',        script: 'Great Vibes' },
  { name: 'Italiana + Jost',             display: 'Italiana',            sans: 'Jost',           script: 'Allura' },
];

function applyPalette(p) {
  const root = document.documentElement;
  Object.entries(p.vars).forEach(([k, v]) => root.style.setProperty(k, v));
}
function applyTypes(t) {
  const root = document.documentElement;
  root.style.setProperty('--f-display', `'${t.display}', serif`);
  root.style.setProperty('--f-sans', `'${t.sans}', system-ui, sans-serif`);
  root.style.setProperty('--f-script', `'${t.script}', cursive`);
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "paletteIdx": 0,
  "typeIdx": 0,
  "cardLayout": "classic"
}/*EDITMODE-END*/;

function WandTweaks({ onCardLayoutChange }) {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  useEffectApp(() => { applyPalette(PALETTES[t.paletteIdx]); }, [t.paletteIdx]);
  useEffectApp(() => { applyTypes(TYPE_PAIRS[t.typeIdx]); }, [t.typeIdx]);
  useEffectApp(() => { onCardLayoutChange && onCardLayoutChange(t.cardLayout); }, [t.cardLayout]);

  return (
    <TweaksPanel>
      <TweakSection label="Color Palette" />
      <div style={{ padding: '4px 12px 12px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
        {PALETTES.map((p, i) => {
          const sel = i === t.paletteIdx;
          return (
            <button
              key={i}
              onClick={() => setTweak('paletteIdx', i)}
              style={{
                background: sel ? 'rgba(0,0,0,0.06)' : 'transparent',
                border: sel ? '1.5px solid #29261b' : '1px solid rgba(0,0,0,0.12)',
                borderRadius: 8,
                padding: 8,
                textAlign: 'left',
                cursor: 'pointer',
                color: 'inherit',
                font: 'inherit',
              }}
            >
              <div style={{ display: 'flex', gap: 3, marginBottom: 6 }}>
                {p.swatch.map((c, j) => (
                  <div key={j} style={{ width: 22, height: 22, borderRadius: 3, background: c, border: '1px solid rgba(0,0,0,0.06)' }} />
                ))}
              </div>
              <div style={{ fontSize: 10.5, opacity: 0.85, lineHeight: 1.2 }}>{p.name}</div>
            </button>
          );
        })}
      </div>

      <TweakSection label="Typography" />
      <TweakSelect
        label="Type Pair"
        value={t.typeIdx}
        options={TYPE_PAIRS.map((tp, i) => ({ value: i, label: tp.name }))}
        onChange={(v) => setTweak('typeIdx', Number(v))}
      />

      <TweakSection label="Event Cards" />
      <TweakRadio
        label="Corner Shape"
        value={t.cardLayout}
        options={['sharp', 'classic', 'rounded']}
        onChange={(v) => setTweak('cardLayout', v)}
      />
    </TweaksPanel>
  );
}

/* ===== Root App ===== */
function App() {
  const [route] = useHashRoute();
  const [modalEvent, setModalEvent] = useStateApp(null);
  const [cardLayout, setCardLayout] = useStateApp('classic');

  // Merge Gigdini performers into the curated event positions.
  // First render uses the inline fallback (sync) so nothing flashes empty;
  // then we load the live roster (or snapshot) and refine.
  const [events, setEvents] = useStateApp(() =>
    window.GIGDINI.fillPositions(window.WAND_DATA.positions, window.GIGDINI.inlineRoster())
  );
  const [rosterSource, setRosterSource] = useStateApp('inline-fallback');

  useEffectApp(() => {
    let alive = true;
    window.GIGDINI.loadRoster().then((roster) => {
      if (!alive) return;
      setEvents(window.GIGDINI.fillPositions(window.WAND_DATA.positions, roster));
      setRosterSource(roster.source);
    });
    return () => { alive = false; };
  }, []);

  const openTickets = () => { if (events[0]) setModalEvent(events[0]); };

  let page;
  if (route === '/about')        page = <AboutPage />;
  else if (route === '/events')  page = <EventsPage events={events} onCardClick={setModalEvent} layout={cardLayout} />;
  else if (route === '/venues')  page = <VenuesPage />;
  else if (route === '/gallery') page = <GalleryPage />;
  else if (route === '/faq')     page = <FAQPage />;
  else if (route === '/contact') page = <ContactPage />;
  else if (route === '/privacy') page = <PrivacyPage />;
  else                           page = <HomePage events={events} onCardClick={setModalEvent} layout={cardLayout} />;

  return (
    <>
      <Nav route={route} onTickets={openTickets} />
      {page}
      <Footer />
      {modalEvent && <TicketModal event={modalEvent} onClose={() => setModalEvent(null)} />}
      <WandTweaks onCardLayoutChange={setCardLayout} />
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
