(function() {
  const { useState, useEffect, useRef, useCallback } = React;

  // สวิตช์ เปิด/ปิด เผยแพร่บทความ (published=เผยแพร่ · draft=ซ่อน) ในตารางหน้ารวม
  function ArticleToggle({ row, reload }) {
    const [status, setStatus] = useState(row.status);
    const [busy, setBusy] = useState(false);
    const on = status === 'published';
    async function toggle() {
      setBusy(true);
      try {
        if (on) { await window.api.unpublishArticle(row.id); setStatus('draft'); }
        else { await window.api.publishArticle(row.id); setStatus('published'); }
      } catch {}
      setBusy(false);
      if (reload) reload();
    }
    return (
      <button onClick={toggle} disabled={busy} title={on ? 'กำลังแสดงบนเว็บ — คลิกเพื่อซ่อน' : 'ซ่อนอยู่ — คลิกเพื่อแสดง'}
        style={{display:'inline-flex',alignItems:'center',gap:8,border:'none',background:'none',cursor:busy?'wait':'pointer',padding:0,fontFamily:'inherit',opacity:busy?.6:1}}>
        <span style={{width:38,height:22,borderRadius:99,background:on?'#15976A':'#CBD5E1',position:'relative',transition:'background .15s',flexShrink:0}}>
          <span style={{position:'absolute',top:2,left:on?18:2,width:18,height:18,borderRadius:'50%',background:'#fff',transition:'left .15s',boxShadow:'0 1px 3px rgba(0,0,0,.25)'}} />
        </span>
        <span style={{fontSize:12.5,fontWeight:600,color:on?'#15976A':'#64748B'}}>{on ? 'แสดง' : 'ซ่อน'}</span>
      </button>
    );
  }

  // ======= Quill Rich Text Editor Component =======
  function RichEditor({ value, onChange, placeholder }) {
    const editorRef = useRef(null);
    const quillRef = useRef(null);
    const isReady = useRef(false);
    const openTableRef = useRef(null);
    const [tbl, setTbl] = useState(null); // modal ตาราง: { data:[[..]], editIndex:null|number }

    // เปิด modal ตาราง (แทรกใหม่ หรือแก้ของเดิม)
    openTableRef.current = (data, editIndex) => {
      setTbl({
        data: data || [['หัวข้อ 1', 'หัวข้อ 2', 'หัวข้อ 3'], ['', '', ''], ['', '', '']],
        editIndex: (editIndex == null ? null : editIndex),
      });
    };

    useEffect(() => {
      if (!editorRef.current || quillRef.current) return;

      // ลงทะเบียน blot ตาราง (ครั้งเดียว) — ให้ Quill เก็บ <table> ไว้ ไม่ตัดทิ้งตอนเซฟ
      if (!window.__pfTableBlot) {
        const BlockEmbed = Quill.import('blots/block/embed');
        class TableBlot extends BlockEmbed {
          static create(html) { const node = super.create(); node.setAttribute('class', 'pf-table'); node.innerHTML = html || ''; return node; }
          static value(node) { return node.innerHTML; }
        }
        TableBlot.blotName = 'pftable';
        TableBlot.tagName = 'table';
        TableBlot.className = 'pf-table';
        Quill.register(TableBlot, true);
        window.__pfTableBlot = true;
      }

      quillRef.current = new Quill(editorRef.current, {
        theme: 'snow',
        placeholder: placeholder || 'เขียนเนื้อหาที่นี่...',
        modules: {
          toolbar: {
            container: [
              // แถว 1: หัวข้อ + ฟอนต์
              [{ 'header': [1, 2, 3, 4, false] }],
              [{ 'font': [] }],
              [{ 'size': ['small', false, 'large', 'huge'] }],

              // แถว 2: ตัวหนา เอียง ขีดเส้นใต้ ขีดฆ่า
              ['bold', 'italic', 'underline', 'strike'],

              // แถว 3: สี
              [{ 'color': [] }, { 'background': [] }],

              // แถว 4: จัดตำแหน่ง
              [{ 'align': [] }],
              [{ 'indent': '-1' }, { 'indent': '+1' }],
              [{ 'direction': 'rtl' }],

              // แถว 5: รายการ
              [{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'list': 'check' }],

              // แถว 6: script
              [{ 'script': 'sub' }, { 'script': 'super' }],

              // แถว 7: block
              ['blockquote', 'code-block'],

              // แถว 8: media + link + ตาราง
              ['link', 'image', 'video'],
              ['table'],

              // แถว 9: ล้าง format
              ['clean'],
            ],
            handlers: {
              image: function() {
                const input = document.createElement('input');
                input.setAttribute('type', 'file');
                input.setAttribute('accept', 'image/*');
                input.click();
                input.onchange = async () => {
                  const file = input.files?.[0];
                  if (!file) return;
                  // Upload รูปไป GCS
                  try {
                    const token = await window.firebaseAuth.currentUser?.getIdToken();
                    const fd = new FormData();
                    fd.append('file', file);
                    const res = await fetch(window.ADMIN_CONFIG.apiUrl + '/admin/articles/upload-image', {
                      method: 'POST', headers: { Authorization: 'Bearer ' + token }, body: fd,
                    });
                    const data = await res.json();
                    if (data.url) {
                      const range = quillRef.current.getSelection(true);
                      quillRef.current.insertEmbed(range.index, 'image', data.url);
                    } else {
                      // Fallback: ใช้ URL prompt
                      const url = prompt('ใส่ URL รูปภาพ:');
                      if (url) {
                        const range = quillRef.current.getSelection(true);
                        quillRef.current.insertEmbed(range.index, 'image', url);
                      }
                    }
                  } catch {
                    const url = prompt('ใส่ URL รูปภาพ:');
                    if (url) {
                      const range = quillRef.current.getSelection(true);
                      quillRef.current.insertEmbed(range.index, 'image', url);
                    }
                  }
                };
              },
              table: function() { if (openTableRef.current) openTableRef.current(); }
            }
          }
        }
      });

      // ใส่ไอคอนปุ่มตาราง + tooltip
      try {
        const tbBtn = quillRef.current.getModule('toolbar').container.querySelector('.ql-table');
        if (tbBtn) {
          tbBtn.innerHTML = '<svg viewBox="0 0 18 18" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"><rect x="2.5" y="3.5" width="13" height="11" rx="1"/><path d="M2.5 8h13M2.5 11.3h13M7 3.5v11M11.3 3.5v11"/></svg>';
          tbBtn.title = 'แทรกตาราง';
        }
      } catch (e) {}

      // คลิกตารางที่มีอยู่ = เปิด modal แก้ไข
      quillRef.current.root.addEventListener('click', (e) => {
        const tEl = e.target.closest && e.target.closest('table.pf-table');
        if (!tEl) return;
        e.preventDefault();
        const data = Array.from(tEl.querySelectorAll('tr')).map(tr =>
          Array.from(tr.querySelectorAll('th,td')).map(c => c.textContent));
        let editIndex = null;
        try { const blot = Quill.find(tEl); if (blot) editIndex = quillRef.current.getIndex(blot); } catch (e2) {}
        if (data.length && openTableRef.current) openTableRef.current(data, editIndex);
      });

      // Set initial value
      if (value) quillRef.current.root.innerHTML = value;
      isReady.current = true;

      // On change
      quillRef.current.on('text-change', () => {
        if (onChange && isReady.current) {
          onChange(quillRef.current.root.innerHTML);
        }
      });
    }, []);

    // Update content from outside (when loading article)
    useEffect(() => {
      if (quillRef.current && isReady.current) {
        const current = quillRef.current.root.innerHTML;
        if (value !== current && value !== undefined) {
          isReady.current = false;
          quillRef.current.root.innerHTML = value || '';
          isReady.current = true;
        }
      }
    }, [value]);

    // สร้าง HTML ตารางจากข้อมูล (แถวแรก = หัวตาราง)
    function buildTable(data) {
      const esc = (s) => String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
      const head = data[0] || [];
      const body = data.slice(1);
      const thead = '<thead><tr>' + head.map(c => '<th>' + esc(c) + '</th>').join('') + '</tr></thead>';
      const tbody = '<tbody>' + body.map(r => '<tr>' + r.map(c => '<td>' + esc(c) + '</td>').join('') + '</tr>').join('') + '</tbody>';
      return thead + tbody;
    }
    function applyTable() {
      const q = quillRef.current; if (!q || !tbl) return;
      const html = buildTable(tbl.data);
      let index;
      if (tbl.editIndex != null) { q.deleteText(tbl.editIndex, 1, 'user'); index = tbl.editIndex; }
      else { const r = q.getSelection(true); index = r ? r.index : q.getLength(); }
      q.insertEmbed(index, 'pftable', html, 'user');
      q.insertText(index + 1, '\n', 'user');
      q.setSelection(index + 2, 0);
      if (onChange) onChange(q.root.innerHTML);
      setTbl(null);
    }
    function resizeTable(rows, cols) {
      setTbl(t => {
        const data = [];
        for (let r = 0; r < rows; r++) { const row = []; for (let c = 0; c < cols; c++) row.push((t.data[r] && t.data[r][c]) || ''); data.push(row); }
        return { ...t, data };
      });
    }
    function setCell(r, c, v) { setTbl(t => { const data = t.data.map(row => row.slice()); data[r][c] = v; return { ...t, data }; }); }

    return (
      <>
        <div ref={editorRef} />
        {tbl && (
          <div onClick={() => setTbl(null)} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.45)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
            <div onClick={e => e.stopPropagation()} style={{ background: '#fff', borderRadius: 12, padding: 20, width: 'min(92vw,720px)', maxHeight: '88vh', overflow: 'auto', boxShadow: '0 18px 50px rgba(0,0,0,.25)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
                <h3 style={{ fontSize: 17, fontWeight: 700 }}>{tbl.editIndex != null ? 'แก้ไขตาราง' : 'แทรกตาราง'}</h3>
                <button className="btn btn-sm" onClick={() => setTbl(null)}>ปิด</button>
              </div>
              <div style={{ display: 'flex', gap: 16, alignItems: 'center', marginBottom: 14, flexWrap: 'wrap' }}>
                <label style={{ fontSize: 13 }}>แถว <input type="number" min="1" max="20" value={tbl.data.length} onChange={e => resizeTable(Math.max(1, Math.min(20, parseInt(e.target.value) || 1)), tbl.data[0].length)} style={{ width: 64, marginLeft: 6 }} /></label>
                <label style={{ fontSize: 13 }}>คอลัมน์ <input type="number" min="1" max="8" value={tbl.data[0].length} onChange={e => resizeTable(tbl.data.length, Math.max(1, Math.min(8, parseInt(e.target.value) || 1)))} style={{ width: 64, marginLeft: 6 }} /></label>
                <span style={{ fontSize: 12, color: '#888' }}>แถวแรก = หัวตาราง</span>
              </div>
              <div style={{ overflowX: 'auto' }}>
                <table style={{ borderCollapse: 'collapse', width: '100%' }}>
                  <tbody>
                    {tbl.data.map((row, r) => (
                      <tr key={r}>
                        {row.map((cell, c) => (
                          <td key={c} style={{ border: '1px solid #E2E6EC', padding: 2 }}>
                            <input value={cell} onChange={e => setCell(r, c, e.target.value)} placeholder={r === 0 ? 'หัวข้อ' : 'ข้อมูล'} style={{ width: '100%', minWidth: 90, border: 'none', padding: '7px 8px', fontWeight: r === 0 ? 700 : 400, background: r === 0 ? '#F6F8FB' : '#fff' }} />
                          </td>
                        ))}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
              <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10, marginTop: 16 }}>
                <button className="btn" onClick={() => setTbl(null)}>ยกเลิก</button>
                <button className="btn btn-primary" onClick={applyTable}>{tbl.editIndex != null ? 'บันทึกตาราง' : 'แทรกตาราง'}</button>
              </div>
            </div>
          </div>
        )}
      </>
    );
  }

  // ======= Articles Page =======
  function ArticlesPage({ navigate, route, t }) {
    const [articles, setArticles] = useState([]);
    const [categories, setCategories] = useState([]);
    const [loading, setLoading] = useState(true);
    const editor = route?.action === 'new' ? 'new' : (route?.action === 'edit' && route?.id ? route.id : null);
    function setEditor(v) { if(v === null) navigate('articles'); else if(v === 'new') navigate('articles','new'); else navigate('articles','edit',v); }
    const [form, setForm] = useState({ title: '', content: '', category_id: '', meta_title: '', meta_description: '', status: 'draft', thumbnail_url: '' });
    // autosave ร่างลง server อัตโนมัติ — สร้างเป็น draft ก่อน (ไม่เผยแพร่) แล้วสลับไปโหมดแก้ไข id เดิม
    const acRef = useRef(null); // id ที่ autosave สร้าง/กำลังแก้ (กันสร้าง draft ซ้ำ + กันเผลอแก้ผิดบทความ)
    const autosave = window.useServerAutosave({
      form,
      enabled: editor !== null && !!String(form.title || '').trim(),
      persist: async (f) => {
        if (!String(f.title || '').trim()) return false;
        const id = (editor !== 'new' ? editor : null) || (acRef.current && acRef.current !== 'creating' ? acRef.current : null);
        if (id) { await window.api.updateArticle(id, { ...f, autosave: true }); return true; }
        if (acRef.current === 'creating') return false;   // กำลังสร้างอยู่ → ไม่สร้างซ้ำ
        acRef.current = 'creating';
        const d = await window.api.createArticle({ ...f, status: 'draft', autosave: true });
        if (d && d.article && d.article.id) { acRef.current = d.article.id; setEditor(d.article.id); return true; }
        acRef.current = null;
        return false;
      },
    });
    const thumbRef = useRef(null);
    const [thumbBusy, setThumbBusy] = useState(false);
    async function uploadThumb(e) {
      const file = e.target.files && e.target.files[0];
      if (!file || editor === 'new') return;
      setThumbBusy(true);
      try {
        const token = await window.firebaseAuth.currentUser?.getIdToken();
        const fd = new FormData(); fd.append('file', file);
        const res = await fetch(window.ADMIN_CONFIG.apiUrl + '/admin/articles/' + editor + '/thumbnail', {
          method: 'POST', headers: { Authorization: 'Bearer ' + token }, body: fd,
        });
        const data = await res.json();
        if (data.url) setForm(f => ({ ...f, thumbnail_url: data.url }));
        else alert('อัปโหลดไม่สำเร็จ' + (data.error ? ': ' + data.error : ''));
      } catch (err) { alert('อัปโหลดไม่สำเร็จ'); }
      setThumbBusy(false);
      if (thumbRef.current) thumbRef.current.value = '';
    }

    function load() {
      setLoading(true);
      Promise.all([window.api.articles(), window.api.articleCategories()])
        .then(([a, c]) => { setArticles(a.articles || []); setCategories(c.categories || []); setLoading(false); })
        .catch(() => setLoading(false));
    }
    useEffect(load, []);
    const ts = window.useTableSort(articles, 'published_at', 'desc'); // เรียก hook ก่อน early-return ของ editor

    function openNew() {
      acRef.current = null; // เริ่มบทความใหม่ → ล้าง id เดิมกัน autosave ไปแก้บทความก่อนหน้า
      setForm({ title: '', content: '', category_id: '', meta_title: '', meta_description: '', status: 'draft', thumbnail_url: '' });
      setEditor('new');
    }
    function openEdit(a) {
      // Load full article
      window.api.get('/admin/articles/' + a.id)
        .then(d => {
          const fm = {
            title: (d.article && d.article.title) || '',
            content: (d.article && d.article.content) || '',
            category_id: (d.article && d.article.category_id) || '',
            meta_title: (d.article && d.article.meta_title) || '',
            meta_description: (d.article && d.article.meta_description) || '',
            status: (d.article && d.article.status) || 'draft',
            thumbnail_url: (d.article && d.article.thumbnail_url) || '',
          };
          acRef.current = a.id;        // แก้บทความนี้ (ไม่สร้างใหม่)
          setForm(fm);
          autosave.markBaseline(fm);   // ตั้งค่าตั้งต้น = ข้อมูลที่เพิ่งโหลด → กัน autosave หลอกตอนเปิด
          setEditor(a.id);
        });
    }

    async function save() {
      if (editor === 'new') await window.api.createArticle(form);
      else await window.api.updateArticle(editor, form);
      acRef.current = null;
      setEditor(null); load();
    }
    async function publish(id) { await window.api.publishArticle(id); load(); }
    async function unpublish(id) { await window.api.unpublishArticle(id); load(); }
    async function del(id) { if (window.confirm('ลบบทความนี้?')) { await window.api.deleteArticle(id); load(); } }

    // ======= Editor View =======
    if (editor !== null) return (
      <div className="page">
        <div className="page-header">
          <div className="row gap-10">
            <button className="btn btn-ghost btn-sm" onClick={() => setEditor(null)}>← กลับ</button>
            <h1>{editor === 'new' ? 'เขียนบทความใหม่' : 'แก้ไขบทความ'}</h1>
          </div>
          <div className="row gap-10" style={{alignItems:'center'}}>
            <window.AutosaveStatus state={autosave} />
            <button className="btn btn-primary" onClick={save}><i className="ph ph-floppy-disk" style={{marginRight:5}}></i>บันทึก</button>
            {editor !== 'new' && form.status === 'draft' && <button className="btn btn-success" onClick={() => { save().then(() => publish(editor)); }}><i className="ph ph-megaphone" style={{marginRight:5}}></i>บันทึก & เผยแพร่</button>}
          </div>
        </div>

        {/* Title */}
        <div className="card" style={{padding:24, marginBottom:20}}>
          <div className="form-group">
            <label>หัวข้อบทความ *</label>
            <input className="input" value={form.title} onChange={e => setForm({...form, title: e.target.value})}
              placeholder="หัวข้อบทความที่น่าสนใจ" style={{fontSize:18, fontWeight:600, height:54}} />
          </div>
          <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
            <div className="form-group">
              <label>หมวดหมู่</label>
              <select className="input" value={form.category_id} onChange={e => setForm({...form, category_id: e.target.value})}>
                <option value="">เลือกหมวดหมู่</option>
                {categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </div>
            <div className="form-group">
              <label>สถานะ</label>
              <select className="input" value={form.status} onChange={e => setForm({...form, status: e.target.value})}>
                <option value="draft">ร่าง</option>
                <option value="published">เผยแพร่</option>
              </select>
            </div>
          </div>
        </div>

        {/* รูปหน้าปก (Thumbnail) */}
        <div className="card" style={{padding:24, marginBottom:20}}>
          <h3 style={{marginBottom:14, color:'#102E54'}}><i className="ph ph-image" style={{marginRight:6,color:'#4A6079'}}></i>รูปหน้าปก</h3>
          {editor === 'new' ? (
            <p style={{color:'#8A6D1B', fontSize:14, background:'#FFF8E8', border:'1px solid #F0E0B0', borderRadius:10, padding:'12px 16px'}}><i className="ph ph-info" style={{marginRight:5}}></i>บันทึกบทความก่อน จึงจะอัปโหลดรูปหน้าปกได้</p>
          ) : (
            <div style={{display:'flex', gap:20, alignItems:'flex-start', flexWrap:'wrap'}}>
              {form.thumbnail_url
                ? <img src={form.thumbnail_url} alt="" style={{width:240, height:150, objectFit:'cover', borderRadius:12, border:'1px solid var(--border)'}} />
                : <div style={{width:240, height:150, borderRadius:12, background:'var(--gray-light)', display:'grid', placeItems:'center', color:'#9CA3AF', fontSize:13}}>ยังไม่มีรูปหน้าปก</div>}
              <div>
                <input ref={thumbRef} type="file" accept="image/*" style={{display:'none'}} onChange={uploadThumb} />
                <button className="btn btn-ghost" onClick={() => thumbRef.current && thumbRef.current.click()} disabled={thumbBusy}>
                  {thumbBusy ? 'กำลังอัปโหลด...' : (form.thumbnail_url ? <><i className="ph ph-arrows-clockwise" style={{marginRight:5}}></i>เปลี่ยนรูป</> : <><i className="ph ph-upload-simple" style={{marginRight:5}}></i>อัปโหลดรูป</>)}
                </button>
                <p style={{fontSize:12, color:'#6B7280', marginTop:10, maxWidth:280, lineHeight:1.6}}>แนะนำอัตราส่วน ~16:10 · JPG/PNG/WebP · รูปนี้ใช้แสดงในการ์ดบทความและหัวบทความบนหน้าเว็บ</p>
              </div>
            </div>
          )}
        </div>

        {/* Rich Text Editor */}
        <div className="card" style={{padding:24, marginBottom:20}}>
          <label style={{display:'block', fontSize:13, fontWeight:600, marginBottom:8, color:'var(--navy-3)'}}>เนื้อหาบทความ</label>
          <RichEditor
            value={form.content}
            onChange={val => setForm(f => ({...f, content: val}))}
            placeholder="เขียนเนื้อหาบทความที่นี่... รองรับ หัวข้อ, ตัวหนา, รูปภาพ, วิดีโอ, ลิงก์ และอื่นๆ"
          />
        </div>

        {/* SEO */}
        <div className="card" style={{padding:24}}>
          <h3 style={{marginBottom:16, color:'#102E54'}}><i className="ph ph-magnifying-glass" style={{marginRight:6,color:'#4A6079'}}></i>SEO (ค้นหาเจอง่าย)</h3>
          <div className="form-group">
            <label>Meta Title</label>
            <input className="input" value={form.meta_title} onChange={e => setForm({...form, meta_title: e.target.value})}
              placeholder="หัวข้อที่แสดงในผลค้นหา Google (แนะนำ 50-60 ตัวอักษร)" />
            <span style={{fontSize:11, color: (form.meta_title||'').length > 60 ? '#D8567A' : '#6B7280'}}>{(form.meta_title||'').length}/60</span>
          </div>
          <div className="form-group">
            <label>Meta Description</label>
            <textarea className="input" rows={2} value={form.meta_description} onChange={e => setForm({...form, meta_description: e.target.value})}
              placeholder="คำอธิบายที่แสดงในผลค้นหา Google (แนะนำ 150-160 ตัวอักษร)" />
            <span style={{fontSize:11, color: (form.meta_description||'').length > 160 ? '#D8567A' : '#6B7280'}}>{(form.meta_description||'').length}/160</span>
          </div>
        </div>
      </div>
    );

    // ======= List View =======
    const cols = [
      { label: t('articles_heading'), sortKey: 'title', render: r => <span className="text-bold" style={{cursor:'pointer',color:'var(--blue)'}} onClick={() => openEdit(r)}>{r.title}</span> },
      { label: t('articles_category'), sortKey: 'category_name', render: r => r.category_name || '-' },
      { label: t('articles_author'), sortKey: 'author_email', render: r => r.author_email || <span style={{color:'var(--text-2)'}}>PROPFINN</span> },
      { label: t('status'), sortKey: 'status', render: r => <ArticleToggle row={r} reload={load} /> },
      { label: t('articles_published_at'), sortKey: 'published_at', render: r => r.published_at ? new Date(r.published_at).toLocaleDateString('th-TH') : '-' },
      { label: t('actions'), render: r => (
        <div className="row gap-6">
          <window.EditBtn onClick={() => openEdit(r)} />
          <window.DeleteBtn onClick={() => del(r.id)} />
        </div>
      )},
    ];

    return (
      <div className="page">
        <div className="page-header">
          <h1><i className="ph ph-newspaper" style={{marginRight:8,color:'#4A6079'}}></i>{t('articles_title')}</h1>
          <button className="btn btn-primary" onClick={openNew}>{t('articles_create')}</button>
        </div>
        <div className="card"><Table columns={cols} data={ts.sorted} loading={loading} empty="ยังไม่มีบทความ" sort={ts.sort} onSort={ts.onSort} /></div>
      </div>
    );
  }

  window.ArticlesPage = ArticlesPage;
})();
