// cluster.jsx — Cluster hub (Izin Renovasi + Cluster OS stubs). Exported to window.

const PERMIT_STATUS = {
  diajukan:  { label: 'DIAJUKAN',  color: 'var(--s-500)',  soft: 'var(--s-100)' },
  ditinjau:  { label: 'DITINJAU',  color: 'var(--blue)',   soft: 'var(--blue-50)' },
  revisi:    { label: 'REVISI',    color: 'var(--amber)',  soft: 'var(--amber-50)' },
  disetujui: { label: 'DISETUJUI', color: 'var(--lime)',   soft: 'var(--lime-50)' },
  ditolak:   { label: 'DITOLAK',   color: 'var(--coral)',  soft: 'var(--coral-50)' },
  selesai:   { label: 'SELESAI',   color: 'var(--violet)', soft: 'var(--violet-50)' },
};
function PermitStatusChip({ status }) {
  const s = PERMIT_STATUS[status] || PERMIT_STATUS.diajukan;
  return (
    <span className="mono" style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '3px 9px', borderRadius: 'var(--r-chip)',
      background: s.soft, color: s.color, fontSize: 10.5, fontWeight: 700, letterSpacing: '0.06em', lineHeight: 1.2 }}>
      <span style={{ width: 5, height: 5, borderRadius: '50%', background: s.color }} /> {s.label}
    </span>
  );
}
const RENO_TYPES = [
  ['ringan', 'Ringan', 'Cat, perbaikan kecil'],
  ['sedang', 'Sedang', 'Tambah / ubah ruang'],
  ['berat', 'Berat', 'Struktur, tambah lantai'],
  ['bongkar_bangun', 'Bongkar Bangun', 'Bongkar total & bangun ulang'],
];
function fmtDate(d) { if (!d) return '-'; try { return new Date(d).toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric' }); } catch (e) { return d; } }
function fmtRp(n) { if (n == null) return '-'; return 'Rp' + Number(n).toLocaleString('id-ID'); }

const fieldStyle = { 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 Label({ children, opt }) {
  return <label style={{ display: 'block', fontSize: 12.5, fontWeight: 700, color: 'var(--text-2)', marginBottom: 7 }}>{children}{opt && <span style={{ color: 'var(--text-3)', fontWeight: 500 }}> (opsional)</span>}</label>;
}

function PermitFlow({ clusters = [], profile, onClose, onDone }) {
  const [clusterId, setClusterId] = React.useState(profile && profile.home_cluster_id ? profile.home_cluster_id : '');
  const [unit, setUnit] = React.useState('');
  const [addr, setAddr] = React.useState('');
  const [renoType, setRenoType] = React.useState('');
  const [startD, setStartD] = React.useState('');
  const [endD, setEndD] = React.useState('');
  const [cName, setCName] = React.useState('');
  const [cPhone, setCPhone] = React.useState('');
  const [workers, setWorkers] = React.useState('');
  const [desc, setDesc] = React.useState('');
  const [files, setFiles] = React.useState([]);
  const [err, setErr] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [sent, setSent] = React.useState(false);
  const fileRef = React.useRef(null);

  const onPick = (e) => {
    const list = Array.from(e.target.files || []);
    setFiles(f => f.concat(list));
    if (fileRef.current) fileRef.current.value = '';
  };
  const removeFile = (i) => setFiles(f => f.filter((_, j) => j !== i));

  const submit = async () => {
    setErr('');
    if (!clusterId) return setErr('Pilih cluster dulu');
    if (!renoType) return setErr('Pilih jenis renovasi');
    if (!startD) return setErr('Isi tanggal mulai');
    setBusy(true);
    const res = await gsData.submitPermit({
      cluster_id: clusterId, unit_number: unit.trim() || null, unit_address: addr.trim() || null,
      reno_type: renoType, description: desc.trim() || null, contractor_name: cName.trim() || null,
      contractor_phone: cPhone.trim() || null, worker_count: workers ? parseInt(workers, 10) : null,
      start_date: startD || null, end_date: endD || null, files,
    });
    setBusy(false);
    if (res.error) return setErr('Gagal mengirim: ' + res.error);
    setSent(true); setTimeout(onDone, 1500);
  };

  if (sent) {
    return (
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', background: 'var(--surface)', padding: 32, textAlign: 'center' }}>
        <div style={{ width: 84, height: 84, borderRadius: '50%', background: 'var(--lime-50)', display: 'grid', placeItems: 'center', marginBottom: 22 }}>
          <span style={{ width: 60, height: 60, borderRadius: '50%', background: 'var(--lime)', display: 'grid', placeItems: 'center' }}><Icon name="check" size={34} color="#fff" sw={2.6} /></span>
        </div>
        <h2 style={{ fontSize: 22, fontWeight: 800, color: 'var(--text-1)', marginBottom: 8 }}>Pengajuan terkirim!</h2>
        <p style={{ fontSize: 14.5, color: 'var(--text-2)', maxWidth: 280 }}>Estate manager akan meninjau pengajuan renovasimu. Pantau statusnya di halaman Cluster.</p>
      </div>
    );
  }

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--surface)' }}>
      <div style={{ paddingTop: SAFE_TOP, background: 'var(--surface)', borderBottom: '1px solid var(--border)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '6px 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', flexShrink: 0 }}>
            <Icon name="x" size={18} color="var(--text-2)" />
          </button>
          <h2 style={{ fontSize: 17, fontWeight: 800, color: 'var(--text-1)' }}>Ajukan Izin Renovasi</h2>
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '20px', scrollbarWidth: 'none', display: 'flex', flexDirection: 'column', gap: 18 }}>
        <div>
          <Label>Cluster</Label>
          <select value={clusterId} onChange={e => setClusterId(e.target.value)} style={{ ...fieldStyle, appearance: 'none', color: clusterId ? 'var(--text-1)' : 'var(--text-3)' }}>
            <option value="">Pilih cluster</option>
            {clusters.map(cl => <option key={cl.id} value={cl.id}>{cl.name}{cl.developer ? ' — ' + cl.developer : ''}</option>)}
          </select>
        </div>
        <div style={{ display: 'flex', gap: 12 }}>
          <div style={{ flex: 1 }}><Label opt>No. Unit / Rumah</Label><input value={unit} onChange={e => setUnit(e.target.value)} placeholder="cth. C12 No. 7" style={fieldStyle} /></div>
        </div>
        <div><Label opt>Alamat / patokan</Label><input value={addr} onChange={e => setAddr(e.target.value)} placeholder="Jalan / blok" style={fieldStyle} /></div>

        <div>
          <Label>Jenis renovasi</Label>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            {RENO_TYPES.map(([k, lbl, sub]) => {
              const on = renoType === k;
              return (
                <button key={k} onClick={() => { setRenoType(k); setErr(''); }} style={{ textAlign: 'left', padding: '12px 13px', borderRadius: 'var(--r-md)', cursor: 'pointer',
                  border: `2px solid ${on ? 'var(--primary)' : 'var(--border)'}`, background: on ? 'var(--primary-soft)' : 'var(--surface)', fontFamily: 'var(--font)' }}>
                  <div style={{ fontSize: 14, fontWeight: 800, color: on ? 'var(--primary)' : 'var(--text-1)' }}>{lbl}</div>
                  <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 2 }}>{sub}</div>
                </button>
              );
            })}
          </div>
        </div>

        <div style={{ display: 'flex', gap: 12 }}>
          <div style={{ flex: 1 }}><Label>Tanggal mulai</Label><input type="date" value={startD} onChange={e => setStartD(e.target.value)} style={fieldStyle} /></div>
          <div style={{ flex: 1 }}><Label opt>Selesai</Label><input type="date" value={endD} onChange={e => setEndD(e.target.value)} style={fieldStyle} /></div>
        </div>

        <div style={{ display: 'flex', gap: 12 }}>
          <div style={{ flex: 1.4 }}><Label opt>Kontraktor / tukang</Label><input value={cName} onChange={e => setCName(e.target.value)} placeholder="Nama" style={fieldStyle} /></div>
          <div style={{ flex: 1 }}><Label opt>Jml pekerja</Label><input type="number" inputMode="numeric" value={workers} onChange={e => setWorkers(e.target.value)} placeholder="0" style={fieldStyle} /></div>
        </div>
        <div><Label opt>No. HP kontraktor</Label><input value={cPhone} onChange={e => setCPhone(e.target.value)} placeholder="08xxxx" style={{ ...fieldStyle, fontFamily: 'var(--mono)' }} /></div>

        <div>
          <Label opt>Deskripsi pekerjaan</Label>
          <textarea value={desc} maxLength={400} onChange={e => setDesc(e.target.value)} rows={3} placeholder="Jelaskan ruang lingkup renovasi..." style={{ ...fieldStyle, resize: 'none', lineHeight: 1.5 }} />
        </div>

        <div>
          <Label opt>Dokumen (KTP, gambar kerja, dll)</Label>
          <input ref={fileRef} type="file" accept="image/*,application/pdf" multiple onChange={onPick} style={{ display: 'none' }} />
          <button onClick={() => fileRef.current && fileRef.current.click()} style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: '13px', borderRadius: 'var(--r-md)',
            border: '2px dashed var(--border-strong)', background: 'var(--surface-2)', cursor: 'pointer', color: 'var(--text-2)', fontFamily: 'var(--font)', fontWeight: 700, fontSize: 13.5 }}>
            <Icon name="camera" size={18} color="var(--primary)" /> Tambah dokumen
          </button>
          {files.length > 0 && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 7, marginTop: 10 }}>
              {files.map((f, i) => (
                <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '9px 12px', borderRadius: 'var(--r-md)', background: 'var(--surface-2)', border: '1px solid var(--border)' }}>
                  <Icon name="shield" size={15} color="var(--primary)" />
                  <span style={{ flex: 1, fontSize: 12.5, color: 'var(--text-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.name}</span>
                  <button onClick={() => removeFile(i)} style={{ border: 'none', background: 'none', cursor: 'pointer', padding: 0 }}><Icon name="x" size={15} color="var(--text-3)" /></button>
                </div>
              ))}
            </div>
          )}
        </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>

      <div style={{ padding: '14px 20px', paddingBottom: 'max(22px, env(safe-area-inset-bottom))', borderTop: '1px solid var(--border)', background: 'var(--surface)' }}>
        <button onClick={submit} disabled={busy} style={{ width: '100%', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: '15px', borderRadius: 'var(--r-chip)',
          border: 'none', cursor: busy ? 'default' : 'pointer', opacity: busy ? 0.7 : 1, background: 'var(--cta)', color: '#fff', fontFamily: 'var(--font)', fontWeight: 800, fontSize: 15, boxShadow: 'var(--sh-cta)' }}>
          {busy ? 'Mengirim...' : 'Kirim Pengajuan'} {!busy && <Icon name="arrow" size={18} color="#fff" sw={2.4} />}
        </button>
      </div>
    </div>
  );
}

function PermitDetailSheet({ permit, onClose }) {
  const approved = permit.status === 'disetujui' || permit.status === 'selesai';
  return (
    <Sheet onClose={onClose} height="88%">
      <div style={{ flex: 1, overflowY: 'auto', scrollbarWidth: 'none', padding: '14px 20px 20px', position: 'relative' }}>
        <button onClick={onClose} style={{ position: 'absolute', top: 6, right: 16, width: 34, height: 34, borderRadius: '50%', border: 'none', background: 'var(--surface-2)', display: 'grid', placeItems: 'center', cursor: 'pointer' }}>
          <Icon name="x" size={18} color="var(--text-1)" />
        </button>
        <div style={{ marginBottom: 12 }}><PermitStatusChip status={permit.status} /></div>
        <h2 style={{ fontSize: 20, fontWeight: 800, color: 'var(--text-1)', marginBottom: 4 }}>{permit.reno_label}</h2>
        <div style={{ fontSize: 13.5, color: 'var(--text-2)', marginBottom: 16 }}>{permit.cluster_name}{permit.unit_number ? ' · ' + permit.unit_number : ''}</div>

        {approved && permit.permit_number && (
          <div style={{ borderRadius: 'var(--r-card)', overflow: 'hidden', border: '1px solid var(--lime)', marginBottom: 18 }}>
            <div style={{ background: 'var(--lime-50)', padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 10 }}>
              <Icon name="check" size={18} color="var(--lime-700)" />
              <div>
                <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--lime-700)', letterSpacing: '0.04em' }}>SURAT IZIN RENOVASI</div>
                <div className="mono" style={{ fontSize: 16, fontWeight: 700, color: 'var(--text-1)' }}>{permit.permit_number}</div>
              </div>
            </div>
            <div style={{ padding: '12px 16px', fontSize: 13, color: 'var(--text-2)' }}>
              Berlaku {fmtDate(permit.start_date)} – {fmtDate(permit.end_date)}{permit.fee_amount ? ' · Biaya ' + fmtRp(permit.fee_amount) : ''}
            </div>
          </div>
        )}

        {(permit.status === 'revisi' || permit.status === 'ditolak') && permit.review_note && (
          <div style={{ display: 'flex', gap: 9, padding: '12px 14px', borderRadius: 'var(--r-md)', background: 'var(--amber-50)', marginBottom: 18 }}>
            <Icon name="shield" size={16} color="var(--amber-700)" style={{ marginTop: 1 }} />
            <div><div style={{ fontSize: 12, fontWeight: 700, color: 'var(--amber-700)' }}>Catatan estate manager</div><div style={{ fontSize: 13.5, color: 'var(--text-2)', lineHeight: 1.5 }}>{permit.review_note}</div></div>
          </div>
        )}

        <div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
          {[['Tanggal', fmtDate(permit.start_date) + ' – ' + fmtDate(permit.end_date)],
            ['Kontraktor', permit.contractor_name || '-'],
            ['No. HP', permit.contractor_phone || '-'],
            ['Pekerja', permit.worker_count != null ? String(permit.worker_count) + ' orang' : '-'],
            ['Dokumen', permit.doc_count + ' file'],
            ['Diajukan', permit.time]].map(([k, v]) => (
            <div key={k} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 0', borderBottom: '1px solid var(--border)' }}>
              <span style={{ fontSize: 13, color: 'var(--text-3)', width: 96 }}>{k}</span>
              <span style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--text-1)', flex: 1 }}>{v}</span>
            </div>
          ))}
        </div>
        {permit.description && <p style={{ fontSize: 14, color: 'var(--text-2)', lineHeight: 1.6, marginTop: 16 }}>{permit.description}</p>}
      </div>
    </Sheet>
  );
}

const MEMBER_STATUS = {
  pending:  { label: 'MENUNGGU VERIFIKASI', color: 'var(--amber-700)', soft: 'var(--amber-50)' },
  verified: { label: 'TERVERIFIKASI',       color: 'var(--lime-700)',  soft: 'var(--lime-50)' },
  rejected: { label: 'DITOLAK',             color: 'var(--coral-700)', soft: 'var(--coral-50)' },
};
function MemberStatusChip({ status }) {
  const s = MEMBER_STATUS[status] || MEMBER_STATUS.pending;
  return <span className="mono" style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '3px 9px', borderRadius: 'var(--r-chip)', background: s.soft, color: s.color, fontSize: 10.5, fontWeight: 700, letterSpacing: '0.05em' }}><span style={{ width: 5, height: 5, borderRadius: '50%', background: s.color }} /> {s.label}</span>;
}
const IPKL_STATUS = {
  unpaid:  { label: 'BELUM BAYAR', color: 'var(--coral-700)', soft: 'var(--coral-50)' },
  paid:    { label: 'LUNAS',       color: 'var(--lime-700)',  soft: 'var(--lime-50)' },
  overdue: { label: 'TERLAMBAT',   color: 'var(--coral-700)', soft: 'var(--coral-50)' },
};
function IpklStatusChip({ status }) {
  const s = IPKL_STATUS[status] || IPKL_STATUS.unpaid;
  return <span className="mono" style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '3px 9px', borderRadius: 'var(--r-chip)', background: s.soft, color: s.color, fontSize: 10.5, fontWeight: 700, letterSpacing: '0.05em' }}>{s.label}</span>;
}

function MembershipFlow({ clusters = [], profile, onClose, onDone }) {
  const [clusterId, setClusterId] = React.useState(profile && profile.home_cluster_id ? profile.home_cluster_id : '');
  const [unit, setUnit] = React.useState('');
  const [rt, setRt] = React.useState('');
  const [rw, setRw] = React.useState('');
  const [err, setErr] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [sent, setSent] = React.useState(false);
  const submit = async () => {
    setErr('');
    if (!clusterId) return setErr('Pilih cluster dulu');
    if (!unit.trim()) return setErr('Isi nomor unit / rumah');
    setBusy(true);
    const res = await gsData.submitMembership({ cluster_id: clusterId, unit: unit.trim(), rt: rt.trim(), rw: rw.trim() });
    setBusy(false);
    if (res.error) { if (/duplicate|unique/i.test(res.error)) return setErr('Kamu sudah pernah mengajukan untuk cluster ini.'); return setErr('Gagal: ' + res.error); }
    setSent(true); setTimeout(onDone, 1400);
  };
  if (sent) {
    return (
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', background: 'var(--surface)', padding: 32, textAlign: 'center' }}>
        <div style={{ width: 84, height: 84, borderRadius: '50%', background: 'var(--lime-50)', display: 'grid', placeItems: 'center', marginBottom: 22 }}>
          <span style={{ width: 60, height: 60, borderRadius: '50%', background: 'var(--lime)', display: 'grid', placeItems: 'center' }}><Icon name="check" size={34} color="#fff" sw={2.6} /></span>
        </div>
        <h2 style={{ fontSize: 22, fontWeight: 800, color: 'var(--text-1)', marginBottom: 8 }}>Pengajuan terkirim!</h2>
        <p style={{ fontSize: 14.5, color: 'var(--text-2)', maxWidth: 280 }}>Pengurus akan memverifikasi keanggotaanmu. Pantau statusnya di halaman Cluster.</p>
      </div>
    );
  }
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--surface)' }}>
      <div style={{ paddingTop: SAFE_TOP, background: 'var(--surface)', borderBottom: '1px solid var(--border)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '6px 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', flexShrink: 0 }}><Icon name="x" size={18} color="var(--text-2)" /></button>
          <h2 style={{ fontSize: 17, fontWeight: 800, color: 'var(--text-1)' }}>Daftar sebagai Warga</h2>
        </div>
      </div>
      <div style={{ flex: 1, overflowY: 'auto', padding: '20px', scrollbarWidth: 'none', display: 'flex', flexDirection: 'column', gap: 18 }}>
        <p style={{ fontSize: 13.5, color: 'var(--text-2)', lineHeight: 1.5, margin: 0 }}>Daftarkan unitmu untuk jadi warga terverifikasi cluster. Pengurus akan meninjau & menyetujui.</p>
        <div>
          <Label>Cluster</Label>
          <select value={clusterId} onChange={e => setClusterId(e.target.value)} style={{ ...fieldStyle, appearance: 'none', color: clusterId ? 'var(--text-1)' : 'var(--text-3)' }}>
            <option value="">Pilih cluster</option>
            {clusters.map(cl => <option key={cl.id} value={cl.id}>{cl.name}{cl.developer ? ' — ' + cl.developer : ''}</option>)}
          </select>
        </div>
        <div><Label>No. Unit / Rumah</Label><input value={unit} onChange={e => setUnit(e.target.value)} placeholder="cth. C12 No. 7" style={fieldStyle} /></div>
        <div style={{ display: 'flex', gap: 12 }}>
          <div style={{ flex: 1 }}><Label opt>RT</Label><input value={rt} onChange={e => setRt(e.target.value)} placeholder="00" style={{ ...fieldStyle, fontFamily: 'var(--mono)' }} /></div>
          <div style={{ flex: 1 }}><Label opt>RW</Label><input value={rw} onChange={e => setRw(e.target.value)} placeholder="00" style={{ ...fieldStyle, fontFamily: 'var(--mono)' }} /></div>
        </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>
      <div style={{ padding: '14px 20px', paddingBottom: 'max(22px, env(safe-area-inset-bottom))', borderTop: '1px solid var(--border)', background: 'var(--surface)' }}>
        <button onClick={submit} disabled={busy} style={{ width: '100%', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: '15px', borderRadius: 'var(--r-chip)', border: 'none', cursor: busy ? 'default' : 'pointer', opacity: busy ? 0.7 : 1, background: 'var(--cta)', color: '#fff', fontFamily: 'var(--font)', fontWeight: 800, fontSize: 15, boxShadow: 'var(--sh-cta)' }}>{busy ? 'Mengirim...' : 'Kirim Pendaftaran'} {!busy && <Icon name="arrow" size={18} color="#fff" sw={2.4} />}</button>
      </div>
    </div>
  );
}

function ClusterScreen({ authed, onRequireAuth, clusters = [], profile }) {
  const [permits, setPermits] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [flow, setFlow] = React.useState(false);
  const [detail, setDetail] = React.useState(null);
  const [anns, setAnns] = React.useState([]);
  const [memberships, setMemberships] = React.useState([]);
  const [ipkl, setIpkl] = React.useState([]);
  const [mFlow, setMFlow] = React.useState(false);
  React.useEffect(() => { gsData.loadAnnouncements().then(setAnns); }, []);

  const load = React.useCallback(() => {
    if (!authed) { setPermits([]); setMemberships([]); setIpkl([]); setLoading(false); return; }
    setLoading(true);
    gsData.loadMyPermits().then(p => { setPermits(p); setLoading(false); });
    gsData.loadMyMembership().then(setMemberships);
    gsData.loadMyIpkl().then(setIpkl);
  }, [authed]);
  React.useEffect(() => { load(); }, [load]);

  const myCluster = clusters.find(c => profile && c.id === profile.home_cluster_id);
  const startPermit = () => { if (!authed) return onRequireAuth(); setFlow(true); };
  const startMembership = () => { if (!authed) return onRequireAuth(); setMFlow(true); };
  const hasPending = memberships.some(m => m.status === 'pending');

  return (
    <div style={{ height: '100%', overflowY: 'auto', background: 'var(--bg)', scrollbarWidth: 'none' }}>
      <div style={{ paddingTop: SAFE_TOP, background: 'var(--surface)', borderBottom: '1px solid var(--border)', paddingBottom: 18 }}>
        <div style={{ padding: '8px 20px 0' }}>
          <h2 style={{ fontSize: 24, fontWeight: 800, letterSpacing: '-0.03em', color: 'var(--text-1)' }}>Cluster</h2>
        </div>
        <div style={{ margin: '14px 20px 0', padding: '14px 16px', borderRadius: 'var(--r-card)', background: 'var(--primary)', color: '#fff', display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ width: 42, height: 42, borderRadius: 'var(--r-md)', background: 'rgba(255,255,255,0.18)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name="shield" size={22} color="#fff" /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 11, fontWeight: 700, opacity: 0.85, letterSpacing: '0.04em' }}>CLUSTER SAYA</div>
            <div style={{ fontSize: 16, fontWeight: 800 }}>{myCluster ? myCluster.name : 'Gading Serpong'}</div>
          </div>
        </div>
      </div>

      {/* Izin Renovasi */}
      <div style={{ padding: '20px 20px 0' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
          <h3 style={{ fontSize: 16, fontWeight: 800, color: 'var(--text-1)' }}>Izin Renovasi</h3>
        </div>
        <button onClick={startPermit} style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '15px 16px', borderRadius: 'var(--r-card)', cursor: 'pointer',
          border: 'none', background: 'var(--cta)', color: '#fff', fontFamily: 'var(--font)', boxShadow: 'var(--sh-cta)', textAlign: 'left' }}>
          <span style={{ width: 40, height: 40, borderRadius: '50%', background: 'rgba(255,255,255,0.2)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name="plus" size={22} color="#fff" sw={2.6} /></span>
          <span style={{ flex: 1 }}>
            <span style={{ display: 'block', fontSize: 15, fontWeight: 800 }}>Ajukan Izin Renovasi</span>
            <span style={{ display: 'block', fontSize: 12.5, opacity: 0.9 }}>Tanpa surat — proses online via estate manager</span>
          </span>
          <Icon name="arrow" size={18} color="#fff" sw={2.4} />
        </button>

        <div style={{ marginTop: 18 }}>
          <h4 style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--text-2)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 10 }}>Pengajuan saya</h4>
          {!authed ? (
            <div style={{ padding: '22px 16px', textAlign: 'center', borderRadius: 'var(--r-card)', background: 'var(--surface-2)', border: '1px dashed var(--border-strong)', fontSize: 13.5, color: 'var(--text-2)' }}>Masuk untuk mengajukan & memantau izin renovasi.</div>
          ) : loading ? (
            <div style={{ padding: '22px 16px', textAlign: 'center', color: 'var(--text-3)', fontSize: 13.5 }}>Memuat...</div>
          ) : permits.length === 0 ? (
            <div style={{ padding: '22px 16px', textAlign: 'center', borderRadius: 'var(--r-card)', background: 'var(--surface-2)', border: '1px dashed var(--border-strong)', fontSize: 13.5, color: 'var(--text-2)' }}>Belum ada pengajuan.</div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
              {permits.map(p => (
                <button key={p.id} onClick={() => setDetail(p)} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 14, textAlign: 'left', cursor: 'pointer',
                  background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-card)', boxShadow: 'var(--sh-1)', fontFamily: 'var(--font)' }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 5 }}>
                      <span style={{ fontSize: 14.5, fontWeight: 800, color: 'var(--text-1)' }}>{p.reno_label}</span>
                      <PermitStatusChip status={p.status} />
                    </div>
                    <div style={{ fontSize: 12.5, color: 'var(--text-2)' }}>{p.cluster_name} · {fmtDate(p.start_date)}{p.permit_number ? ' · ' : ''}<span className="mono">{p.permit_number || ''}</span></div>
                  </div>
                  <Icon name="chevR" size={18} color="var(--text-3)" />
                </button>
              ))}
            </div>
          )}
        </div>
      </div>

      {/* Pengumuman */}
      {anns.length > 0 && (
        <div style={{ padding: '22px 20px 0' }}>
          <h4 style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--text-2)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 10 }}>Pengumuman</h4>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
            {anns.map(a => (
              <div key={a.id} style={{ padding: '14px 16px', borderRadius: 'var(--r-card)', background: 'var(--surface)', border: '1px solid var(--border)', boxShadow: 'var(--sh-1)' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 7, marginBottom: 5 }}>
                  {a.pinned && <Icon name="pin" size={14} color="var(--cta)" />}
                  <span style={{ fontSize: 14, fontWeight: 800, color: 'var(--text-1)' }}>{a.title}</span>
                </div>
                {a.body && <p style={{ fontSize: 13, color: 'var(--text-2)', lineHeight: 1.5, marginBottom: 7 }}>{a.body}</p>}
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 11.5, color: 'var(--text-3)' }}>
                  <span style={{ padding: '2px 8px', borderRadius: 'var(--r-chip)', background: 'var(--blue-50)', color: 'var(--primary)', fontWeight: 700 }}>{a.cluster || 'Semua'}</span>
                  <span className="mono">{a.time}</span>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Keanggotaan warga */}
      <div style={{ padding: '22px 20px 0' }}>
        <h4 style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--text-2)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 10 }}>Keanggotaan warga</h4>
        {!authed ? (
          <div style={{ padding: '22px 16px', textAlign: 'center', borderRadius: 'var(--r-card)', background: 'var(--surface-2)', border: '1px dashed var(--border-strong)', fontSize: 13.5, color: 'var(--text-2)' }}>Masuk untuk mendaftar sebagai warga cluster.</div>
        ) : memberships.length === 0 ? (
          <button onClick={startMembership} style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '15px 16px', borderRadius: 'var(--r-card)', cursor: 'pointer', border: '1px solid var(--border)', background: 'var(--surface)', boxShadow: 'var(--sh-1)', fontFamily: 'var(--font)', textAlign: 'left' }}>
            <span style={{ width: 40, height: 40, borderRadius: '50%', background: 'var(--primary-soft)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name="user" size={20} color="var(--primary)" /></span>
            <span style={{ flex: 1 }}><span style={{ display: 'block', fontSize: 14.5, fontWeight: 800, color: 'var(--text-1)' }}>Daftar sebagai warga cluster</span><span style={{ display: 'block', fontSize: 12.5, color: 'var(--text-3)' }}>Verifikasi unit untuk jadi warga resmi</span></span>
            <Icon name="arrow" size={18} color="var(--text-3)" sw={2.4} />
          </button>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
            {memberships.map(m => (
              <div key={m.id} style={{ padding: 14, background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-card)', boxShadow: 'var(--sh-1)' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                  <span style={{ fontSize: 14.5, fontWeight: 800, color: 'var(--text-1)' }}>{m.cluster_name}</span>
                  <MemberStatusChip status={m.status} />
                </div>
                <div style={{ fontSize: 12.5, color: 'var(--text-2)' }}>Unit {m.unit}{m.rt || m.rw ? ' · RT ' + (m.rt || '-') + ' / RW ' + (m.rw || '-') : ''}</div>
              </div>
            ))}
            {!hasPending && (
              <button onClick={startMembership} style={{ alignSelf: 'flex-start', display: 'inline-flex', alignItems: 'center', gap: 6, padding: '8px 14px', borderRadius: 'var(--r-chip)', border: '1px solid var(--border)', background: 'var(--surface)', cursor: 'pointer', fontFamily: 'var(--font)', fontSize: 12.5, fontWeight: 700, color: 'var(--primary)' }}><Icon name="plus" size={14} color="var(--primary)" sw={2.4} /> Ajukan cluster lain</button>
            )}
          </div>
        )}
      </div>

      {/* Tagihan IPKL */}
      <div style={{ padding: '22px 20px 0' }}>
        <h4 style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--text-2)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 10 }}>Tagihan IPKL</h4>
        {!authed ? (
          <div style={{ padding: '22px 16px', textAlign: 'center', borderRadius: 'var(--r-card)', background: 'var(--surface-2)', border: '1px dashed var(--border-strong)', fontSize: 13.5, color: 'var(--text-2)' }}>Masuk untuk melihat tagihan IPKL.</div>
        ) : ipkl.length === 0 ? (
          <div style={{ padding: '22px 16px', textAlign: 'center', borderRadius: 'var(--r-card)', background: 'var(--surface-2)', border: '1px dashed var(--border-strong)', fontSize: 13.5, color: 'var(--text-2)' }}>Belum ada tagihan.</div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {ipkl.map(b => (
              <div key={b.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px', borderRadius: 'var(--r-card)', background: 'var(--surface)', border: '1px solid var(--border)', boxShadow: 'var(--sh-1)' }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 14.5, fontWeight: 800, color: 'var(--text-1)' }}>{fmtRp(b.amount)}</div>
                  <div style={{ fontSize: 12, color: 'var(--text-3)', marginTop: 1 }}>{b.period}{b.cluster ? ' · ' + b.cluster : ''}{b.due ? ' · jatuh tempo ' + fmtDate(b.due) : ''}</div>
                </div>
                <IpklStatusChip status={b.status} />
              </div>
            ))}
          </div>
        )}
        <p style={{ fontSize: 11.5, color: 'var(--text-3)', marginTop: 10, lineHeight: 1.5 }}>Pembayaran langsung ke pengurus/pengelola. Aplikasi hanya membantu memantau status tagihan.</p>
      </div>

      <div style={{ height: 110 }} />

      {flow && (
        <div style={{ position: 'absolute', inset: 0, zIndex: 88, animation: 'gsFade 160ms var(--ease)' }}>
          <PermitFlow clusters={clusters} profile={profile} onClose={() => setFlow(false)} onDone={() => { setFlow(false); load(); }} />
        </div>
      )}
      {mFlow && (
        <div style={{ position: 'absolute', inset: 0, zIndex: 88, animation: 'gsFade 160ms var(--ease)' }}>
          <MembershipFlow clusters={clusters} profile={profile} onClose={() => setMFlow(false)} onDone={() => { setMFlow(false); load(); }} />
        </div>
      )}
      {detail && <PermitDetailSheet permit={detail} onClose={() => setDetail(null)} />}
    </div>
  );
}

Object.assign(window, { ClusterScreen, PermitFlow, PermitDetailSheet, PermitStatusChip, MembershipFlow });
