// events.jsx — Papan Event komunitas. Browse + detail + RSVP + buat acara. Global.

const EVENT_CATS = [
  { key: 'komunitas', label: 'Kumpul Warga', icon: 'users', color: '#7C3AED' },
  { key: 'olahraga', label: 'Olahraga', icon: 'dumbbell', color: '#10B981' },
  { key: 'bazaar', label: 'Bazaar', icon: 'store', color: '#EF4444' },
  { key: 'edukasi', label: 'Edukasi', icon: 'school', color: '#1B4FD8' },
  { key: 'hiburan', label: 'Hiburan', icon: 'music', color: '#EC4899' },
  { key: 'anak', label: 'Anak & Keluarga', icon: 'cake', color: '#F59E0B' },
  { key: 'keagamaan', label: 'Keagamaan', icon: 'leaf', color: '#14B8A6' },
  { key: 'lainnya', label: 'Lainnya', icon: 'grid', color: '#64748B' },
];
const EVENT_CAT = EVENT_CATS.reduce((a, c) => (a[c.key] = c, a), {});
const ID_DAYS = ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'];
const ID_MON = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'];

function evDateParts(iso) {
  const d = new Date(iso);
  return { day: d.getDate(), mon: ID_MON[d.getMonth()], dow: ID_DAYS[d.getDay()],
    time: ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2), d: d };
}
function evWhenLabel(iso) {
  const p = evDateParts(iso);
  const now = new Date(); const t0 = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const diff = Math.round((new Date(p.d.getFullYear(), p.d.getMonth(), p.d.getDate()) - t0) / 86400000);
  const rel = diff === 0 ? 'Hari ini' : diff === 1 ? 'Besok' : (p.dow + ', ' + p.day + ' ' + p.mon);
  return rel + ' · ' + p.time;
}

function EventCard({ ev, onOpen }) {
  const cc = EVENT_CAT[ev.category] || EVENT_CAT.lainnya;
  const p = evDateParts(ev.starts_at);
  return (
    <button onClick={() => onOpen(ev)} style={{ display: 'flex', width: '100%', textAlign: 'left', gap: 0, padding: 0, border: '1px solid var(--border)',
      borderRadius: 'var(--r-card)', overflow: 'hidden', background: 'var(--surface)', cursor: 'pointer', boxShadow: 'var(--sh-1)', fontFamily: 'var(--font)' }}>
      <div style={{ width: 64, flexShrink: 0, background: cc.color + '14', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '12px 0' }}>
        <span style={{ fontSize: 11, fontWeight: 700, color: cc.color, textTransform: 'uppercase' }}>{p.dow}</span>
        <span style={{ fontSize: 22, fontWeight: 800, color: 'var(--text-1)', lineHeight: 1.1 }}>{p.day}</span>
        <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-3)' }}>{p.mon}</span>
      </div>
      <div style={{ flex: 1, padding: '12px 14px', minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
          <Icon name={cc.icon} size={13} color={cc.color} />
          <span style={{ fontSize: 11, fontWeight: 700, color: cc.color }}>{cc.label}</span>
          {ev.is_featured && <span style={{ marginLeft: 'auto', fontSize: 9.5, fontWeight: 800, color: '#fff', background: 'var(--cta)', padding: '2px 7px', borderRadius: 999 }}>UNGGULAN</span>}
        </div>
        <div style={{ fontSize: 14.5, fontWeight: 700, color: 'var(--text-1)', lineHeight: 1.3, display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{ev.title}</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 5, fontSize: 12, color: 'var(--text-3)', marginTop: 5 }}>
          <Icon name="clock" size={12} color="var(--text-3)" /><span>{evDateParts(ev.starts_at).time}</span>
          {ev.venue && <><span>·</span><Icon name="pin" size={12} color="var(--text-3)" /><span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{ev.venue}</span></>}
        </div>
        {ev.rsvp_count > 0 && <div style={{ fontSize: 11.5, color: 'var(--primary)', fontWeight: 600, marginTop: 4 }}>{ev.rsvp_count} warga ikut</div>}
      </div>
    </button>
  );
}

function EventsScreen({ authed, onRequireAuth, profile, clusters = [], onCreate }) {
  const [items, setItems] = React.useState([]);
  const [cat, setCat] = React.useState('all');
  const [loading, setLoading] = React.useState(true);
  const [rsvps, setRsvps] = React.useState({});
  const [detail, setDetail] = React.useState(null);

  const load = React.useCallback(() => {
    setLoading(true);
    gsData.loadEvents({ category: cat }).then(d => { setItems(d); setLoading(false); });
    if (authed) gsData.myEventRsvps().then(setRsvps);
  }, [cat, authed]);
  React.useEffect(() => { load(); }, [load]);

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--bg)' }}>
      <div style={{ paddingTop: SAFE_TOP, background: 'var(--surface)', borderBottom: '1px solid var(--border)' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '8px 20px 12px' }}>
          <h2 style={{ fontSize: 24, fontWeight: 800, letterSpacing: '-0.03em', color: 'var(--text-1)' }}>Acara Warga</h2>
          <button onClick={onCreate} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '9px 14px', borderRadius: 'var(--r-chip)', border: 'none',
            background: 'var(--cta)', color: '#fff', fontWeight: 800, fontSize: 13, cursor: 'pointer', boxShadow: 'var(--sh-cta)', fontFamily: 'var(--font)' }}>
            <Icon name="plus" size={16} color="#fff" sw={2.6} /> Buat
          </button>
        </div>
        <div style={{ display: 'flex', gap: 8, overflowX: 'auto', padding: '0 20px 12px', scrollbarWidth: 'none' }}>
          <Pill active={cat === 'all'} onClick={() => setCat('all')}>Semua</Pill>
          {EVENT_CATS.map(c => <Pill key={c.key} active={cat === c.key} color={c.color} onClick={() => setCat(c.key)}>{c.label}</Pill>)}
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '16px 16px 90px', scrollbarWidth: 'none' }}>
        {loading ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>{[0, 1, 2].map(i => <div key={i} style={{ height: 96, borderRadius: 'var(--r-card)', background: 'var(--surface-2)' }} />)}</div>
        ) : items.length === 0 ? (
          <div style={{ textAlign: 'center', padding: '60px 24px', color: 'var(--text-3)' }}>
            <div style={{ width: 64, height: 64, borderRadius: '50%', background: 'var(--surface-2)', display: 'grid', placeItems: 'center', margin: '0 auto 16px' }}><Icon name="calendar" size={30} color="var(--text-3)" /></div>
            <div style={{ fontSize: 15, fontWeight: 700, color: 'var(--text-2)' }}>Belum ada acara mendatang</div>
            <div style={{ fontSize: 13, marginTop: 4 }}>Buat acara pertama untuk warga!</div>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
            {items.map(ev => <EventCard key={ev.id} ev={ev} onOpen={setDetail} />)}
          </div>
        )}
      </div>

      {detail && <EventDetailSheet ev={detail} authed={authed} profile={profile} clusters={clusters} going={!!rsvps[detail.id]}
        onRequireAuth={onRequireAuth} onClose={() => setDetail(null)} onChanged={() => { setDetail(null); load(); }} />}
    </div>
  );
}

function EventDetailSheet({ ev, authed, profile, clusters = [], going, onRequireAuth, onClose, onChanged }) {
  const cc = EVENT_CAT[ev.category] || EVENT_CAT.lainnya;
  const [isGoing, setIsGoing] = React.useState(going);
  const [count, setCount] = React.useState(ev.rsvp_count || 0);
  const [busy, setBusy] = React.useState(false);
  const [editing, setEditing] = React.useState(false);
  const [confirmDel, setConfirmDel] = React.useState(false);
  const isOwner = profile && ev.user_id === profile.id;

  if (editing) return <div style={{ position: 'absolute', inset: 0, zIndex: 90 }}><EventEditFlow ev={ev} clusters={clusters} onClose={() => setEditing(false)} onDone={() => { setEditing(false); onChanged(); }} /></div>;
  const wa = ev.contact_wa ? waLink(ev.contact_wa, 'Halo, saya mau tanya soal acara "' + ev.title + '" di gs.town.') : null;
  const mapUrl = ev.lat != null && ev.lng != null
    ? 'https://www.google.com/maps/search/?api=1&query=' + ev.lat + ',' + ev.lng
    : (ev.venue ? 'https://www.google.com/maps/search/?api=1&query=' + encodeURIComponent(ev.venue + ' Gading Serpong') : null);

  const toggle = async () => {
    if (!authed) return onRequireAuth && onRequireAuth();
    const next = !isGoing; setIsGoing(next); setCount(c => c + (next ? 1 : -1)); setBusy(true);
    const res = await gsData.toggleRsvp(ev.id, next); setBusy(false);
    if (res.error) { setIsGoing(!next); setCount(c => c + (next ? -1 : 1)); }
  };
  const ownAct = async (fn) => { setBusy(true); await fn(); setBusy(false); onChanged(); };

  const p = evDateParts(ev.starts_at);
  const endTime = ev.ends_at ? evDateParts(ev.ends_at).time : null;

  return (
    <Sheet onClose={onClose} height="92%">
      <div style={{ flex: 1, overflowY: 'auto', scrollbarWidth: 'none' }}>
        <div style={{ position: 'relative', height: ev.photo_url ? 200 : 120, background: cc.color + '14', display: 'grid', placeItems: 'center', overflow: 'hidden' }}>
          {ev.photo_url ? <img src={ev.photo_url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} /> : <Icon name={cc.icon} size={52} color={cc.color} />}
          <button onClick={onClose} style={{ position: 'absolute', top: 12, right: 12, width: 34, height: 34, borderRadius: '50%', border: 'none', background: 'rgba(255,255,255,0.92)', display: 'grid', placeItems: 'center', cursor: 'pointer' }}><Icon name="x" size={18} color="var(--s-900)" /></button>
        </div>
        <div style={{ padding: '18px 20px 8px' }}>
          <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '4px 10px', borderRadius: 999, background: cc.color + '18', marginBottom: 10 }}>
            <Icon name={cc.icon} size={13} color={cc.color} /><span style={{ fontSize: 11.5, fontWeight: 800, color: cc.color }}>{cc.label}</span>
          </div>
          <h2 style={{ fontSize: 21, fontWeight: 800, color: 'var(--text-1)', letterSpacing: '-0.02em', lineHeight: 1.3 }}>{ev.title}</h2>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 1, marginTop: 14 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 0', borderBottom: '1px solid var(--border)' }}>
              <Icon name="calendar" size={18} color="var(--primary)" />
              <div><div style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-1)' }}>{p.dow}, {p.day} {p.mon}</div><div style={{ fontSize: 12.5, color: 'var(--text-3)' }}>{p.time}{endTime ? ' – ' + endTime : ''}</div></div>
            </div>
            {ev.venue && (
              <button onClick={() => mapUrl && window.open(mapUrl, '_blank')} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 0', borderBottom: '1px solid var(--border)', border: 'none', borderBottomStyle: 'solid', borderBottomWidth: 1, borderBottomColor: 'var(--border)', background: 'none', cursor: mapUrl ? 'pointer' : 'default', textAlign: 'left', width: '100%', fontFamily: 'var(--font)' }}>
                <Icon name="pin" size={18} color="var(--primary)" />
                <div style={{ flex: 1 }}><div style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-1)' }}>{ev.venue}</div>{mapUrl && <div style={{ fontSize: 12, color: 'var(--primary)', fontWeight: 600 }}>Buka di peta</div>}</div>
              </button>
            )}
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 0', borderBottom: ev.body ? '1px solid var(--border)' : 'none' }}>
              <Icon name="user" size={18} color="var(--primary)" />
              <div><div style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-1)' }}>{ev.organizer}</div><div style={{ fontSize: 12.5, color: 'var(--text-3)' }}>Penyelenggara{ev.cluster ? ' · ' + ev.cluster : ''}</div></div>
              <span style={{ marginLeft: 'auto', display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 13, fontWeight: 700, color: 'var(--text-2)' }}><Icon name="users" size={15} color="var(--text-3)" /> {count}</span>
            </div>
          </div>
          {ev.body && <p style={{ fontSize: 14.5, color: 'var(--text-2)', lineHeight: 1.6, whiteSpace: 'pre-wrap', marginTop: 14 }}>{ev.body}</p>}
        </div>
      </div>

      <div style={{ padding: '12px 20px', paddingBottom: 26, borderTop: '1px solid var(--border)', background: 'var(--surface)' }}>
        {isOwner ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
            {ev.status === 'cancelled' && <div style={{ textAlign: 'center', fontSize: 12.5, fontWeight: 700, color: 'var(--amber-700)', padding: '2px 0' }}>Acara ini dibatalkan</div>}
            <div style={{ display: 'flex', gap: 9 }}>
              <button disabled={busy} onClick={() => setEditing(true)} className="gs-press" style={{ flex: 1, padding: '14px', borderRadius: 'var(--r-chip)', border: 'none', background: 'var(--primary)', color: '#fff', fontWeight: 800, fontSize: 14, cursor: 'pointer', fontFamily: 'var(--font)' }}>Edit acara</button>
              {ev.status !== 'cancelled' && <button disabled={busy} onClick={() => ownAct(() => gsData.setEventStatus(ev.id, 'cancelled'))} className="gs-press" style={{ flex: 1, padding: '14px', borderRadius: 'var(--r-chip)', border: '1px solid var(--border)', background: 'var(--surface)', color: 'var(--amber-700)', fontWeight: 700, fontSize: 14, cursor: 'pointer', fontFamily: 'var(--font)' }}>Batalkan</button>}
            </div>
            <button disabled={busy} onClick={() => setConfirmDel(true)} className="gs-press" style={{ width: '100%', padding: '14px', borderRadius: 'var(--r-chip)', border: 'none', background: 'var(--coral-50)', color: 'var(--coral-700)', fontWeight: 700, fontSize: 14, cursor: 'pointer', fontFamily: 'var(--font)' }}>Hapus acara</button>
            {confirmDel && <ConfirmDialog title="Hapus acara?" message="Acara & semua RSVP akan dihapus permanen." busy={busy} onCancel={() => setConfirmDel(false)} onConfirm={() => { setConfirmDel(false); ownAct(() => gsData.deleteEvent(ev.id)); }} />}
          </div>
        ) : (
          <div style={{ display: 'flex', gap: 9 }}>
            <button onClick={toggle} disabled={busy} style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: '15px', borderRadius: 'var(--r-chip)', border: isGoing ? '1px solid var(--primary)' : 'none',
              background: isGoing ? 'var(--primary-soft)' : 'var(--cta)', color: isGoing ? 'var(--primary)' : '#fff', fontWeight: 800, fontSize: 15, cursor: 'pointer', boxShadow: isGoing ? 'none' : 'var(--sh-cta)', fontFamily: 'var(--font)' }}>
              <Icon name={isGoing ? 'check' : 'users'} size={19} color={isGoing ? 'var(--primary)' : '#fff'} /> {isGoing ? 'Kamu ikut' : 'Saya ikut'}
            </button>
            {wa && (authed
              ? <a href={wa} target="_blank" rel="noopener noreferrer" style={{ width: 56, display: 'grid', placeItems: 'center', borderRadius: 'var(--r-chip)', background: 'var(--surface)', border: '1px solid var(--border)' }}><Icon name="phone" size={20} color="var(--cta)" /></a>
              : <button onClick={() => onRequireAuth && onRequireAuth()} title="Masuk untuk lihat kontak" style={{ width: 56, display: 'grid', placeItems: 'center', borderRadius: 'var(--r-chip)', background: 'var(--surface)', border: '1px solid var(--border)', cursor: 'pointer' }}><Icon name="phone" size={20} color="var(--text-3)" /></button>)}
          </div>
        )}
      </div>
    </Sheet>
  );
}

function EventCreateFlow({ clusters, profile, onClose, onDone }) {
  const [cat, setCat] = React.useState('komunitas');
  const [title, setTitle] = React.useState('');
  const [starts, setStarts] = React.useState('');
  const [ends, setEnds] = React.useState('');
  const [venue, setVenue] = React.useState('');
  const [clusterId, setClusterId] = React.useState('');
  const [wa, setWa] = React.useState('');
  const [body, setBody] = React.useState('');
  const [photoFile, setPhotoFile] = React.useState(null);
  const [photoPrev, setPhotoPrev] = React.useState(null);
  const [err, setErr] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [done, setDone] = React.useState(false);
  const fileRef = React.useRef(null);

  const onFile = (e) => { const f = e.target.files && e.target.files[0]; if (!f) return; setPhotoFile(f); if (photoPrev) URL.revokeObjectURL(photoPrev); setPhotoPrev(URL.createObjectURL(f)); };

  const submit = async () => {
    if (!title.trim()) return setErr('Judul acara wajib diisi');
    if (!starts) return setErr('Tanggal & waktu mulai wajib diisi');
    setBusy(true); setErr('');
    const res = await gsData.submitEvent({ category: cat, title, starts_at: new Date(starts).toISOString(),
      ends_at: ends ? new Date(ends).toISOString() : null, venue, cluster_id: clusterId || null, contact_wa: wa, body, photoFile });
    setBusy(false);
    if (res.error) return setErr('Gagal: ' + res.error);
    setDone(true); setTimeout(onDone, 1400);
  };

  if (done) return (
    <FlowShell onClose={onClose} title="">
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: 32 }}>
        <div style={{ width: 80, height: 80, borderRadius: '50%', background: 'var(--lime-50)', display: 'grid', placeItems: 'center', marginBottom: 20 }}>
          <span style={{ width: 56, height: 56, borderRadius: '50%', background: 'var(--lime)', display: 'grid', placeItems: 'center' }}><Icon name="check" size={32} color="#fff" sw={2.6} /></span>
        </div>
        <h2 style={{ fontSize: 21, fontWeight: 800, color: 'var(--text-1)' }}>Acara dibuat!</h2>
        <p style={{ fontSize: 14, color: 'var(--text-2)', marginTop: 6, maxWidth: 260 }}>Acaramu sudah tayang di papan acara warga.</p>
      </div>
    </FlowShell>
  );

  const fld = { width: '100%', padding: '13px 14px', borderRadius: 'var(--r-md)', border: '1px solid var(--border)', background: 'var(--surface-2)', fontFamily: 'var(--font)', fontSize: 14.5, fontWeight: 500, color: 'var(--text-1)', outline: 'none' };

  return (
    <FlowShell onClose={onClose} title="Buat Acara"
      footer={<button onClick={submit} disabled={busy} style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: 15, borderRadius: 'var(--r-chip)', border: 'none', background: 'var(--cta)', color: '#fff', fontWeight: 800, fontSize: 15, cursor: busy ? 'default' : 'pointer', opacity: busy ? 0.7 : 1, boxShadow: 'var(--sh-cta)' }}>{busy ? 'Membuat...' : 'Buat Acara'}{!busy && <Icon name="arrow" size={18} color="#fff" sw={2.4} />}</button>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
        <div>
          <Lbl>Kategori</Lbl>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 8 }}>
            {EVENT_CATS.map(c => { const on = cat === c.key; return (
              <button key={c.key} onClick={() => setCat(c.key)} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5, padding: '11px 4px', borderRadius: 'var(--r-md)', cursor: 'pointer', border: '2px solid ' + (on ? c.color : 'var(--border)'), background: on ? c.color + '12' : 'var(--surface)', fontFamily: 'var(--font)' }}>
                <Icon name={c.icon} size={19} color={c.color} /><span style={{ fontSize: 9.5, fontWeight: 700, color: on ? c.color : 'var(--text-2)', textAlign: 'center', lineHeight: 1.1 }}>{c.label}</span>
              </button>); })}
          </div>
        </div>
        <div>
          <Lbl>Foto poster <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(opsional)</span></Lbl>
          <input ref={fileRef} type="file" accept="image/*" onChange={onFile} style={{ display: 'none' }} />
          <button onClick={() => fileRef.current && fileRef.current.click()} style={{ width: '100%', height: photoPrev ? 160 : 92, borderRadius: 'var(--r-md)', border: photoPrev ? 'none' : '2px dashed var(--border-strong)', background: 'var(--surface-2)', display: 'grid', placeItems: 'center', cursor: 'pointer', overflow: 'hidden', padding: 0 }}>
            {photoPrev ? <img src={photoPrev} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} /> : <span style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, color: 'var(--text-3)' }}><Icon name="camera" size={24} color="var(--text-3)" /><span style={{ fontSize: 12.5, fontWeight: 600 }}>Tambah poster acara</span></span>}
          </button>
        </div>
        <div><Lbl>Judul acara</Lbl><Inp value={title} onChange={e => { setTitle(e.target.value); setErr(''); }} placeholder="cth. Senam Pagi Bersama Warga" /></div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <div><Lbl>Mulai</Lbl><input type="datetime-local" value={starts} onChange={e => { setStarts(e.target.value); setErr(''); }} style={fld} /></div>
          <div><Lbl>Selesai <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(ops)</span></Lbl><input type="datetime-local" value={ends} onChange={e => setEnds(e.target.value)} style={fld} /></div>
        </div>
        <div><Lbl>Lokasi / venue</Lbl><Inp value={venue} onChange={e => setVenue(e.target.value)} placeholder="cth. Lapangan Cluster Allevare" /></div>
        <div><Lbl>Cluster <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(opsional)</span></Lbl>
          <select value={clusterId} onChange={e => setClusterId(e.target.value)} style={{ ...fld, appearance: 'none' }}>
            <option value="">Pilih cluster</option>
            {clusters.map(cl => <option key={cl.id} value={cl.id}>{cl.name}</option>)}
          </select></div>
        <div><Lbl>Deskripsi <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(opsional)</span></Lbl>
          <textarea value={body} maxLength={800} onChange={e => setBody(e.target.value)} rows={3} placeholder="Detail acara, syarat ikut, biaya, dll..." style={{ ...fld, resize: 'none', lineHeight: 1.5 }} /></div>
        <div><Lbl>Kontak WhatsApp <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(opsional)</span></Lbl><Inp value={wa} onChange={e => setWa(e.target.value)} placeholder="08xxxxxxxxxx" type="tel" /></div>
        {err && <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '11px 14px', borderRadius: 'var(--r-md)', background: 'var(--coral-50)', color: 'var(--coral-700)', fontSize: 13, fontWeight: 600 }}><Icon name="shield" size={16} color="var(--coral-700)" /> {err}</div>}
      </div>
    </FlowShell>
  );
}

function toLocalInput(iso) {
  if (!iso) return '';
  const d = new Date(iso);
  const p = n => ('0' + n).slice(-2);
  return d.getFullYear() + '-' + p(d.getMonth() + 1) + '-' + p(d.getDate()) + 'T' + p(d.getHours()) + ':' + p(d.getMinutes());
}

function EventEditFlow({ ev, clusters = [], onClose, onDone }) {
  const [cat, setCat] = React.useState(ev.category || 'komunitas');
  const [title, setTitle] = React.useState(ev.title || '');
  const [starts, setStarts] = React.useState(toLocalInput(ev.starts_at));
  const [ends, setEnds] = React.useState(toLocalInput(ev.ends_at));
  const [venue, setVenue] = React.useState(ev.venue || '');
  const [clusterId, setClusterId] = React.useState(ev.cluster_id || '');
  const [wa, setWa] = React.useState(ev.contact_wa || '');
  const [body, setBody] = React.useState(ev.body || '');
  const [photoFile, setPhotoFile] = React.useState(null);
  const [photoPrev, setPhotoPrev] = React.useState(ev.photo_url || null);
  const [err, setErr] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const fileRef = React.useRef(null);

  const onFile = (e) => { const f = e.target.files && e.target.files[0]; if (!f) return; setPhotoFile(f); setPhotoPrev(URL.createObjectURL(f)); };
  const submit = async () => {
    if (!title.trim()) return setErr('Judul acara wajib diisi');
    if (!starts) return setErr('Tanggal & waktu mulai wajib diisi');
    setBusy(true); setErr('');
    const res = await gsData.updateEvent(ev.id, { category: cat, title, starts_at: new Date(starts).toISOString(),
      ends_at: ends ? new Date(ends).toISOString() : null, venue, cluster_id: clusterId || null, contact_wa: wa, body, photoFile });
    setBusy(false);
    if (res.error) return setErr('Gagal: ' + res.error);
    onDone();
  };

  const fld = { width: '100%', padding: '13px 14px', borderRadius: 'var(--r-md)', border: '1px solid var(--border)', background: 'var(--surface-2)', fontFamily: 'var(--font)', fontSize: 14.5, fontWeight: 500, color: 'var(--text-1)', outline: 'none' };

  return (
    <FlowShell onClose={onClose} title="Edit Acara"
      footer={<button onClick={submit} disabled={busy} className="gs-press" style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: 15, borderRadius: 'var(--r-chip)', border: 'none', background: 'var(--primary)', color: '#fff', fontWeight: 800, fontSize: 15, cursor: busy ? 'default' : 'pointer', opacity: busy ? 0.7 : 1 }}>{busy ? 'Menyimpan...' : 'Simpan perubahan'}{!busy && <Icon name="check" size={18} color="#fff" sw={2.6} />}</button>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
        <div>
          <Lbl>Kategori</Lbl>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 8 }}>
            {EVENT_CATS.map(c => { const on = cat === c.key; return (
              <button key={c.key} onClick={() => setCat(c.key)} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5, padding: '11px 4px', borderRadius: 'var(--r-md)', cursor: 'pointer', border: '2px solid ' + (on ? c.color : 'var(--border)'), background: on ? c.color + '12' : 'var(--surface)', fontFamily: 'var(--font)' }}>
                <Icon name={c.icon} size={19} color={c.color} /><span style={{ fontSize: 9.5, fontWeight: 700, color: on ? c.color : 'var(--text-2)', textAlign: 'center', lineHeight: 1.1 }}>{c.label}</span>
              </button>); })}
          </div>
        </div>
        <div>
          <Lbl>Foto poster</Lbl>
          <input ref={fileRef} type="file" accept="image/*" onChange={onFile} style={{ display: 'none' }} />
          <button onClick={() => fileRef.current && fileRef.current.click()} style={{ width: '100%', height: photoPrev ? 160 : 92, borderRadius: 'var(--r-md)', border: photoPrev ? 'none' : '2px dashed var(--border-strong)', background: 'var(--surface-2)', display: 'grid', placeItems: 'center', cursor: 'pointer', overflow: 'hidden', padding: 0 }}>
            {photoPrev ? <img src={photoPrev} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} /> : <span style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, color: 'var(--text-3)' }}><Icon name="camera" size={24} color="var(--text-3)" /><span style={{ fontSize: 12.5, fontWeight: 600 }}>Ganti poster</span></span>}
          </button>
        </div>
        <div><Lbl>Judul acara</Lbl><Inp value={title} onChange={e => { setTitle(e.target.value); setErr(''); }} placeholder="cth. Senam Pagi Bersama Warga" /></div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <div><Lbl>Mulai</Lbl><input type="datetime-local" value={starts} onChange={e => { setStarts(e.target.value); setErr(''); }} style={fld} /></div>
          <div><Lbl>Selesai <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(ops)</span></Lbl><input type="datetime-local" value={ends} onChange={e => setEnds(e.target.value)} style={fld} /></div>
        </div>
        <div><Lbl>Lokasi / venue</Lbl><Inp value={venue} onChange={e => setVenue(e.target.value)} placeholder="cth. Lapangan Cluster Allevare" /></div>
        <div><Lbl>Cluster <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(opsional)</span></Lbl>
          <select value={clusterId} onChange={e => setClusterId(e.target.value)} style={{ ...fld, appearance: 'none' }}>
            <option value="">Pilih cluster</option>
            {clusters.map(cl => <option key={cl.id} value={cl.id}>{cl.name}</option>)}
          </select></div>
        <div><Lbl>Deskripsi</Lbl><textarea value={body} maxLength={800} onChange={e => setBody(e.target.value)} rows={3} placeholder="Detail acara..." style={{ ...fld, resize: 'none', lineHeight: 1.5 }} /></div>
        <div><Lbl>Kontak WhatsApp</Lbl><Inp value={wa} onChange={e => setWa(e.target.value)} placeholder="08xxxxxxxxxx" type="tel" /></div>
        {err && <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '11px 14px', borderRadius: 'var(--r-md)', background: 'var(--coral-50)', color: 'var(--coral-700)', fontSize: 13, fontWeight: 600 }}><Icon name="shield" size={16} color="var(--coral-700)" /> {err}</div>}
      </div>
    </FlowShell>
  );
}

Object.assign(window, { EventsScreen, EventDetailSheet, EventCreateFlow, EventEditFlow, EVENT_CATS, evDateParts, evWhenLabel });
