function emptySub() {
  return {
    id: 'sub-' + Date.now(), num: '0X', title: '', category: 'imc', venue: '', photo: null,
    dateIso: '', startTime: '', endTime: '',
    coaches: [{ name: '', bio: '', photo: null }],
    capacity: 40, minCapacity: 0,
    refundPolicy: '7day',
    pricingTiers: [{ name: 'Standard', price: 0, features: [], highlighted: true }],
    program: [],
    certificateTemplate: null,
  };
}
function defaultCertTemplate() {
  return { title: 'Certificate of Completion', body: 'has successfully completed', accreditorLabel: 'Accreditor', accentColor: '#F49B52', bgFrom: '#0E2247', bgTo: '#173463' };
}
function subLegacyFallback(s) {
  return {
    coaches: s.coaches && s.coaches.length ? s.coaches : [{ name: '', bio: '', photo: null }],
    capacity: s.capacity != null ? s.capacity : 40,
    minCapacity: s.minCapacity != null ? s.minCapacity : 0,
    refundPolicy: s.refundPolicy && window.UdUI.REFUND_OPTIONS.some((o) => o.value === s.refundPolicy) ? s.refundPolicy : '7day',
    pricingTiers: s.pricingTiers && s.pricingTiers.length ? s.pricingTiers : [{ name: 'Standard', price: 0, features: [], highlighted: true }],
    program: s.program || [],
  };
}

function parseTimeRangeOverlap(aStart, aEnd, bStart, bEnd) {
  if (!aStart || !bStart) return true;
  const toMin = (t) => {
    const m = /(\d{1,2}):(\d{2})\s*([AP]M)?/i.exec(t || '');
    if (!m) return null;
    let h = parseInt(m[1], 10); const min = parseInt(m[2], 10); const ap = (m[3] || '').toUpperCase();
    if (ap === 'PM' && h < 12) h += 12; if (ap === 'AM' && h === 12) h = 0;
    return h * 60 + min;
  };
  const as = toMin(aStart), ae = toMin(aEnd) || (as != null ? as + 60 : null), bs = toMin(bStart), be = toMin(bEnd) || (bs != null ? bs + 60 : null);
  if (as == null || bs == null) return true;
  return as < be && bs < ae;
}
function findScheduleCollision(subEvents, candidate, excludeId) {
  if (!candidate.dateIso) return null;
  for (const s of subEvents) {
    if (s.id === excludeId) continue;
    if (s.dateIso !== candidate.dateIso) continue;
    if (parseTimeRangeOverlap(candidate.startTime, candidate.endTime, s.startTime, s.endTime)) return s;
  }
  return null;
}

function SubEventFormDialog({ open, initial, mainVenue, allSubEvents, otherMainSubDates, onClose, onSave }) {
  const { Button, Input } = window.TheUpperDeckDesignSystem_4d3294;
  const { CustomDatePicker, WideUploadBox, CoachesEditor, PricingTiersEditor, ProgramEditor, FormPanel, CategoryCombo, REFUND_OPTIONS, CustomSelect } = window.UdUI;
  const [f, setF] = React.useState(initial ? { ...initial, ...subLegacyFallback(initial) } : emptySub());
  const [error, setError] = React.useState('');
  const [saving, setSaving] = React.useState(false);
  React.useEffect(() => { if (open) { setF(initial ? { ...initial, ...subLegacyFallback(initial) } : emptySub()); setError(''); } }, [open, initial]);
  if (!open) return null;
  function set(k, v) { setF((s) => ({ ...s, [k]: v })); }

  async function submit() {
    const collision = findScheduleCollision(allSubEvents || [], f, f.id);
    if (collision) { setError('This overlaps with "' + collision.title + '" (' + collision.date + ', ' + collision.time + '). Adjust the date or time.'); return; }
    if (f.dateIso) {
      const dayHit = (otherMainSubDates || []).find((s) => f.dateIso >= s.starts_at.slice(0, 10) && f.dateIso <= s.ends_at.slice(0, 10));
      if (dayHit) { setError('Another main event ("' + dayHit.title + '") already runs on this day. Pick a different date.'); return; }
    }
    setError('');
    setSaving(true);
    try { await onSave(f); } catch (e) { setError(e.message || 'Could not save sub-event.'); }
    setSaving(false);
  }

  return ReactDOM.createPortal(
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(8,21,27,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000, padding: 24 }}>
      <div className="ud-modal" onClick={(e) => e.stopPropagation()} style={{ width: 'min(820px, 94vw)', maxHeight: '90vh', overflowY: 'auto', position: 'relative', background: 'white', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', animation: 'udScaleIn 200ms var(--ease-standard) both' }}>
        <button onClick={onClose} style={{ position: 'absolute', top: 20, right: 24, width: 32, height: 32, borderRadius: '50%', border: 'none', background: 'var(--bg-sunken)', color: 'var(--text-primary)', fontSize: 18, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>×</button>
        <div style={{ padding: '28px 32px 20px', borderBottom: '1px solid var(--border-default)' }}>
          <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 'var(--text-2xl)', margin: '0 0 4px' }}>{initial ? 'Update sub-event' : 'New sub-event'}</h2>
          <div style={{ fontSize: 'var(--text-xs)', color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-wide)' }}>Sub-event details</div>
        </div>

        <div style={{ padding: '24px 32px 0' }}>
          <WideUploadBox label="Cover image" hint="Recommended 1280×720 · click to upload" value={f.photo} onChange={(v) => set('photo', v)} />
        </div>

        <div style={{ padding: '24px 32px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 28 }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <FormPanel title="Primary details">
              <div>
                <div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, marginBottom: 6 }}>Category</div>
                <CategoryCombo value={f.category} onChange={(v) => set('category', v)} options={window.CATEGORY_OPTIONS} onAddOption={window.registerCategory} width="100%" />
              </div>
              <Input label="Title" value={f.title} onChange={(v) => set('title', v)} />
              <div>
                <div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, marginBottom: 6 }}>Description</div>
                <textarea value={f.description || ''} onChange={(e) => set('description', e.target.value)} rows={3} style={{ width: '100%', boxSizing: 'border-box', padding: 10, borderRadius: 'var(--radius-md)', border: '1px solid var(--border-default)', fontFamily: 'var(--font-body)', fontSize: 'var(--text-sm)', resize: 'vertical' }} />
              </div>
              <Input label="Venue (blank = main venue)" value={f.venue} onChange={(v) => set('venue', v)} placeholder={mainVenue} />
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                <Input label="Minimum capacity" value={String(f.minCapacity)} type="number" onChange={(v) => set('minCapacity', Number(v) || 0)} />
                <Input label="Maximum capacity" type="number" value={String(f.capacity)} onChange={(v) => set('capacity', Number(v) || 0)} />
              </div>
            </FormPanel>
            <FormPanel title="Secondary details">
              <div>
                <div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, marginBottom: 6 }}>Refund policy</div>
                <CustomSelect value={f.refundPolicy} onChange={(v) => set('refundPolicy', v)} options={REFUND_OPTIONS} width="100%" />
              </div>
              <div>
                <div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, marginBottom: 6 }}>Date</div>
                <CustomDatePicker value={f.dateIso} onChange={(v) => set('dateIso', v)} placeholder="Pick date" />
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                <Input label="Start time" placeholder="e.g. 9:00 AM" value={f.startTime} onChange={(v) => set('startTime', v)} />
                <Input label="End time" placeholder="e.g. 5:00 PM" value={f.endTime} onChange={(v) => set('endTime', v)} />
              </div>
            </FormPanel>
            <FormPanel title="Program / agenda">
              <ProgramEditor items={f.program || []} onChange={(v) => set('program', v)} />
            </FormPanel>
          </div>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            <FormPanel title="Coaches / accreditors">
              <CoachesEditor coaches={f.coaches} onChange={(v) => set('coaches', v)} />
            </FormPanel>
            <FormPanel title="Pricing tiers (₱)">
              <PricingTiersEditor tiers={f.pricingTiers} onChange={(v) => set('pricingTiers', v)} />
            </FormPanel>
          </div>
        </div>

        {error && <div style={{ margin: '0 32px 20px', padding: '10px 14px', borderRadius: 'var(--radius-md)', background: 'var(--status-error-bg)', color: 'var(--status-error)', fontSize: 'var(--text-sm)' }}>{error}</div>}
        <div style={{ padding: '16px 32px 28px', display: 'flex', justifyContent: 'flex-end', gap: 12, borderTop: '1px solid var(--border-default)' }}>
          <Button variant="secondary" onClick={onClose}>Cancel</Button>
          <Button onClick={submit} disabled={saving}>{saving ? 'Saving…' : (initial ? 'Update sub-event' : 'Save sub-event')}</Button>
        </div>
      </div>
    </div>, document.body
  );
}

function CertificatePreviewDialog({ open, sub, event, onClose }) {
  if (!open || !sub) return null;
  const t = { ...defaultCertTemplate(), ...(sub.certificateTemplate || {}) };
  const coach = (sub.coaches || []).map((c) => c.name).filter(Boolean).join(' & ') || 'FTI Global';
  return ReactDOM.createPortal(
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(8,21,27,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000, padding: 24 }}>
      <div className="ud-modal" onClick={(e) => e.stopPropagation()} style={{ width: 'min(640px, 94vw)', position: 'relative', background: 'white', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', padding: 28, animation: 'udScaleIn 200ms var(--ease-standard) both' }}>
        <button onClick={onClose} style={{ position: 'absolute', top: 16, right: 16, width: 32, height: 32, borderRadius: '50%', border: 'none', background: 'var(--bg-sunken)', color: 'var(--text-primary)', fontSize: 18, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 2 }}>×</button>
        <div style={{ fontSize: 'var(--text-xs)', color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-wide)', marginBottom: 14 }}>Certificate preview</div>
        <div style={{ background: t.bgFrom, borderRadius: 8, padding: 6, backgroundImage: 'linear-gradient(135deg, ' + t.bgFrom + ' 0%, ' + t.bgTo + ' 100%)' }}>
          <div style={{ border: '1.5px solid ' + t.accentColor, borderRadius: 6, padding: '38px 32px', textAlign: 'center', position: 'relative' }}>
            <div style={{ fontSize: 'var(--text-xs)', letterSpacing: 'var(--tracking-widest)', color: t.accentColor, textTransform: 'uppercase', fontWeight: 700 }}>{t.title}</div>
            <div style={{ width: 60, height: 2, background: t.accentColor, margin: '14px auto' }} />
            <div style={{ fontFamily: 'var(--font-display)', fontSize: 'var(--text-3xl)', fontWeight: 700, margin: '6px 0 4px', color: 'white' }}>[Attendee name]</div>
            <div style={{ color: 'rgba(255,255,255,0.65)', margin: '10px 0' }}>{t.body}</div>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'var(--text-xl)', color: 'white' }}>{sub.title}</div>
            <div style={{ color: 'rgba(255,255,255,0.5)', fontSize: 'var(--text-sm)', margin: '4px 0 26px' }}>part of {event.title} · {sub.date}</div>
            <div style={{ display: 'flex', justifyContent: 'center', gap: 40 }}>
              <div>
                <div style={{ borderTop: '1px solid rgba(255,255,255,0.35)', paddingTop: 6, fontSize: 'var(--text-sm)', fontWeight: 600, color: 'white' }}>{coach}</div>
                <div style={{ fontSize: 'var(--text-xs)', color: t.accentColor, textTransform: 'uppercase', letterSpacing: 'var(--tracking-wide)' }}>{t.accreditorLabel}</div>
              </div>
            </div>
            <div style={{ fontSize: 'var(--text-xs)', fontWeight: 700, letterSpacing: 'var(--tracking-wide)', color: 'rgba(255,255,255,0.35)', marginTop: 20 }}>THE UPPER DECK</div>
          </div>
        </div>
        <div style={{ fontSize: 'var(--text-xs)', color: 'var(--text-muted)', marginTop: 14 }}>Actual certificates are issued per checked-in, paid attendee from the Certificates tab, with the attendee's real name and a scannable verification QR.</div>
      </div>
    </div>, document.body
  );
}

function CertificateTemplateEditorDialog({ open, sub, event, onClose, onSave, onUploadTemplate }) {
  const { Button, Input } = window.TheUpperDeckDesignSystem_4d3294;
  const [t, setT] = React.useState(defaultCertTemplate());
  const [saving, setSaving] = React.useState(false);
  const [uploading, setUploading] = React.useState(false);
  React.useEffect(() => { if (open && sub) setT({ ...defaultCertTemplate(), ...(sub.certificateTemplate || {}) }); }, [open, sub]);
  if (!open || !sub) return null;
  function set(k, v) { setT((s) => ({ ...s, [k]: v })); }
  const coach = (sub.coaches || []).map((c) => c.name).filter(Boolean).join(' & ') || 'FTI Global';
  async function submit() { setSaving(true); await onSave(t); setSaving(false); }
  async function handleFile(e) {
    const file = e.target.files[0];
    if (!file) return;
    setUploading(true);
    const reader = new FileReader();
    reader.onload = async () => { await onUploadTemplate(reader.result, file.name); setUploading(false); };
    reader.readAsDataURL(file);
  }
  return ReactDOM.createPortal(
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(8,21,27,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000, padding: 24 }}>
      <div className="ud-modal" onClick={(e) => e.stopPropagation()} style={{ width: 'min(880px, 94vw)', maxHeight: '90vh', overflowY: 'auto', position: 'relative', background: 'white', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', padding: 28, animation: 'udScaleIn 200ms var(--ease-standard) both' }}>
        <button onClick={onClose} style={{ position: 'absolute', top: 16, right: 16, width: 32, height: 32, borderRadius: '50%', border: 'none', background: 'var(--bg-sunken)', color: 'var(--text-primary)', fontSize: 18, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 2 }}>×</button>
        <h2 style={{ fontFamily: 'var(--font-display)', margin: '0 0 20px' }}>Design certificate</h2>
        <div style={{ border: '1px solid var(--border-default)', borderRadius: 'var(--radius-md)', padding: 14, marginBottom: 20, display: 'flex', alignItems: 'center', gap: 14 }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontWeight: 600, fontSize: 'var(--text-sm)' }}>Or upload your own template (PDF/DOCX)</div>
            <div style={{ fontSize: 'var(--text-xs)', color: 'var(--text-muted)' }}>{sub.certTemplateName ? 'Uploaded: ' + sub.certTemplateName : 'If uploaded, this file is used instead of the design below \u2014 printed manually per attendee.'}</div>
          </div>
          <label style={{ padding: '8px 14px', borderRadius: 'var(--radius-md)', border: '1px solid var(--border-default)', cursor: 'pointer', fontSize: 'var(--text-sm)', fontWeight: 600 }}>
            {uploading ? 'Uploading\u2026' : 'Upload file'}
            <input type="file" accept=".pdf,.doc,.docx" onChange={handleFile} style={{ display: 'none' }} disabled={uploading} />
          </label>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '260px 1fr', gap: 28 }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <Input label="Heading" value={t.title} onChange={(v) => set('title', v)} />
            <Input label="Body text" value={t.body} onChange={(v) => set('body', v)} />
            <Input label="Signature label" value={t.accreditorLabel} onChange={(v) => set('accreditorLabel', v)} />
            <div>
              <div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, marginBottom: 6 }}>Accent color</div>
              <input type="color" value={t.accentColor} onChange={(e) => set('accentColor', e.target.value)} style={{ width: 48, height: 32, border: '1px solid var(--border-default)', borderRadius: 'var(--radius-sm)', padding: 0, cursor: 'pointer' }} />
            </div>
            <div>
              <div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, marginBottom: 6 }}>Background gradient</div>
              <div style={{ display: 'flex', gap: 8 }}>
                <input type="color" value={t.bgFrom} onChange={(e) => set('bgFrom', e.target.value)} style={{ width: 48, height: 32, border: '1px solid var(--border-default)', borderRadius: 'var(--radius-sm)', padding: 0, cursor: 'pointer' }} />
                <input type="color" value={t.bgTo} onChange={(e) => set('bgTo', e.target.value)} style={{ width: 48, height: 32, border: '1px solid var(--border-default)', borderRadius: 'var(--radius-sm)', padding: 0, cursor: 'pointer' }} />
              </div>
            </div>
          </div>
          <div>
            <div style={{ background: t.bgFrom, borderRadius: 8, padding: 6, backgroundImage: 'linear-gradient(135deg, ' + t.bgFrom + ' 0%, ' + t.bgTo + ' 100%)' }}>
              <div style={{ border: '1.5px solid ' + t.accentColor, borderRadius: 6, padding: '38px 32px', textAlign: 'center', position: 'relative' }}>
                <div style={{ fontSize: 'var(--text-xs)', letterSpacing: 'var(--tracking-widest)', color: t.accentColor, textTransform: 'uppercase', fontWeight: 700 }}>{t.title}</div>
                <div style={{ width: 60, height: 2, background: t.accentColor, margin: '14px auto' }} />
                <div style={{ fontFamily: 'var(--font-display)', fontSize: 'var(--text-3xl)', fontWeight: 700, margin: '6px 0 4px', color: 'white' }}>[Attendee name]</div>
                <div style={{ color: 'rgba(255,255,255,0.65)', margin: '10px 0' }}>{t.body}</div>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'var(--text-xl)', color: 'white' }}>{sub.title}</div>
                <div style={{ color: 'rgba(255,255,255,0.5)', fontSize: 'var(--text-sm)', margin: '4px 0 26px' }}>part of {event.title} · {sub.date}</div>
                <div style={{ display: 'flex', justifyContent: 'center', gap: 40 }}>
                  <div>
                    <div style={{ borderTop: '1px solid rgba(255,255,255,0.35)', paddingTop: 6, fontSize: 'var(--text-sm)', fontWeight: 600, color: 'white' }}>{coach}</div>
                    <div style={{ fontSize: 'var(--text-xs)', color: t.accentColor, textTransform: 'uppercase', letterSpacing: 'var(--tracking-wide)' }}>{t.accreditorLabel}</div>
                  </div>
                </div>
                <div style={{ fontSize: 'var(--text-xs)', fontWeight: 700, letterSpacing: 'var(--tracking-wide)', color: 'rgba(255,255,255,0.35)', marginTop: 20 }}>THE UPPER DECK</div>
              </div>
            </div>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 12, marginTop: 24 }}>
          <Button onClick={submit} disabled={saving}>{saving ? 'Saving…' : 'Save template'}</Button>
          <Button variant="secondary" onClick={onClose}>Cancel</Button>
        </div>
      </div>
    </div>, document.body
  );
}

function CheckinQrDialog({ open, sub, event, onClose }) {
  const { Button } = window.TheUpperDeckDesignSystem_4d3294;
  const canvasRef = React.useRef(null);
  if (!open || !sub) return null;
  const url = window.location.origin + window.location.pathname.replace('admin-dashboard', 'event-site').replace(/[^/]*$/, '') + 'checkin.html?event=' + sub.id;
  const qrSrc = 'https://api.qrserver.com/v1/create-qr-code/?size=340x340&margin=0&color=0E2247&data=' + encodeURIComponent(url);

  async function drawPoster() {
    const W = 720, H = 900;
    const canvas = document.createElement('canvas');
    canvas.width = W; canvas.height = H;
    const ctx = canvas.getContext('2d');
    const grad = ctx.createLinearGradient(0, 0, W, H);
    grad.addColorStop(0, '#0E2247'); grad.addColorStop(1, '#173463');
    ctx.fillStyle = grad; ctx.fillRect(0, 0, W, H);
    ctx.textAlign = 'center';
    ctx.fillStyle = '#F49B52'; ctx.font = '700 22px sans-serif';
    ctx.fillText('FTI GLOBAL', W / 2, 90);
    ctx.fillStyle = 'rgba(255,255,255,0.55)'; ctx.font = '600 13px sans-serif';
    ctx.fillText('FUNCTIONAL TRAINING INSTITUTE', W / 2, 116);
    ctx.fillStyle = '#F49B52'; ctx.font = '700 18px sans-serif';
    ctx.fillText('SCAN TO CHECK IN', W / 2, 175);
    ctx.fillStyle = '#fff'; ctx.font = '700 34px sans-serif';
    wrapText(ctx, sub.title, W / 2, 225, 620, 40);
    ctx.fillStyle = 'rgba(255,255,255,0.6)'; ctx.font = '400 18px sans-serif';
    ctx.fillText((sub.date || '') + ' \u00b7 ' + (event.venue || ''), W / 2, 320);
    const qrImg = await loadImg(qrSrc);
    const qrBoxSize = 400, qrPad = 30, qrX = (W - qrBoxSize) / 2, qrY = 360;
    ctx.fillStyle = '#fff'; ctx.fillRect(qrX, qrY, qrBoxSize, qrBoxSize);
    ctx.drawImage(qrImg, qrX + qrPad, qrY + qrPad, qrBoxSize - qrPad * 2, qrBoxSize - qrPad * 2);
    ctx.fillStyle = 'rgba(255,255,255,0.75)'; ctx.font = '400 17px sans-serif';
    ctx.fillText('Scan this to mark yourself as attended', W / 2, qrY + qrBoxSize + 50);
    ctx.fillText('for this event.', W / 2, qrY + qrBoxSize + 76);
    ctx.fillStyle = 'rgba(255,255,255,0.35)'; ctx.font = '700 13px sans-serif';
    ctx.fillText('THE UPPER DECK', W / 2, H - 40);
    return canvas;
  }
  function loadImg(src) { return new Promise((res) => { const i = new Image(); i.crossOrigin = 'anonymous'; i.onload = () => res(i); i.src = src; }); }
  function wrapText(ctx, text, x, y, maxWidth, lineHeight) {
    const words = text.split(' '); let line = ''; const lines = [];
    for (const w of words) { const test = line + w + ' '; if (ctx.measureText(test).width > maxWidth && line) { lines.push(line); line = w + ' '; } else line = test; }
    lines.push(line);
    const startY = y - (lines.length - 1) * lineHeight / 2;
    lines.forEach((l, i) => ctx.fillText(l.trim(), x, startY + i * lineHeight));
  }
  async function downloadImage() {
    const canvas = await drawPoster();
    const a = document.createElement('a'); a.href = canvas.toDataURL('image/png'); a.download = sub.title + ' - check-in poster.png'; a.click();
  }
  async function downloadPdf() {
    const canvas = await drawPoster();
    const w = window.open('');
    w.document.write('<img src="' + canvas.toDataURL('image/png') + '" style="width:100%" onload="window.print()">');
  }

  return ReactDOM.createPortal(
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(8,21,27,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000, padding: 24 }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: 'min(400px, 92vw)', position: 'relative', animation: 'udScaleIn 200ms var(--ease-standard) both' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
          <div style={{ fontSize: 'var(--text-xs)', color: 'rgba(255,255,255,0.7)', textTransform: 'uppercase', letterSpacing: 'var(--tracking-wide)' }}>Check-in poster</div>
          <button onClick={onClose} style={{ width: 28, height: 28, borderRadius: '50%', border: 'none', background: 'rgba(255,255,255,0.15)', color: 'white', cursor: 'pointer' }}>×</button>
        </div>
        <div style={{ background: 'linear-gradient(135deg, #0E2247, #173463)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', padding: '32px 28px', textAlign: 'center' }}>
          <div style={{ color: 'var(--brand-primary)', fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'var(--text-lg)', letterSpacing: '0.02em' }}>FTI GLOBAL</div>
          <div style={{ color: 'rgba(255,255,255,0.5)', fontSize: 10, letterSpacing: '0.1em', marginBottom: 20 }}>FUNCTIONAL TRAINING INSTITUTE</div>
          <div style={{ color: 'var(--brand-primary)', fontWeight: 700, fontSize: 'var(--text-sm)', letterSpacing: '0.06em', marginBottom: 10 }}>SCAN TO CHECK IN</div>
          <div style={{ color: 'white', fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'var(--text-xl)', marginBottom: 8 }}>{sub.title}</div>
          <div style={{ color: 'rgba(255,255,255,0.6)', fontSize: 'var(--text-sm)', marginBottom: 22 }}>{sub.date} · {event.venue}</div>
          <div style={{ background: 'white', borderRadius: 'var(--radius-md)', padding: 16, display: 'inline-block' }}>
            <img src={qrSrc} alt="Self check-in QR code" style={{ width: 200, height: 200, display: 'block' }} />
          </div>
          <div style={{ color: 'rgba(255,255,255,0.75)', fontSize: 'var(--text-sm)', marginTop: 20 }}>Scan this to mark yourself as attended for this event.</div>
          <div style={{ color: 'rgba(255,255,255,0.35)', fontWeight: 700, fontSize: 'var(--text-xs)', letterSpacing: '0.06em', marginTop: 20 }}>THE UPPER DECK</div>
        </div>
        <div style={{ display: 'flex', gap: 10, marginTop: 16 }}>
          <button onClick={downloadImage} style={{ flex: 1, padding: '12px 0', borderRadius: 'var(--radius-md)', border: '1px solid var(--brand-primary)', background: 'white', color: 'var(--brand-primary)', fontWeight: 600, cursor: 'pointer' }}>Download image</button>
          <button onClick={downloadPdf} style={{ flex: 1, padding: '12px 0', borderRadius: 'var(--radius-md)', border: 'none', background: 'var(--brand-primary)', color: 'white', fontWeight: 600, cursor: 'pointer' }}>Download PDF</button>
        </div>
      </div>
    </div>, document.body
  );
}

function EventDetailScreen({ eventId, onBack, adminId }) {
  const { Badge, Button, Tabs, ScheduleRow, ProgressBar, Tag } = window.TheUpperDeckDesignSystem_4d3294;
  const [event, setEvent] = React.useState(null);
  const [otherMainSubDates, setOtherMainSubDates] = React.useState([]);
  const [tab, setTab] = React.useState('overview');
  const [subDialog, setSubDialog] = React.useState(null);
  const [checkInSub, setCheckInSub] = React.useState(null);
  const [certSub, setCertSub] = React.useState(null);
  const [certDesignSub, setCertDesignSub] = React.useState(null);
  const [checkinQrSub, setCheckinQrSub] = React.useState(null);
  const [orders, setOrders] = React.useState([]);
  const [eventDialog, setEventDialog] = React.useState(false);

  function reload() {
    return Promise.all([window.fetchMainEventsLive(), window.fetchOrdersLive(), window.fetchAllSubEventDatesLive()]).then(([events, allOrders, allSubs]) => {
      const ev = events.find((e) => e.id === eventId);
      setEvent(ev);
      setOrders(allOrders.filter((o) => o.mainId === eventId));
      setOtherMainSubDates(allSubs.filter((s) => s.main_event_id !== eventId));
    });
  }
  React.useEffect(() => { reload(); setTab('overview'); setSubDialog(null); setCheckInSub(null); }, [eventId]);

  if (!event) return <div style={{ padding: 32, color: 'var(--text-muted)' }}>Loading…</div>;

  async function saveSub(f) {
    await window.saveSubEventLive(event.id, f);
    await reload();
    setSubDialog(null);
  }
  async function deleteSub(id) {
    if (!window.confirm('Delete this sub-event?')) return;
    await window.deleteSubEventLive(id);
    reload();
  }
  async function saveCertTemplate(subId, tmpl) {
    await window.saveSubEventLive(event.id, { ...event.subEvents.find((s) => s.id === subId), certificateTemplate: tmpl });
    await reload();
    setCertDesignSub(null);
  }
  async function uploadCertTemplate(dataUrl, fileName) {
    await window.saveCertTemplateFileLive(certDesignSub.id, dataUrl, fileName);
    reload();
  }
  async function saveEvent(f) {
    await window.saveMainEventLive({ ...event, ...f }, adminId);
    await reload();
    setEventDialog(false);
  }
  async function deleteEvent() {
    if (!window.confirm('Delete this event and all its sub-events? This cannot be undone.')) return;
    await window.deleteMainEventLive(event.id);
    onBack();
  }

  const totalCapacity = event.subEvents.reduce((s, x) => s + (x.capacity || 0), 0);
  const totalBooked = orders.filter((o) => o.status === 'paid').length;
  const totalRevenue = orders.filter((o) => o.status === 'paid').reduce((s, o) => s + o.amount, 0);
  const tabs = [{ value: 'overview', label: 'Overview' }, { value: 'subevents', label: 'Sub-events (' + event.subEvents.length + ')' }, { value: 'schedule', label: 'Schedule' }, { value: 'pricing', label: 'Pricing' }];

  return (
    <div>
      <button onClick={onBack} style={{ border: 'none', background: 'none', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 'var(--text-sm)', padding: 0, marginBottom: 16 }}>← Back to events</button>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 20, gap: 12, flexWrap: 'wrap' }}>
        <div>
          <Badge tone={event.status === 'published' ? 'success' : 'warning'}>{event.status}</Badge>
          <h1 style={{ fontFamily: 'var(--font-display)', fontSize: 'var(--text-3xl)', margin: '10px 0 6px' }}>{event.title}</h1>
          <div style={{ color: 'var(--text-secondary)' }}>{event.dateRange || 'No sub-events scheduled'} · {event.venue}</div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <Button variant="secondary" onClick={() => setEventDialog(true)}>Edit event</Button>
          <window.UdUI.Btn variant="danger" onClick={deleteEvent}>Delete event</window.UdUI.Btn>
        </div>
      </div>

      <div style={{ marginBottom: 24 }}><Tabs tabs={tabs} active={tab} onChange={setTab} /></div>

      {tab === 'overview' && (
        <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0,2fr) minmax(0,1fr)', gap: 24 }}>
          <div>
            <p style={{ color: 'var(--text-secondary)', lineHeight: 'var(--leading-relaxed)' }}>{event.description}</p>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, marginTop: 24, marginBottom: 10 }}>Analytics</div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: 12, marginBottom: 24 }}>
              <div style={{ background: 'var(--navy-900)', color: 'white', borderRadius: 'var(--radius-md)', padding: 14 }}>
                <div style={{ fontSize: 'var(--text-xs)', color: 'rgba(255,255,255,0.7)', textTransform: 'uppercase' }}>Revenue</div>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'var(--text-xl)' }}>{window.fmtUSD(totalRevenue)}</div>
              </div>
              <div style={{ background: 'var(--teal-600)', color: 'white', borderRadius: 'var(--radius-md)', padding: 14 }}>
                <div style={{ fontSize: 'var(--text-xs)', color: 'rgba(255,255,255,0.75)', textTransform: 'uppercase' }}>Bookings</div>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'var(--text-xl)' }}>{totalBooked}</div>
              </div>
              <div style={{ background: 'var(--violet-600)', color: 'white', borderRadius: 'var(--radius-md)', padding: 14 }}>
                <div style={{ fontSize: 'var(--text-xs)', color: 'rgba(255,255,255,0.75)', textTransform: 'uppercase' }}>Sub-events</div>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'var(--text-xl)' }}>{event.subEvents.length}</div>
              </div>
            </div>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, marginBottom: 10 }}>Event details</div>
            <div style={{ background: 'white', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-sm)', padding: 20, display: 'flex', flexDirection: 'column', gap: 14 }}>
              <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap' }}>
                <img src={event.photo || 'https://placehold.co/160x90?text=Cover'} style={{ width: 160, height: 90, objectFit: 'cover', borderRadius: 'var(--radius-md)', border: '1px solid var(--border-default)' }} />
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 'var(--text-sm)' }}>
                  <div><span style={{ color: 'var(--text-muted)' }}>Venue: </span>{event.venue}</div>
                  <div><span style={{ color: 'var(--text-muted)' }}>Scheduled launch: </span>{event.scheduledLaunch && event.scheduledLaunch.enabled ? event.scheduledLaunch.datetime : 'Not scheduled'}</div>
                </div>
              </div>
              <div style={{ borderTop: '1px solid var(--border-default)', paddingTop: 14 }}>
                <div style={{ fontWeight: 600, marginBottom: 8, fontSize: 'var(--text-sm)' }}>FAQs ({(event.faqs || []).filter((f) => f.q).length})</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                  {(event.faqs || []).filter((f) => f.q).map((f, i) => (
                    <div key={i} style={{ fontSize: 'var(--text-sm)' }}><div style={{ fontWeight: 600 }}>{f.q}</div><div style={{ color: 'var(--text-secondary)' }}>{f.a}</div></div>
                  ))}
                  {!(event.faqs || []).some((f) => f.q) && <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>No FAQs added yet.</div>}
                </div>
              </div>
            </div>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <div style={{ background: 'white', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-sm)', padding: 20 }}>
              <div style={{ fontWeight: 700, marginBottom: 12 }}>Capacity</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                {event.subEvents.map((s) => {
                  const booked = orders.filter((o) => o.eventId === s.id && o.status === 'paid').length;
                  return <ProgressBar key={s.id} value={booked} max={Math.max(s.capacity || 0, 1)} label={s.title + ' · ' + booked + ' / ' + (s.capacity || 0) + ' booked'} />;
                })}
              </div>
              {event.subEvents.length > 0 && <div style={{ borderTop: '1px solid var(--border-default)', marginTop: 12, paddingTop: 12 }}>
                <ProgressBar value={totalBooked} max={Math.max(totalCapacity, 1)} label={'Total · ' + totalBooked + ' / ' + totalCapacity + ' booked'} />
              </div>}
              {event.subEvents.length === 0 && <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>No sub-events yet.</div>}
            </div>
            <div style={{ background: 'white', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-sm)', padding: 20 }}>
              <div style={{ fontWeight: 700, marginBottom: 12 }}>Attendance</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                {event.subEvents.map((s) => {
                  const paid = orders.filter((o) => o.eventId === s.id && o.status === 'paid');
                  const checkedIn = paid.filter((o) => o.checkedIn).length;
                  return <ProgressBar key={s.id} value={checkedIn} max={Math.max(paid.length, 1)} label={s.title + ' · ' + checkedIn + ' / ' + paid.length + ' checked in'} />;
                })}
              </div>
              {event.subEvents.length === 0 && <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>No sub-events yet.</div>}
            </div>
          </div>
        </div>
      )}

      {tab === 'subevents' && (
        <div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginBottom: 16 }}>
            {event.subEvents.map((s) => {
              const paid = orders.filter((o) => o.eventId === s.id && o.status === 'paid');
              const checkedInCount = paid.filter((o) => o.checkedIn).length;
              const rate = paid.length ? Math.round(checkedInCount / paid.length * 100) : 0;
              return (
                <div key={s.id} style={{ background: 'white', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-sm)', padding: '16px 18px', display: 'flex', flexDirection: 'column', gap: 12 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
                    <span style={{ fontFamily: 'var(--font-mono)', color: window.catColorMap[s.category] || 'var(--brand-primary)', fontSize: 'var(--text-sm)' }}>{s.num}</span>
                    <div style={{ flex: 1, minWidth: 160 }}>
                      <div style={{ fontWeight: 600 }}>{s.title}</div>
                      <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>{s.date} · {s.startTime}{'\u2013'}{s.endTime} · {(s.coaches || []).map((c) => c.name).filter(Boolean).join(', ')}</div>
                    </div>
                    <div style={{ textAlign: 'right', minWidth: 108 }}>
                      <div style={{ fontSize: 'var(--text-sm)', fontWeight: 600 }}>{checkedInCount}/{paid.length} attended</div>
                      <div style={{ fontSize: 'var(--text-xs)', fontWeight: 600, color: paid.length === 0 ? 'var(--text-muted)' : (rate >= 80 ? 'var(--status-success)' : 'var(--status-error)') }}>{rate}% check-in rate</div>
                    </div>
                    <div style={{ fontWeight: 600, minWidth: 60, textAlign: 'right' }}>{window.fmtUSD((s.pricingTiers[0] && s.pricingTiers[0].price) || 0)}</div>
                  </div>
                  {(s.program || []).length > 0 && (
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 'var(--text-xs)', color: 'var(--text-muted)' }}>
                      {s.program.map((p, i) => <div key={i}><strong style={{ color: 'var(--text-secondary)' }}>{p.time}</strong> {p.description}</div>)}
                    </div>
                  )}
                  <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', borderTop: '1px solid var(--border-default)', paddingTop: 12, flexWrap: 'wrap' }}>
                    <window.UdUI.Btn size="sm" variant="secondary" onClick={() => setCheckinQrSub(s)}>Check-in QR</window.UdUI.Btn>
                    <window.UdUI.Btn size="sm" variant="secondary" onClick={() => setCertSub(s)}>Certificate</window.UdUI.Btn>
                    <window.UdUI.Btn size="sm" variant="secondary" onClick={() => setCertDesignSub(s)}>Design certificate</window.UdUI.Btn>
                    <window.UdUI.Btn size="sm" variant="secondary" onClick={() => setSubDialog({ editing: s })}>Edit</window.UdUI.Btn>
                    <window.UdUI.Btn size="sm" variant="danger" onClick={() => deleteSub(s.id)}>Delete</window.UdUI.Btn>
                  </div>
                </div>
              );
            })}
            {event.subEvents.length === 0 && <div style={{ color: 'var(--text-muted)', fontSize: 'var(--text-sm)' }}>No sub-events yet.</div>}
          </div>
          <Button variant="secondary" onClick={() => setSubDialog({ editing: null })}>+ Add sub-event</Button>
          <SubEventFormDialog open={!!subDialog} initial={subDialog ? subDialog.editing : null} mainVenue={event.venue} allSubEvents={event.subEvents} otherMainSubDates={otherMainSubDates} onClose={() => setSubDialog(null)} onSave={saveSub} />
          <CertificatePreviewDialog open={!!certSub} sub={certSub} event={event} onClose={() => setCertSub(null)} />
          <CertificateTemplateEditorDialog open={!!certDesignSub} sub={certDesignSub} event={event} onClose={() => setCertDesignSub(null)} onSave={(tmpl) => saveCertTemplate(certDesignSub.id, tmpl)} onUploadTemplate={uploadCertTemplate} />
          <CheckinQrDialog open={!!checkinQrSub} sub={checkinQrSub} event={event} onClose={() => setCheckinQrSub(null)} />
        </div>
      )}

      {tab === 'schedule' && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {event.subEvents.map((s) => (
            <div key={s.id} style={{ background: 'white', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-sm)', padding: '16px 18px', display: 'flex', gap: 16 }}>
              <div style={{ fontFamily: 'var(--font-mono)', color: 'var(--brand-primary)', fontSize: 'var(--text-sm)', flex: '0 0 90px' }}>{s.date}</div>
              <div>
                <div style={{ fontWeight: 700 }}>{s.title}</div>
                <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)' }}>{s.startTime} \u2013 {s.endTime}</div>
                <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-secondary)' }}>{(s.coaches || []).map((c) => c.name).filter(Boolean).join(' & ') || 'Not assigned'}</div>
              </div>
            </div>
          ))}
          {event.subEvents.length === 0 && <div style={{ color: 'var(--text-muted)', fontSize: 'var(--text-sm)' }}>No sub-events yet.</div>}
        </div>
      )}

      {tab === 'pricing' && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 28 }}>
          {event.subEvents.map((s) => (
            <div key={s.id}>
              <div style={{ fontWeight: 700, marginBottom: 12 }}>{s.title}</div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 16 }}>
                {(s.pricingTiers || []).map((t, i) => (
                  <div key={i} style={{ background: 'white', border: t.highlighted ? '2px solid var(--brand-primary)' : '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-sm)', padding: 20 }}>
                    <div style={{ fontWeight: 700, marginBottom: 6 }}>{t.name}</div>
                    <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'var(--text-xl)', marginBottom: 10 }}>{'\u20b1' + t.price.toLocaleString('en-US')}</div>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 'var(--text-sm)', color: 'var(--text-secondary)' }}>
                      {(t.features || []).map((f, fi) => <div key={fi}>· {f}</div>)}
                    </div>
                  </div>
                ))}
                {(s.pricingTiers || []).length === 0 && <div style={{ color: 'var(--text-muted)', fontSize: 'var(--text-sm)' }}>No pricing tiers set.</div>}
              </div>
            </div>
          ))}
          {event.subEvents.length === 0 && <div style={{ color: 'var(--text-muted)', fontSize: 'var(--text-sm)' }}>No sub-events yet.</div>}
        </div>
      )}

      <window.EventFormDialog open={eventDialog} initial={event} onClose={() => setEventDialog(false)} onSave={saveEvent} />
    </div>
  );
}
window.EventDetailScreen = EventDetailScreen;
