// lapak.jsx — Lapak warga (marketplace). Browse + detail + pasang (quota/tier). Global.

const LAPAK_CATS = [
  { key: 'preloved', label: 'Pre-loved', icon: 'tag', color: '#7C3AED' },
  { key: 'properti', label: 'Properti', icon: 'home', color: '#1B4FD8' },
  { key: 'jasa', label: 'Jasa & Tukang', icon: 'wrench', color: '#F59E0B' },
  { key: 'loker', label: 'Loker', icon: 'bag', color: '#0EA5E9' },
  { key: 'kuliner', label: 'Kuliner', icon: 'food', color: '#EF4444' },
  { key: 'otomotif', label: 'Otomotif', icon: 'car', color: '#14B8A6' },
  { key: 'jastip', label: 'Jastip', icon: 'store', color: '#EC4899' },
  { key: 'hobi', label: 'Hobi & OR', icon: 'dumbbell', color: '#10B981' },
  { key: 'lainnya', label: 'Lainnya', icon: 'grid', color: '#64748B' },
];
const LAPAK_CAT = LAPAK_CATS.reduce((a, c) => (a[c.key] = c, a), {});
const LAPAK_TIERS = [
  { tier: 1, name: 'Gratis', price: 0, quota: '1 lapak / bulan', sub: 'Untuk semua warga' },
  { tier: 2, name: 'Mingguan', price: 50000, quota: '1 lapak / minggu', sub: 'Lebih sering jualan' },
  { tier: 3, name: 'Pro', price: 75000, quota: '2 lapak / minggu', sub: 'Untuk yang aktif' },
  { tier: 4, name: 'Bisnis', price: 120000, quota: '3 lapak / minggu', sub: 'Untuk UMKM & toko' },
];

function lapakRp(n) {
  if (n == null || n === '') return 'Nego';
  return 'Rp' + Number(n).toLocaleString('id-ID');
}
function waLink(num, text) {
  if (!num) return null;
  var n = ('' + num).replace(/[^0-9]/g, '');
  if (n.indexOf('0') === 0) n = '62' + n.slice(1);
  else if (n.indexOf('62') !== 0) n = '62' + n;
  return 'https://wa.me/' + n + (text ? '?text=' + encodeURIComponent(text) : '');
}

function LapakCard({ item, onOpen }) {
  const cc = LAPAK_CAT[item.category] || LAPAK_CAT.lainnya;
  const img = item.photos && item.photos[0];
  return (
    <button onClick={() => onOpen(item)} style={{ display: 'block', textAlign: 'left', 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={{ position: 'relative', aspectRatio: '1 / 1', background: cc.color + '14', display: 'grid', placeItems: 'center', overflow: 'hidden' }}>
        {img ? <img src={img} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
             : <Icon name={cc.icon} size={40} color={cc.color} />}
        {item.is_featured && <span style={{ position: 'absolute', top: 8, left: 8, fontSize: 10, fontWeight: 800, color: '#fff', background: 'var(--cta)', padding: '3px 8px', borderRadius: 999 }}>UNGGULAN</span>}
        <span style={{ position: 'absolute', top: 8, right: 8, width: 26, height: 26, borderRadius: '50%', background: 'rgba(255,255,255,0.92)', display: 'grid', placeItems: 'center' }}>
          <Icon name={cc.icon} size={14} color={cc.color} />
        </span>
      </div>
      <div style={{ padding: '10px 11px 12px' }}>
        <div style={{ fontSize: 13.5, fontWeight: 700, color: 'var(--text-1)', lineHeight: 1.3, display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden', minHeight: 35 }}>{item.title}</div>
        <div style={{ fontSize: 14.5, fontWeight: 800, color: 'var(--cta)', marginTop: 5 }}>{lapakRp(item.price)}</div>
        <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 4, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{item.cluster || item.seller}</div>
      </div>
    </button>
  );
}

function LapakScreen({ authed, onRequireAuth, clusters, profile, onPost }) {
  const [items, setItems] = React.useState([]);
  const [cat, setCat] = React.useState('all');
  const [q, setQ] = React.useState('');
  const [loading, setLoading] = React.useState(true);
  const [detail, setDetail] = React.useState(null);

  const load = React.useCallback(() => {
    setLoading(true);
    gsData.loadLapak({ category: cat, search: q.trim() }).then(d => { setItems(d); setLoading(false); });
  }, [cat, q]);
  React.useEffect(() => { const t = setTimeout(load, q ? 280 : 0); return () => clearTimeout(t); }, [cat, q]);

  const isOwner = detail && profile && detail.user_id === profile.id;

  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={{ padding: '8px 20px 12px' }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <h2 style={{ fontSize: 24, fontWeight: 800, letterSpacing: '-0.03em', color: 'var(--text-1)' }}>Lapak Warga</h2>
            <button onClick={onPost} 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} /> Pasang
            </button>
          </div>
          <div style={{ position: 'relative', marginTop: 12 }}>
            <span style={{ position: 'absolute', left: 13, top: '50%', transform: 'translateY(-50%)' }}><Icon name="search" size={17} color="var(--text-3)" /></span>
            <input value={q} onChange={e => setQ(e.target.value)} placeholder="Cari barang, jasa, properti..."
              style={{ width: '100%', padding: '11px 14px 11px 38px', borderRadius: 'var(--r-chip)', border: '1px solid var(--border)', background: 'var(--surface-2)',
                fontFamily: 'var(--font)', fontSize: 14, color: 'var(--text-1)', outline: 'none' }} />
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8, overflowX: 'auto', padding: '0 20px 12px', scrollbarWidth: 'none' }}>
          <Pill active={cat === 'all'} onClick={() => setCat('all')}>Semua</Pill>
          {LAPAK_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: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            {[0, 1, 2, 3].map(i => <div key={i} style={{ aspectRatio: '0.78', 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="store" size={30} color="var(--text-3)" />
            </div>
            <div style={{ fontSize: 15, fontWeight: 700, color: 'var(--text-2)' }}>Belum ada lapak di sini</div>
            <div style={{ fontSize: 13, marginTop: 4 }}>Jadi yang pertama pasang lapak!</div>
          </div>
        ) : (
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            {items.map(it => <LapakCard key={it.id} item={it} onOpen={setDetail} />)}
          </div>
        )}
      </div>

      {detail && <LapakDetailSheet item={detail} isOwner={isOwner} authed={authed} clusters={clusters} onRequireAuth={onRequireAuth} onClose={() => setDetail(null)}
        onChanged={() => { setDetail(null); load(); }} />}
    </div>
  );
}

function LapakDetailSheet({ item, isOwner, authed, clusters = [], onRequireAuth, onClose, onChanged }) {
  const cc = LAPAK_CAT[item.category] || LAPAK_CAT.lainnya;
  const [idx, setIdx] = React.useState(0);
  const [busy, setBusy] = React.useState(false);
  const [editing, setEditing] = React.useState(false);
  const [confirmDel, setConfirmDel] = React.useState(false);
  const photos = item.photos && item.photos.length ? item.photos : [];
  const wa = waLink(item.contact_wa, 'Halo, saya lihat lapak "' + item.title + '" di gs.town. Masih ada?');

  const act = async (fn) => { setBusy(true); await fn(); setBusy(false); onChanged(); };

  if (editing) return <div style={{ position: 'absolute', inset: 0, zIndex: 90 }}><LapakEditFlow item={item} clusters={clusters} onClose={() => setEditing(false)} onDone={() => { setEditing(false); onChanged(); }} /></div>;

  return (
    <Sheet onClose={onClose} height="90%">
      <div style={{ position: 'relative' }}>
        <div style={{ position: 'relative', aspectRatio: '1 / 1', background: cc.color + '14', display: 'grid', placeItems: 'center', overflow: 'hidden' }}>
          {photos.length ? <img src={photos[idx]} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} /> : <Icon name={cc.icon} size={64} 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(--text-1)" />
          </button>
          {photos.length > 1 && (
            <div style={{ position: 'absolute', bottom: 12, left: 0, right: 0, display: 'flex', justifyContent: 'center', gap: 6 }}>
              {photos.map((_, i) => <button key={i} onClick={() => setIdx(i)} style={{ width: i === idx ? 22 : 7, height: 7, borderRadius: 999, border: 'none', background: i === idx ? '#fff' : 'rgba(255,255,255,0.55)', cursor: 'pointer', transition: 'all .2s' }} />)}
            </div>
          )}
        </div>
      </div>
      <div style={{ padding: '18px 20px 30px' }}>
        <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: 20, fontWeight: 800, color: 'var(--text-1)', letterSpacing: '-0.02em', lineHeight: 1.3 }}>{item.title}</h2>
        <div style={{ fontSize: 23, fontWeight: 800, color: 'var(--cta)', margin: '8px 0 14px' }}>{lapakRp(item.price)}</div>
        {item.body && <p style={{ fontSize: 14.5, color: 'var(--text-2)', lineHeight: 1.6, whiteSpace: 'pre-wrap', marginBottom: 16 }}>{item.body}</p>}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 14px', borderRadius: 'var(--r-card)', background: 'var(--surface-2)', marginBottom: 18 }}>
          <div style={{ width: 38, height: 38, borderRadius: '50%', background: 'var(--primary-soft)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
            <Icon name="user" size={19} color="var(--primary)" />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-1)' }}>{item.seller}</div>
            {item.cluster && <div style={{ fontSize: 12, color: 'var(--text-3)' }}>{item.cluster}</div>}
          </div>
        </div>

        {isOwner ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
            <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-3)', marginBottom: 2 }}>Kelola lapak kamu</div>
            <div style={{ display: 'flex', gap: 9 }}>
              <button disabled={busy} onClick={() => setEditing(true)} className="gs-press" style={ownBtn('var(--primary)')}>Edit lapak</button>
              <button disabled={busy} onClick={() => act(() => gsData.bumpLapak(item.id))} className="gs-press" style={ownBtn('var(--primary)')}>Naikkan ke atas</button>
            </div>
            <div style={{ display: 'flex', gap: 9 }}>
              {item.status !== 'sold' && <button disabled={busy} onClick={() => act(() => gsData.setLapakStatus(item.id, 'sold'))} className="gs-press" style={ownBtn('var(--lime-700)')}>Tandai terjual</button>}
              <button disabled={busy} onClick={() => setConfirmDel(true)} className="gs-press" style={{ ...ownBtn('var(--coral-700)'), background: 'var(--coral-50)' }}>Hapus lapak</button>
            </div>
            {confirmDel && <ConfirmDialog title="Hapus lapak?" message="Lapak ini akan dihapus permanen dan tidak bisa dikembalikan." busy={busy} onCancel={() => setConfirmDel(false)} onConfirm={() => { setConfirmDel(false); act(() => gsData.deleteLapak(item.id)); }} />}
          </div>
        ) : (
          !item.contact_wa ? <div style={{ textAlign: 'center', fontSize: 13, color: 'var(--text-3)', padding: 12 }}>Penjual tidak mencantumkan kontak.</div>
          : !authed ? (
            <button onClick={() => onRequireAuth && onRequireAuth()} style={{ display: 'flex', width: '100%', alignItems: 'center', justifyContent: 'center', gap: 9, padding: '15px', borderRadius: 'var(--r-chip)', border: 'none',
              background: 'var(--cta)', color: '#fff', fontWeight: 800, fontSize: 15, cursor: 'pointer', boxShadow: 'var(--sh-cta)', fontFamily: 'var(--font)' }}>
              <Icon name="shield" size={18} color="#fff" /> Masuk untuk lihat kontak
            </button>
          ) : (
            <a href={wa} target="_blank" rel="noopener noreferrer" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 9, padding: '15px', borderRadius: 'var(--r-chip)',
              background: 'var(--cta)', color: '#fff', fontWeight: 800, fontSize: 15.5, textDecoration: 'none', boxShadow: 'var(--sh-cta)' }}>
              <Icon name="phone" size={19} color="#fff" /> Hubungi via WhatsApp
            </a>
          )
        )}
      </div>
    </Sheet>
  );
}
function ownBtn(color) {
  return { flex: 1, padding: '13px', borderRadius: 'var(--r-md)', border: '1px solid var(--border)', background: 'var(--surface)',
    color: color, fontWeight: 700, fontSize: 13.5, cursor: 'pointer', fontFamily: 'var(--font)' };
}

function LapakPostFlow({ clusters, profile, onClose, onDone }) {
  const [quota, setQuota] = React.useState(undefined);
  const [cat, setCat] = React.useState('preloved');
  const [title, setTitle] = React.useState('');
  const [price, setPrice] = React.useState('');
  const [body, setBody] = React.useState('');
  const [wa, setWa] = React.useState('');
  const [clusterId, setClusterId] = React.useState('');
  const [files, setFiles] = React.useState([]);
  const [prev, setPrev] = React.useState([]);
  const [err, setErr] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [done, setDone] = React.useState(false);
  const [view, setView] = React.useState('form');
  const fileRef = React.useRef(null);

  React.useEffect(() => { gsData.lapakQuota().then(setQuota); }, []);

  const onFiles = (e) => {
    const fs = Array.from(e.target.files || []).slice(0, 4 - files.length);
    if (!fs.length) return;
    setFiles(p => [...p, ...fs].slice(0, 4));
    setPrev(p => [...p, ...fs.map(f => URL.createObjectURL(f))].slice(0, 4));
  };
  const rmPhoto = (i) => { setFiles(p => p.filter((_, j) => j !== i)); setPrev(p => p.filter((_, j) => j !== i)); };

  const submit = async () => {
    if (!title.trim()) return setErr('Judul lapak wajib diisi');
    if (!wa.trim()) return setErr('Nomor WhatsApp wajib diisi');
    setBusy(true); setErr('');
    const res = await gsData.submitLapak({ category: cat, title, price, body, contact_wa: wa, cluster_id: clusterId || null, files });
    setBusy(false);
    if (res.error === 'QUOTA') { setQuota(q => ({ ...(q || {}), can_post: false })); return; }
    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)' }}>Lapak terpasang!</h2>
        <p style={{ fontSize: 14, color: 'var(--text-2)', marginTop: 6, maxWidth: 260 }}>Lapakmu sudah tayang dan bisa dilihat semua warga.</p>
      </div>
    </FlowShell>;
  }

  if (view === 'upgrade') {
    return <FlowShell onClose={() => setView('form')} title="Paket Lapak"><LapakUpgrade quota={quota} note="Pilih paket untuk pasang lapak lebih sering." onClose={() => setView('form')} /></FlowShell>;
  }

  // gate kuota habis -> tampilkan upsell tier
  if (quota && quota.can_post === false) {
    return <FlowShell onClose={onClose} title="Kuota habis">
      <LapakUpgrade quota={quota} note="Kuota lapak periode ini sudah habis. Upgrade untuk pasang lebih sering." onClose={onClose} />
    </FlowShell>;
  }

  return (
    <FlowShell onClose={onClose} title="Pasang Lapak"
      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 ? 'Memasang...' : 'Pasang Lapak'}{!busy && <Icon name="arrow" size={18} color="#fff" sw={2.4} />}</button>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
        {quota && <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '10px 13px', borderRadius: 'var(--r-md)', background: 'var(--primary-soft)', fontSize: 12.5, color: 'var(--primary)', fontWeight: 600 }}>
          <Icon name="check" size={15} color="var(--primary)" /> Sisa kuota: {quota.remaining} dari {quota.limit} ({quota.period === 'week' ? 'minggu ini' : 'bulan ini'})
        </div>}

        <div>
          <Lbl>Kategori</Lbl>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8 }}>
            {LAPAK_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 6px', 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={20} color={c.color} /><span style={{ fontSize: 10.5, fontWeight: 700, color: on ? c.color : 'var(--text-2)' }}>{c.label}</span>
              </button>); })}
          </div>
        </div>

        <div>
          <Lbl>Foto <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(maks 4, opsional)</span></Lbl>
          <input ref={fileRef} type="file" accept="image/*" multiple onChange={onFiles} style={{ display: 'none' }} />
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {prev.map((src, i) => (
              <div key={i} style={{ position: 'relative', width: 72, height: 72, borderRadius: 'var(--r-md)', overflow: 'hidden', border: '1px solid var(--border)' }}>
                <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                <button onClick={() => rmPhoto(i)} style={{ position: 'absolute', top: 2, right: 2, width: 20, height: 20, borderRadius: '50%', border: 'none', background: 'rgba(15,23,42,0.7)', display: 'grid', placeItems: 'center', cursor: 'pointer' }}><Icon name="x" size={12} color="#fff" /></button>
              </div>
            ))}
            {files.length < 4 && <button onClick={() => fileRef.current && fileRef.current.click()} style={{ width: 72, height: 72, borderRadius: 'var(--r-md)', border: '2px dashed var(--border-strong)', background: 'var(--surface-2)', display: 'grid', placeItems: 'center', cursor: 'pointer' }}><Icon name="camera" size={22} color="var(--text-3)" /></button>}
          </div>
        </div>

        <div><Lbl>Judul</Lbl><Inp value={title} onChange={e => { setTitle(e.target.value); setErr(''); }} placeholder="cth. iPhone 13 128GB mulus" /></div>
        <div><Lbl>Harga <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(kosongkan = nego)</span></Lbl>
          <div style={{ position: 'relative' }}>
            <span style={{ position: 'absolute', left: 14, top: '50%', transform: 'translateY(-50%)', fontSize: 14, fontWeight: 700, color: 'var(--text-3)' }}>Rp</span>
            <input type="number" value={price} onChange={e => setPrice(e.target.value)} placeholder="0" style={{ ...inpStyle, paddingLeft: 40 }} />
          </div>
        </div>
        <div><Lbl>Deskripsi <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(opsional)</span></Lbl>
          <textarea value={body} maxLength={600} onChange={e => setBody(e.target.value)} rows={3} placeholder="Kondisi, alasan jual, dll..." style={{ ...inpStyle, resize: 'none', lineHeight: 1.5 }} /></div>
        <div><Lbl>Nomor WhatsApp</Lbl><Inp value={wa} onChange={e => { setWa(e.target.value); setErr(''); }} placeholder="08xxxxxxxxxx" type="tel" /></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={{ ...inpStyle, appearance: 'none' }}>
            <option value="">Pilih cluster</option>
            {clusters.map(cl => <option key={cl.id} value={cl.id}>{cl.name}</option>)}
          </select></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>}

        <button onClick={() => setView('upgrade')} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6, padding: 12, borderRadius: 'var(--r-md)', border: '1px dashed var(--border-strong)', background: 'transparent', color: 'var(--text-2)', fontSize: 12.5, fontWeight: 600, cursor: 'pointer', fontFamily: 'var(--font)' }}>
          Mau pasang lebih sering? Lihat paket berbayar
        </button>
      </div>
    </FlowShell>
  );
}

function LapakUpgrade({ quota, note, onClose }) {
  const [cfg, setCfg] = React.useState({});
  React.useEffect(() => { gsData.loadSettings().then(setCfg); }, []);
  const priceFor = (tier) => {
    if (tier === 2) return cfg.lapak_price_t2 != null ? cfg.lapak_price_t2 : 50000;
    if (tier === 3) return cfg.lapak_price_t3 != null ? cfg.lapak_price_t3 : 75000;
    if (tier === 4) return cfg.lapak_price_t4 != null ? cfg.lapak_price_t4 : 120000;
    return 0;
  };
  const pengurusWa = cfg.pengurus_wa ? waLink(cfg.pengurus_wa, 'Halo, saya mau upgrade paket Lapak di gs.town.') : null;
  return (
    <div style={{ padding: '8px 20px 30px' }}>
      {note && <p style={{ fontSize: 14, color: 'var(--text-2)', lineHeight: 1.5, marginBottom: 18 }}>{note}</p>}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        {LAPAK_TIERS.map(t => { const cur = quota && quota.tier === t.tier; return (
          <div key={t.tier} style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '16px 18px', borderRadius: 'var(--r-card)',
            border: '2px solid ' + (cur ? 'var(--primary)' : 'var(--border)'), background: cur ? 'var(--primary-soft)' : 'var(--surface)' }}>
            <div style={{ flex: 1 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <span style={{ fontSize: 15.5, fontWeight: 800, color: 'var(--text-1)' }}>{t.name}</span>
                {cur && <span style={{ fontSize: 10, fontWeight: 800, color: 'var(--primary)', background: 'var(--surface)', padding: '2px 8px', borderRadius: 999 }}>PAKET KAMU</span>}
              </div>
              <div style={{ fontSize: 12.5, color: 'var(--text-2)', marginTop: 3 }}>{t.quota} · {t.sub}</div>
            </div>
            <div style={{ textAlign: 'right' }}>
              <div style={{ fontSize: 16, fontWeight: 800, color: t.tier > 1 ? 'var(--cta)' : 'var(--lime-700)' }}>{t.tier > 1 ? 'Rp' + priceFor(t.tier).toLocaleString('id-ID') : 'Gratis'}</div>
              {t.tier > 1 && <div style={{ fontSize: 10.5, color: 'var(--text-3)' }}>/bulan</div>}
            </div>
          </div>
        ); })}
      </div>
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, marginTop: 16, padding: '12px 14px', borderRadius: 'var(--r-md)', background: 'var(--amber-50, #fffbeb)', fontSize: 12.5, color: 'var(--text-2)', lineHeight: 1.5 }}>
        <Icon name="bulb" size={16} color="var(--amber-700, #b45309)" />
        <span>Pembayaran online <b>segera hadir</b>. Untuk upgrade sekarang, hubungi pengurus.</span>
      </div>
      {pengurusWa
        ? <a href={pengurusWa} target="_blank" rel="noopener noreferrer" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 9, width: '100%', marginTop: 14, padding: 14, borderRadius: 'var(--r-chip)', background: 'var(--cta)', color: '#fff', fontWeight: 800, fontSize: 14.5, textDecoration: 'none', boxShadow: 'var(--sh-cta)' }}><Icon name="phone" size={18} color="#fff" /> Hubungi pengurus{cfg.pengurus_name ? ' · ' + cfg.pengurus_name : ''}</a>
        : null}
      <button onClick={onClose} style={{ width: '100%', marginTop: 10, padding: 14, borderRadius: 'var(--r-chip)', border: '1px solid var(--border)', background: 'var(--surface)', color: 'var(--text-2)', fontWeight: 700, fontSize: 14, cursor: 'pointer', fontFamily: 'var(--font)' }}>Tutup</button>
    </div>
  );
}

// ---- edit existing lapak (prefilled) ----
function LapakEditFlow({ item, clusters = [], onClose, onDone }) {
  const [cat, setCat] = React.useState(item.category || 'preloved');
  const [title, setTitle] = React.useState(item.title || '');
  const [price, setPrice] = React.useState(item.price == null ? '' : String(item.price));
  const [body, setBody] = React.useState(item.body || '');
  const [wa, setWa] = React.useState(item.contact_wa || '');
  const [clusterId, setClusterId] = React.useState(item.cluster_id || '');
  const [keep, setKeep] = React.useState(Array.isArray(item.photos) ? item.photos.slice() : []);
  const [files, setFiles] = React.useState([]);
  const [prev, setPrev] = React.useState([]);
  const [err, setErr] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const fileRef = React.useRef(null);

  const onFiles = (e) => {
    const room = 4 - keep.length - files.length;
    const fs = Array.from(e.target.files || []).slice(0, Math.max(0, room));
    if (!fs.length) return;
    setFiles(p => [...p, ...fs]);
    setPrev(p => [...p, ...fs.map(f => URL.createObjectURL(f))]);
  };
  const rmKeep = (i) => setKeep(p => p.filter((_, j) => j !== i));
  const rmNew = (i) => { setFiles(p => p.filter((_, j) => j !== i)); setPrev(p => p.filter((_, j) => j !== i)); };

  const submit = async () => {
    if (!title.trim()) return setErr('Judul lapak wajib diisi');
    if (!wa.trim()) return setErr('Nomor WhatsApp wajib diisi');
    setBusy(true); setErr('');
    const res = await gsData.updateLapak(item.id, { category: cat, title, price, body, contact_wa: wa, cluster_id: clusterId || null, files, keepPhotos: keep });
    setBusy(false);
    if (res.error) return setErr('Gagal: ' + res.error);
    onDone();
  };

  return (
    <FlowShell onClose={onClose} title="Edit Lapak"
      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', gap: 8 }}>
            {LAPAK_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 6px', 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={20} color={c.color} /><span style={{ fontSize: 10.5, fontWeight: 700, color: on ? c.color : 'var(--text-2)' }}>{c.label}</span>
              </button>); })}
          </div>
        </div>
        <div>
          <Lbl>Foto <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(maks 4)</span></Lbl>
          <input ref={fileRef} type="file" accept="image/*" multiple onChange={onFiles} style={{ display: 'none' }} />
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {keep.map((src, i) => (
              <div key={'k' + i} style={{ position: 'relative', width: 72, height: 72, borderRadius: 'var(--r-md)', overflow: 'hidden', border: '1px solid var(--border)' }}>
                <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                <button onClick={() => rmKeep(i)} style={{ position: 'absolute', top: 2, right: 2, width: 20, height: 20, borderRadius: '50%', border: 'none', background: 'rgba(15,23,42,0.7)', display: 'grid', placeItems: 'center', cursor: 'pointer' }}><Icon name="x" size={12} color="#fff" /></button>
              </div>
            ))}
            {prev.map((src, i) => (
              <div key={'n' + i} style={{ position: 'relative', width: 72, height: 72, borderRadius: 'var(--r-md)', overflow: 'hidden', border: '1px solid var(--border)' }}>
                <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                <button onClick={() => rmNew(i)} style={{ position: 'absolute', top: 2, right: 2, width: 20, height: 20, borderRadius: '50%', border: 'none', background: 'rgba(15,23,42,0.7)', display: 'grid', placeItems: 'center', cursor: 'pointer' }}><Icon name="x" size={12} color="#fff" /></button>
              </div>
            ))}
            {(keep.length + files.length) < 4 && <button onClick={() => fileRef.current && fileRef.current.click()} style={{ width: 72, height: 72, borderRadius: 'var(--r-md)', border: '2px dashed var(--border-strong)', background: 'var(--surface-2)', display: 'grid', placeItems: 'center', cursor: 'pointer' }}><Icon name="camera" size={22} color="var(--text-3)" /></button>}
          </div>
        </div>
        <div><Lbl>Judul</Lbl><Inp value={title} onChange={e => { setTitle(e.target.value); setErr(''); }} placeholder="cth. iPhone 13 128GB mulus" /></div>
        <div><Lbl>Harga <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>(kosongkan = nego)</span></Lbl>
          <div style={{ position: 'relative' }}>
            <span style={{ position: 'absolute', left: 14, top: '50%', transform: 'translateY(-50%)', fontSize: 14, fontWeight: 700, color: 'var(--text-3)' }}>Rp</span>
            <input type="number" value={price} onChange={e => setPrice(e.target.value)} placeholder="0" style={{ ...inpStyle, paddingLeft: 40 }} />
          </div>
        </div>
        <div><Lbl>Deskripsi</Lbl><textarea value={body} maxLength={600} onChange={e => setBody(e.target.value)} rows={3} placeholder="Kondisi, alasan jual, dll..." style={{ ...inpStyle, resize: 'none', lineHeight: 1.5 }} /></div>
        <div><Lbl>Nomor WhatsApp</Lbl><Inp value={wa} onChange={e => { setWa(e.target.value); setErr(''); }} placeholder="08xxxxxxxxxx" type="tel" /></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={{ ...inpStyle, appearance: 'none' }}>
            <option value="">Pilih cluster</option>
            {clusters.map(cl => <option key={cl.id} value={cl.id}>{cl.name}</option>)}
          </select></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>
  );
}

// ---- shared flow shell (fullscreen) ----
function FlowShell({ title, children, footer, onClose }) {
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--surface)' }}>
      <div style={{ paddingTop: SAFE_TOP, borderBottom: '1px solid var(--border)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '8px 16px 14px' }}>
          <button onClick={onClose} style={{ width: 36, height: 36, borderRadius: '50%', border: '1px solid var(--border)', background: 'var(--surface)', display: 'grid', placeItems: 'center', cursor: 'pointer' }}><Icon name="x" size={18} color="var(--text-2)" /></button>
          <h2 style={{ fontSize: 18, fontWeight: 800, color: 'var(--text-1)', letterSpacing: '-0.02em' }}>{title}</h2>
        </div>
      </div>
      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 20px 16px', scrollbarWidth: 'none' }}>{children}</div>
      {footer && <div style={{ padding: '14px 20px', paddingBottom: 'max(22px, env(safe-area-inset-bottom))', borderTop: '1px solid var(--border)' }}>{footer}</div>}
    </div>
  );
}

const inpStyle = { 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' };
function Lbl({ children }) { return <label style={{ display: 'block', fontSize: 12.5, fontWeight: 700, color: 'var(--text-2)', marginBottom: 7 }}>{children}</label>; }
function Inp(props) { return <input {...props} style={{ ...inpStyle, ...(props.style || {}) }} />; }

Object.assign(window, { LapakScreen, LapakPostFlow, LapakUpgrade, LapakDetailSheet, LapakEditFlow, LAPAK_CATS, LAPAK_TIERS, lapakRp, waLink });
