/* ════════════════════════════════════════════════
   Dashboard — modul Artikel & Pendaftar
   ════════════════════════════════════════════════ */
const ART_CATS = ['Tahfidz', 'Bahasa Arab', 'Fiqih', 'Akhlaq'];

/* WYSIWYG editor (contentEditable) — format langsung terlihat */
function Wysiwyg({ value, onChange }) {
  const ref = React.useRef();
  const [active, setActive] = React.useState({});
  React.useEffect(() => { if (ref.current && ref.current.innerHTML !== (value || '')) ref.current.innerHTML = value || ''; }, []);
  const sync = () => { if (ref.current) onChange(ref.current.innerHTML); };
  const exec = (cmd, val) => { document.execCommand('styleWithCSS', false, false); document.execCommand(cmd, false, val); ref.current && ref.current.focus(); sync(); refreshActive(); };
  const block = (tag) => exec('formatBlock', tag);
  const link = () => { const url = window.prompt('Masukkan URL tautan:', 'https://'); if (url) exec('createLink', url); };
  const arabicBlock = () => { exec('formatBlock', 'p'); const sel = document.getSelection(); let n = sel && sel.anchorNode; while (n && n.nodeName !== 'P' && n !== ref.current) n = n.parentNode; if (n && n.nodeName === 'P') { n.setAttribute('dir', 'rtl'); n.className = 'ar'; sync(); } };
  const hr = () => { exec('insertHTML', '<hr/>'); };
  const fileRef = React.useRef();
  const insertImage = async (e) => {
    const file = e.target.files[0]; e.target.value = ''; if (!file) return;
    const reader = new FileReader();
    reader.onload = async () => {
      let url = reader.result; // dataURL sementara
      ref.current && ref.current.focus();
      document.execCommand('insertHTML', false, `<img src="${url}" alt="" style="max-width:100%;border-radius:10px;margin:8px 0" /><p><br/></p>`);
      sync();
      // unggah ke server, ganti dataURL dgn URL asli
      try { const fd = new FormData(); fd.append('file', file); fd.append('_preview', url); const res = await api.post('upload.php', fd); const real = res.ok && (res.data?.url || res.url); if (real && ref.current) { ref.current.innerHTML = ref.current.innerHTML.replace(url, real); sync(); } } catch {}
    };
    reader.readAsDataURL(file);
  };
  const refreshActive = () => { try { setActive({ bold: document.queryCommandState('bold'), italic: document.queryCommandState('italic'), underline: document.queryCommandState('underline'), ul: document.queryCommandState('insertUnorderedList'), ol: document.queryCommandState('insertOrderedList') }); } catch {} };
  const btn = (label, on, st) => <button type="button" onMouseDown={(e) => { e.preventDefault(); on(); }} style={{ padding: '6px 11px', borderRadius: 7, border: '1px solid var(--border)', background: st ? 'var(--navy)' : 'var(--surface)', color: st ? '#fff' : 'var(--ink-deep)', fontSize: 13, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit', minWidth: 32 }}>{label}</button>;
  const selStyle = { padding: '6px 8px', borderRadius: 7, border: '1px solid var(--border)', background: 'var(--surface)', color: 'var(--ink-deep)', fontSize: 12.5, fontFamily: 'inherit', cursor: 'pointer' };
  const sep = () => <span style={{ width: 1, alignSelf: 'stretch', background: 'var(--border-soft)', margin: '0 2px' }} />;
  return (
    <div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 8, alignItems: 'center' }}>
        {btn(<b>B</b>, () => exec('bold'), active.bold)}
        {btn(<i>I</i>, () => exec('italic'), active.italic)}
        {btn(<span style={{ textDecoration: 'underline' }}>U</span>, () => exec('underline'), active.underline)}
        {sep()}
        {btn('H2', () => block('h2'))}
        {btn('H3', () => block('h3'))}
        {btn('¶', () => block('p'))}
        {sep()}
        {/* Jenis font */}
        <select onMouseDown={(e) => e.stopPropagation()} onChange={(e) => { if (e.target.value) exec('fontName', e.target.value); e.target.selectedIndex = 0; }} style={selStyle} defaultValue="">
          <option value="">Font</option>
          <option value="'Plus Jakarta Sans',sans-serif">Plus Jakarta</option>
          <option value="Fraunces,serif">Fraunces</option>
          <option value="Georgia,serif">Georgia</option>
          <option value="'Amiri',serif">Amiri (Arab)</option>
        </select>
        {/* Ukuran font */}
        <select onMouseDown={(e) => e.stopPropagation()} onChange={(e) => { if (e.target.value) exec('fontSize', e.target.value); e.target.selectedIndex = 0; }} style={selStyle} defaultValue="">
          <option value="">Ukuran</option>
          <option value="2">Kecil</option>
          <option value="3">Normal</option>
          <option value="5">Besar</option>
          <option value="6">Sangat Besar</option>
        </select>
        {/* Warna font */}
        <label style={{ display: 'inline-flex', alignItems: 'center', gap: 5, ...selStyle, cursor: 'pointer' }} title="Warna teks">
          <span style={{ fontWeight: 800 }}>A</span>
          <input type="color" defaultValue="#1B2F6E" onMouseDown={(e) => e.stopPropagation()} onInput={(e) => exec('foreColor', e.target.value)} style={{ width: 22, height: 20, border: 'none', background: 'none', padding: 0, cursor: 'pointer' }} />
        </label>
        {sep()}
        {/* Perataan */}
        {btn('⬅', () => exec('justifyLeft'))}
        {btn('⬌', () => exec('justifyCenter'))}
        {btn('➡', () => exec('justifyRight'))}
        {btn('☰', () => exec('justifyFull'))}
        {btn('⇤', () => exec('outdent'))}
        {btn('⇥', () => exec('indent'))}
        {sep()}
        {btn('• Poin', () => exec('insertUnorderedList'), active.ul)}
        {btn('1. Nomor', () => exec('insertOrderedList'), active.ol)}
        {btn('Kutipan', () => block('blockquote'))}
        {btn('Tautan', link)}
        {btn('Gambar', () => fileRef.current && fileRef.current.click())}
        {btn('﷽ Teks Arab', arabicBlock)}
        {btn('Garis', hr)}
        <label style={{ display: 'inline-flex', alignItems: 'center', gap: 5, ...selStyle, cursor: 'pointer' }} title="Warna sorot">
          <span style={{ fontWeight: 800, background: '#FCE96A', padding: '0 3px', borderRadius: 3 }}>H</span>
          <input type="color" defaultValue="#FCE96A" onMouseDown={(e) => e.stopPropagation()} onInput={(e) => exec('hiliteColor', e.target.value)} style={{ width: 22, height: 20, border: 'none', background: 'none', padding: 0, cursor: 'pointer' }} />
        </label>
        {btn('Hapus Format', () => exec('removeFormat'))}
      </div>
      <div ref={ref} contentEditable suppressContentEditableWarning onInput={sync} onKeyUp={refreshActive} onMouseUp={refreshActive}
        className="wysiwyg-area"
        style={{ minHeight: 240, padding: '14px 16px', borderRadius: 10, border: '1.5px solid var(--border)', background: 'var(--surface)', color: 'var(--ink-deep)', fontSize: 15, lineHeight: 1.7, outline: 'none', overflowY: 'auto' }} />
      <input ref={fileRef} type="file" accept="image/*" onChange={insertImage} style={{ display: 'none' }} />
      <div style={{ fontSize: 11.5, color: 'var(--muted)', marginTop: 6 }}>Ketik langsung — gunakan tombol di atas untuk memformat. Hasil tampil persis seperti di artikel.</div>
    </div>
  );
}

/* Toolbar format Markdown untuk textarea isi artikel */
function MdToolbar({ taRef, value, onChange }) {
  const wrap = (before, after, placeholder) => {
    const ta = taRef.current; if (!ta) return;
    const s = ta.selectionStart, e = ta.selectionEnd;
    const sel = value.slice(s, e) || placeholder;
    const next = value.slice(0, s) + before + sel + after + value.slice(e);
    onChange(next);
    setTimeout(() => { ta.focus(); ta.selectionStart = s + before.length; ta.selectionEnd = s + before.length + sel.length; }, 0);
  };
  const prefixLine = (prefix) => {
    const ta = taRef.current; if (!ta) return;
    const s = ta.selectionStart;
    const lineStart = value.lastIndexOf('\n', s - 1) + 1;
    const next = value.slice(0, lineStart) + prefix + value.slice(lineStart);
    onChange(next);
    setTimeout(() => { ta.focus(); ta.selectionStart = ta.selectionEnd = s + prefix.length; }, 0);
  };
  const btn = { padding: '6px 10px', borderRadius: 7, border: '1px solid var(--border)', background: 'var(--surface)', color: 'var(--ink-deep)', fontSize: 13, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit', minWidth: 32 };
  const tools = [
    ['B', () => wrap('**', '**', 'teks tebal'), { fontWeight: 900 }],
    ['I', () => wrap('*', '*', 'teks miring'), { fontStyle: 'italic' }],
    ['H2', () => prefixLine('## '), {}],
    ['H3', () => prefixLine('### '), {}],
    ['• Poin', () => prefixLine('- '), {}],
    ['1. Nomor', () => prefixLine('1. '), {}],
    ['❝ Kutipan', () => prefixLine('> '), {}],
    ['🔗 Tautan', () => wrap('[', '](https://)', 'teks tautan'), {}],
  ];
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 8 }}>
      {tools.map(([label, fn, st]) => (
        <button key={label} type="button" onClick={fn} style={{ ...btn, ...st }}>{label}</button>
      ))}
    </div>
  );
}

function ArticlesModule({ user, toast }) {
  const [articles, setArticles] = useState([]);
  const [loading, setLoading] = useState(true);
  const [modal, setModal] = useState(null); // null | {id?} form
  const [form, setForm] = useState({});
  const [saving, setSaving] = useState(false);
  const bodyRef = React.useRef();
  const [writers, setWriters] = useState([]);
  useEffect(() => { api.get('auth.php?action=users').then(r => { if (r.ok && r.users) setWriters(r.users); }); }, []);

  const load = () => {
    setLoading(true);
    const act = user.role === 'admin' ? 'all' : 'my';
    api.get('articles.php?action=' + act).then(r => {
      if (r.ok && r.articles) setArticles(r.articles);
    }).finally(() => setLoading(false));
  };
  useEffect(load, []);

  const openAdd = () => { setForm({ title: '', category: 'Tahfidz', excerpt: '', body: '', icon: '📖', status: 'published', cover_url: '', author_name: user.name }); setModal({}); };
  const openEdit = (a) => { setForm({ ...a }); setModal({ id: a.id }); };

  const save = async () => {
    if (!form.title) return;
    setSaving(true);
    const action = modal.id ? 'update' : 'create';
    const payload = modal.id ? { ...form, id: modal.id } : form;
    try {
      const r = await api.post('articles.php?action=' + action, payload);
      if (r.ok) { toast(modal.id ? '✅ Artikel diperbarui' : '✅ Artikel ditambahkan'); setModal(null); load(); }
      else toast('⚠️ ' + (r.error || 'Gagal menyimpan'));
    } finally { setSaving(false); }
  };

  const del = async (a) => {
    if (!window.confirm(`Hapus artikel "${a.title}"?`)) return;
    const r = await api.post('articles.php?action=delete', { id: a.id });
    if (r.ok) { toast('Artikel dihapus'); load(); } else toast('⚠️ Gagal menghapus');
  };

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 18, gap: 12, flexWrap: 'wrap' }}>
        <p style={{ color: 'var(--muted)', fontSize: 13.5, margin: 0 }}>Kelola seluruh artikel yang tampil di situs.</p>
        <DBtn variant="orange" onClick={openAdd}>+ Tulis Artikel</DBtn>
      </div>

      <DCard pad="0">
        {loading ? <div style={{ padding: 40, textAlign: 'center', color: 'var(--muted)' }}>Memuat…</div>
        : articles.length === 0 ? <div style={{ padding: 50, textAlign: 'center', color: 'var(--muted)' }}>Belum ada artikel. Klik "Tulis Artikel".</div>
        : <div style={{ padding: '8px 14px' }}>
            <DTable cols={['', 'Judul', 'Kategori', 'Status', 'Aksi']}>
              {articles.map(a => (
                <tr key={a.id}>
                  <DTd style={{ width: 56 }}>
                    <div style={{ width: 44, height: 44, borderRadius: 8, background: catStyle(a.category).color, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 20, overflow: 'hidden' }}>
                      {a.cover_url ? <img src={a.cover_url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} /> : <GlyphMark name={CAT_GLYPH[a.category] || 'scroll'} size={24} />}
                    </div>
                  </DTd>
                  <DTd><div style={{ fontWeight: 700, color: 'var(--ink-deep)' }}>{a.title}</div><div style={{ fontSize: 12, color: 'var(--muted)' }}>{a.author_name || a.author || user.name}</div></DTd>
                  <DTd><CatBadge cat={a.category} small /></DTd>
                  <DTd><Pill color={a.status === 'published' ? 'green' : 'gray'}>{a.status === 'published' ? 'Terbit' : 'Draf'}</Pill></DTd>
                  <DTd>
                    <div style={{ display: 'flex', gap: 6 }}>
                      <DBtn size="sm" onClick={() => openEdit(a)}>Edit</DBtn>
                      <DBtn size="sm" variant="danger" onClick={() => del(a)}>Hapus</DBtn>
                    </div>
                  </DTd>
                </tr>
              ))}
            </DTable>
          </div>}
      </DCard>

      <Modal open={!!modal} onClose={() => setModal(null)} title={modal && modal.id ? 'Edit Artikel' : 'Tulis Artikel Baru'} width="640px">
        {modal && (
          <>
            <ImageUpload label="Gambar Sampul" value={form.cover_url} onChange={v => setForm(f => ({ ...f, cover_url: v }))} />
            <DField label="Judul *"><input value={form.title} onChange={e => setForm(f => ({ ...f, title: e.target.value }))} style={dInp} placeholder="Judul artikel" /></DField>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <DField label="Kategori" hint="Ketik baru untuk membuat kategori"><input list="art-cat-list" value={form.category} onChange={e => setForm(f => ({ ...f, category: e.target.value }))} style={dInp} placeholder="mis. Tahfidz" /><datalist id="art-cat-list">{ART_CATS.map(c => <option key={c} value={c} />)}</datalist></DField>
              <DField label="Status"><select value={form.status} onChange={e => setForm(f => ({ ...f, status: e.target.value }))} style={dInp}><option value="published">Terbit</option><option value="draft">Draf</option></select></DField>
            </div>
              <DField label="Penulis" hint="Pilih siapa yang menulis artikel ini">
                <select value={form.author_id || ''} onChange={e => { const w = writers.find(x => String(x.id) === e.target.value); setForm(f => ({ ...f, author_id: e.target.value, author_name: w ? w.name : f.author_name })); }} style={dInp}>
                  <option value="">{form.author_name || '— Pilih penulis —'}</option>
                  {writers.map(w => <option key={w.id} value={w.id}>{w.name}{w.role === 'admin' ? ' (Admin)' : ''}</option>)}
                </select>
              </DField>
              <DField label="Jadikan Banner Beranda?" hint="Tampil di slideshow atas beranda">
                <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontSize: 14, color: 'var(--ink-deep)' }}>
                  <input type="checkbox" checked={!!form.banner_home} onChange={e => setForm(f => ({ ...f, banner_home: e.target.checked }))} style={{ width: 18, height: 18, accentColor: 'var(--sage)' }} />
                  {form.banner_home ? 'Ya, tampilkan di banner' : 'Tidak'}
                </label>
              </DField>
              <DField label="Artikel Unggulan?" hint="Tampil di slideshow unggulan halaman Artikel">
                <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontSize: 14, color: 'var(--ink-deep)' }}>
                  <input type="checkbox" checked={!!form.featured} onChange={e => setForm(f => ({ ...f, featured: e.target.checked }))} style={{ width: 18, height: 18, accentColor: 'var(--orange)' }} />
                  {form.featured ? 'Ya, jadikan unggulan' : 'Tidak'}
                </label>
              </DField>
            <DField label="Ringkasan" hint="Tampil di kartu artikel"><textarea value={form.excerpt} onChange={e => setForm(f => ({ ...f, excerpt: e.target.value }))} rows="2" style={{ ...dInp, resize: 'vertical' }} /></DField>
            <DField label="Isi Artikel" hint="Editor visual — format langsung terlihat">
              <Wysiwyg value={form.body || ''} onChange={(v) => setForm(f => ({ ...f, body: v }))} />
            </DField>
            <div style={{ display: 'flex', gap: 10, marginTop: 6 }}>
              <DBtn variant="orange" size="lg" onClick={save} disabled={saving || !form.title} style={{ flex: 1 }}>{saving ? 'Menyimpan…' : 'Simpan Artikel'}</DBtn>
              <DBtn size="lg" onClick={() => setModal(null)}>Batal</DBtn>
            </div>
          </>
        )}
      </Modal>
    </div>
  );
}

/* ── Pendaftar Santri ── */
function RegistrationsModule({ toast }) {
  const [regs, setRegs] = useState([]);
  const [loading, setLoading] = useState(true);
  const [filter, setFilter] = useState('semua');
  const statusMap = { baru: ['Baru', 'orange'], diproses: ['Diproses', 'blue'], selesai: ['Selesai', 'green'], dibatalkan: ['Batal', 'red'] };

  const load = () => { setLoading(true); api.get('registrations.php?action=list').then(r => { if (r.ok && r.registrations) setRegs(r.registrations); }).finally(() => setLoading(false)); };
  useEffect(load, []);

  const setStatus = async (reg, status) => {
    const prev = regs;
    setRegs(p => p.map(x => x.id === reg.id ? { ...x, status } : x));
    const r = await api.post('registrations.php?action=update_status', { id: reg.id, status });
    if (r.ok) toast('✅ Status diperbarui'); else { setRegs(prev); toast('⚠️ Gagal'); }
  };
  const del = async (reg) => {
    if (!window.confirm(`Hapus pendaftaran "${reg.name}"?`)) return;
    const r = await api.post('registrations.php?action=delete', { id: reg.id });
    if (r.ok) { toast('Dihapus'); load(); }
  };
  const wa = (reg) => window.open(`https://wa.me/62${(reg.phone || '').replace(/^0/, '')}?text=` + encodeURIComponent(`Assalamu'alaikum Bpk/Ibu ${reg.parent_name || ''}, terima kasih telah mendaftarkan ${reg.name} di Markaz Qurrota A'yun.`), '_blank');

  const filtered = filter === 'semua' ? regs : regs.filter(r => r.status === filter);
  const counts = regs.reduce((a, r) => { a[r.status] = (a[r.status] || 0) + 1; return a; }, {});

  return (
    <div>
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 16 }}>
        {['semua', 'baru', 'diproses', 'selesai'].map(f => (
          <button key={f} onClick={() => setFilter(f)} style={{ padding: '7px 14px', borderRadius: 999, fontSize: 12.5, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit', border: `1.5px solid ${filter === f ? 'var(--navy)' : 'var(--border)'}`, background: filter === f ? 'var(--navy)' : 'var(--surface)', color: filter === f ? '#fff' : 'var(--ink)', textTransform: 'capitalize' }}>
            {f}{f !== 'semua' && counts[f] ? ` (${counts[f]})` : ''}
          </button>
        ))}
      </div>
      <DCard pad="0">
        {loading ? <div style={{ padding: 40, textAlign: 'center', color: 'var(--muted)' }}>Memuat…</div>
        : filtered.length === 0 ? <div style={{ padding: 50, textAlign: 'center', color: 'var(--muted)' }}>Belum ada pendaftar{filter !== 'semua' ? ' dengan status ini' : ''}.</div>
        : <div style={{ padding: '8px 14px' }}>
            <DTable cols={['Santri', 'Program', 'Kontak', 'Status', 'Aksi']}>
              {filtered.map(r => (
                <tr key={r.id}>
                  <DTd><div style={{ fontWeight: 700, color: 'var(--ink-deep)' }}>{r.name}</div><div style={{ fontSize: 12, color: 'var(--muted)' }}>{r.usia} · {r.gender || '-'}</div></DTd>
                  <DTd><div>{r.program}</div>{r.level && <div style={{ fontSize: 12, color: 'var(--muted)' }}>{r.level}</div>}</DTd>
                  <DTd><div>{r.parent_name}</div><div style={{ fontSize: 12, color: 'var(--muted)' }}>{r.phone}</div></DTd>
                  <DTd><Pill color={(statusMap[r.status] || ['', 'gray'])[1]}>{(statusMap[r.status] || ['Baru'])[0]}</Pill></DTd>
                  <DTd>
                    <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                      <DBtn size="sm" variant="success" onClick={() => wa(r)}>💬</DBtn>
                      {r.status === 'baru' && <DBtn size="sm" variant="primary" onClick={() => setStatus(r, 'diproses')}>Proses</DBtn>}
                      {r.status === 'diproses' && <DBtn size="sm" variant="success" onClick={() => setStatus(r, 'selesai')}>Selesai</DBtn>}
                      <DBtn size="sm" variant="danger" onClick={() => del(r)}>Hapus</DBtn>
                    </div>
                  </DTd>
                </tr>
              ))}
            </DTable>
          </div>}
      </DCard>
    </div>
  );
}

Object.assign(window, { ArticlesModule, RegistrationsModule, ART_CATS });
