// ============================================================
// EDITOR — Rich text editor with preview, cover, tags, schedule
// ============================================================

function Editor({ id, onDone }) {
  const [doc, setDoc] = useState(null);
  const [categories, setCategories] = useState([]);
  const [saving, setSaving] = useState(false);
  const [toast, setToast] = useState('');
  const [previewOn, setPreviewOn] = useState(false);
  const bodyRef = useRef(null);
  const bodyInitialized = useRef(false);

  useEffect(() => {
    api.listCategories().then(setCategories);
    if (id) {
      api.getArticle(id).then(a => setDoc(a || newDoc()));
    } else {
      setDoc(newDoc());
    }
  }, [id]);

  // Inject html into contenteditable once on load (avoid React reconciling on every keystroke)
  useEffect(() => {
    if (doc && bodyRef.current && !bodyInitialized.current) {
      bodyRef.current.innerHTML = doc.body || '';
      bodyInitialized.current = true;
    }
  }, [doc]);

  if (!doc) return <div className="empty">Carregando…</div>;

  const set = (patch) => setDoc(d => ({ ...d, ...patch }));

  const onBodyInput = () => {
    setDoc(d => ({ ...d, body: bodyRef.current.innerHTML }));
  };

  const save = async (status) => {
    setSaving(true);
    const body = bodyRef.current ? bodyRef.current.innerHTML : doc.body;
    const payload = {
      ...doc,
      body,
      status,
      slug: doc.slug || slugify(doc.title) || api.uid(),
      author: doc.author || 'Dr. Angelo Santos',
    };
    if (status === 'published' && !payload.publishedAt) payload.publishedAt = new Date().toISOString();
    if (status === 'scheduled' && doc.scheduledFor) payload.publishedAt = doc.scheduledFor;
    if (status === 'draft') {} // leave publishedAt as-is

    const saved = await api.upsertArticle(payload);
    setSaving(false);
    setToast(status === 'published' ? 'Artigo publicado.' :
             status === 'scheduled' ? 'Artigo agendado.' : 'Rascunho salvo.');
    setDoc(saved);
    if (!id) setTimeout(() => onDone && onDone(), 600);
  };

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 20, gap: 16, flexWrap: 'wrap' }}>
        <div>
          <a href="#/admin" style={{
            fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: '0.14em',
            textTransform: 'uppercase', color: 'var(--ink-3)'
          }}>← Voltar à redação</a>
          <h1 className="admin-h1" style={{ marginTop: 6 }}>
            {id ? 'Editar artigo' : 'Novo artigo'}
          </h1>
          <p className="admin-sub">
            <span className={`badge ${doc.status || 'draft'}`} style={{ marginRight: 10 }}>
              {doc.status === 'published' ? 'Publicado' :
               doc.status === 'scheduled' ? 'Agendado' : 'Rascunho'}
            </span>
            {readingTime(doc.body)} min de leitura · {(doc.body || '').replace(/<[^>]+>/g, ' ').split(/\s+/).filter(Boolean).length} palavras
          </p>
        </div>
        <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
          <button className="btn-ghost" onClick={() => setPreviewOn(true)}>
            <Icon.eye /> &nbsp;Pré-visualizar
          </button>
          <button className="btn-ghost" onClick={() => save('draft')} disabled={saving}>
            Salvar rascunho
          </button>
          {doc.status === 'scheduled' || (doc.scheduledFor && doc.status !== 'published') ? (
            <button className="btn-primary gold" onClick={() => save('scheduled')} disabled={saving || !doc.scheduledFor}>
              Agendar
            </button>
          ) : null}
          <button className="btn-primary green" onClick={() => save('published')} disabled={saving || !doc.title}>
            {saving ? 'Salvando…' : doc.status === 'published' ? 'Atualizar' : 'Publicar agora'}
          </button>
        </div>
      </div>

      <div className="editor-shell">
        <div className="editor-main">
          <input
            type="text"
            className="editor-title"
            placeholder="Manchete da edição"
            value={doc.title}
            onChange={e => set({ title: e.target.value, slug: doc.slug || slugify(e.target.value) })}
          />
          <textarea
            className="editor-subtitle"
            placeholder="Linha-fina ou olho — uma frase que conduz o leitor."
            value={doc.subtitle}
            rows={2}
            onChange={e => set({ subtitle: e.target.value })}
          />

          <RichToolbar
            onCommand={(cmd, val) => {
              document.execCommand(cmd, false, val);
              bodyRef.current?.focus();
              onBodyInput();
            }}
            onInsertHTML={(html) => {
              bodyRef.current?.focus();
              document.execCommand('insertHTML', false, html);
              onBodyInput();
            }}
          />

          <div
            ref={bodyRef}
            className="editor-body"
            contentEditable
            suppressContentEditableWarning
            data-placeholder="Comece a escrever a matéria…"
            onInput={onBodyInput}
          />
        </div>

        <aside className="editor-side">
          {/* Cover uploader */}
          <div className="editor-card">
            <h6>Imagem de capa</h6>
            <CoverUploader value={doc.cover} onChange={v => set({ cover: v })} />
            <label>Legenda da imagem</label>
            <input
              type="text"
              value={doc.coverCaption}
              onChange={e => set({ coverCaption: e.target.value })}
              placeholder="Crédito ou contexto da imagem"
            />
          </div>

          {/* Meta */}
          <div className="editor-card">
            <h6>Publicação</h6>

            <label>Editoria</label>
            <select value={doc.category} onChange={e => set({ category: e.target.value })}>
              {categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>

            <label>Slug</label>
            <input
              type="text"
              value={doc.slug || ''}
              onChange={e => set({ slug: slugify(e.target.value) })}
              placeholder="auto-a-partir-do-titulo"
              style={{ fontFamily: 'var(--mono)', fontSize: 13 }}
            />

            <label>Autor</label>
            <input
              type="text"
              value={doc.author}
              onChange={e => set({ author: e.target.value })}
            />

            <label>Agendar para</label>
            <input
              type="datetime-local"
              value={doc.scheduledFor ? toLocalDT(doc.scheduledFor) : ''}
              onChange={e => set({ scheduledFor: e.target.value ? new Date(e.target.value).toISOString() : null })}
              style={{ fontFamily: 'var(--mono)', fontSize: 13 }}
            />
            <small style={{
              fontFamily: 'var(--sans)', fontSize: 11, color: 'var(--ink-3)',
              display: 'block', marginTop: -8, marginBottom: 12
            }}>
              Defina para mudar status para "Agendado".
            </small>
          </div>

          {/* Tags */}
          <div className="editor-card">
            <h6>Etiquetas</h6>
            <TagInput value={doc.tags || []} onChange={v => set({ tags: v })} />
          </div>

          {/* Destaque */}
          <div className="editor-card">
            <h6>Destaque editorial</h6>
            <label style={{ display: 'flex', gap: 10, alignItems: 'center', textTransform: 'none', letterSpacing: 0, fontFamily: 'var(--serif)', fontSize: 14, color: 'var(--ink)', marginBottom: 0 }}>
              <input
                type="checkbox"
                checked={!!doc.featured}
                onChange={e => set({ featured: e.target.checked })}
                style={{ width: 'auto', margin: 0 }}
              />
              <span>Manchete da capa — substitui a anterior</span>
            </label>
          </div>
        </aside>
      </div>

      {previewOn && (
        <PreviewModal doc={{ ...doc, body: bodyRef.current?.innerHTML || doc.body }} onClose={() => setPreviewOn(false)} />
      )}

      <Toast message={toast} onDone={() => setToast('')} />
    </div>
  );
}

function newDoc() {
  return {
    id: null,
    title: '',
    subtitle: '',
    body: '',
    cover: '',
    coverCaption: '',
    category: 'tribuna',
    tags: [],
    author: 'Dr. Angelo Santos',
    status: 'draft',
    publishedAt: null,
    scheduledFor: null,
    featured: false,
  };
}

function toLocalDT(iso) {
  // Convert ISO to value for input[type=datetime-local]
  const d = new Date(iso);
  const pad = (n) => String(n).padStart(2, '0');
  return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
}

// ---------- Rich text toolbar (Medium / Ghost style) ----------
function RichToolbar({ onCommand, onInsertHTML }) {
  const [linkOpen, setLinkOpen] = useState(false);
  const [linkUrl, setLinkUrl] = useState('');
  const savedRange = useRef(null);
  const imgRef = useRef(null);

  const saveSel = () => {
    const sel = window.getSelection();
    if (sel && sel.rangeCount) savedRange.current = sel.getRangeAt(0).cloneRange();
  };
  const restoreSel = () => {
    if (!savedRange.current) return;
    const sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(savedRange.current);
  };

  const Btn = ({ cmd, val, children, title }) => (
    <button type="button" title={title} onMouseDown={(e) => { e.preventDefault(); onCommand(cmd, val); }}>
      {children}
    </button>
  );

  const applyLink = () => {
    let url = linkUrl.trim();
    if (url) {
      if (!/^(https?:\/\/|mailto:|#|tel:)/i.test(url)) url = 'https://' + url;
      restoreSel();
      onCommand('createLink', url);
    }
    setLinkOpen(false);
    setLinkUrl('');
  };

  const onImg = async (file) => {
    if (!file) return;
    try {
      const url = await api.uploadImage(file);
      const html =
        `<figure class="body-figure"><img src="${url}" alt="" />` +
        `<figcaption>Clique para escrever a legenda…</figcaption></figure><p><br/></p>`;
      restoreSel();
      onInsertHTML(html);
    } catch (err) {
      alert('Falha ao enviar imagem: ' + err.message);
    }
  };

  return (
    <div className="editor-toolbar">
      <Btn cmd="formatBlock" val="h2" title="Título de seção (H2)">H₂</Btn>
      <Btn cmd="formatBlock" val="h3" title="Subtítulo (H3)">H₃</Btn>
      <Btn cmd="formatBlock" val="p" title="Parágrafo">¶</Btn>
      <span className="sep" />
      <Btn cmd="bold" title="Negrito (Ctrl+B)"><strong>B</strong></Btn>
      <Btn cmd="italic" title="Itálico (Ctrl+I)"><em>I</em></Btn>
      <Btn cmd="underline" title="Sublinhado (Ctrl+U)"><u>U</u></Btn>
      <Btn cmd="strikeThrough" title="Tachado"><s>S</s></Btn>
      <span className="sep" />
      <Btn cmd="insertUnorderedList" title="Lista com marcadores">• ≡</Btn>
      <Btn cmd="insertOrderedList" title="Lista numerada">1. ≡</Btn>
      <span className="sep" />
      <Btn cmd="formatBlock" val="blockquote" title="Citação destacada">“ ”</Btn>
      <Btn cmd="formatBlock" val="pre" title="Bloco de código">{'</>'}</Btn>
      <span className="sep" />
      <button
        type="button"
        title="Inserir link"
        className={linkOpen ? 'active' : ''}
        onMouseDown={(e) => { e.preventDefault(); saveSel(); setLinkOpen(o => !o); }}
      ><Icon.link /></button>
      <button
        type="button"
        title="Inserir imagem no texto"
        onMouseDown={(e) => { e.preventDefault(); saveSel(); imgRef.current?.click(); }}
      ><Icon.image /></button>
      <input ref={imgRef} type="file" accept="image/*" hidden onChange={e => { onImg(e.target.files?.[0]); e.target.value = ''; }} />
      <button type="button" title="Remover formatação" onMouseDown={(e) => { e.preventDefault(); onCommand('removeFormat'); }}>×</button>

      {linkOpen && (
        <div className="link-popover" onMouseDown={(e) => e.stopPropagation()}>
          <Icon.link />
          <input
            autoFocus
            value={linkUrl}
            onChange={e => setLinkUrl(e.target.value)}
            placeholder="Cole ou digite a URL e tecle Enter"
            onKeyDown={e => {
              if (e.key === 'Enter') { e.preventDefault(); applyLink(); }
              if (e.key === 'Escape') { setLinkOpen(false); setLinkUrl(''); }
            }}
          />
          <button type="button" onMouseDown={(e) => { e.preventDefault(); applyLink(); }}>Aplicar</button>
        </div>
      )}
    </div>
  );
}

// ---------- Cover uploader ----------
function CoverUploader({ value, onChange }) {
  const fileRef = useRef(null);
  const [showUrl, setShowUrl] = useState(false);
  const [urlVal, setUrlVal] = useState('');
  const [uploading, setUploading] = useState(false);

  const onFile = async (f) => {
    if (!f) return;
    setUploading(true);
    try {
      const url = await api.uploadImage(f);
      onChange(url);
    } catch (err) {
      alert('Falha ao enviar imagem: ' + err.message);
    } finally {
      setUploading(false);
    }
  };

  return (
    <div>
      <div
        className={`cover-uploader ${value ? 'has-image' : ''}`}
        onClick={() => !value && fileRef.current?.click()}
        onDragOver={(e) => e.preventDefault()}
        onDrop={(e) => { e.preventDefault(); onFile(e.dataTransfer.files?.[0]); }}
      >
        {value ? (
          <>
            <img src={value} alt="" />
            <button className="remove" onClick={(e) => { e.stopPropagation(); onChange(''); }} title="Remover">×</button>
          </>
        ) : (
          <>
            <Icon.upload />
            <div style={{ marginTop: 10 }}>{uploading ? 'Enviando…' : 'Arraste ou clique para enviar'}</div>
            <div style={{ fontFamily: 'var(--serif)', textTransform: 'none', fontSize: 11, letterSpacing: 0, color: 'var(--ink-3)', marginTop: 4, fontStyle: 'italic' }}>
              JPG, PNG ou WebP, ratio 16:9 preferido
            </div>
          </>
        )}
        <input ref={fileRef} type="file" accept="image/*" hidden onChange={e => onFile(e.target.files?.[0])} />
      </div>
      {!value && (
        <div style={{ marginTop: -6 }}>
          {!showUrl ? (
            <button
              type="button"
              onClick={() => setShowUrl(true)}
              style={{ background: 'transparent', border: 0, fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--gold)', padding: '4px 0', cursor: 'pointer' }}
            >
              ou usar URL externa
            </button>
          ) : (
            <div style={{ display: 'flex', gap: 6 }}>
              <input
                value={urlVal}
                onChange={e => setUrlVal(e.target.value)}
                placeholder="https://…"
                style={{ flex: 1, padding: 8, border: '1px solid var(--rule)', fontFamily: 'var(--mono)', fontSize: 12, marginBottom: 0 }}
              />
              <button type="button" className="btn-ghost" style={{ padding: '6px 10px' }} onClick={() => { if (urlVal) onChange(urlVal); setShowUrl(false); }}>OK</button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ---------- Tag input ----------
function TagInput({ value, onChange }) {
  const [draft, setDraft] = useState('');
  const add = () => {
    const t = draft.trim().toLowerCase();
    if (!t) return;
    if (value.includes(t)) { setDraft(''); return; }
    onChange([...value, t]);
    setDraft('');
  };
  return (
    <div className="tag-input" onClick={(e) => e.currentTarget.querySelector('input')?.focus()}>
      {value.map(t => (
        <span key={t} className="tag">
          {t}
          <button type="button" onClick={() => onChange(value.filter(x => x !== t))}>×</button>
        </span>
      ))}
      <input
        type="text"
        value={draft}
        onChange={e => setDraft(e.target.value)}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ',') { e.preventDefault(); add(); }
          if (e.key === 'Backspace' && !draft && value.length) onChange(value.slice(0, -1));
        }}
        placeholder={value.length ? '' : 'adicione tags e tecle Enter'}
      />
    </div>
  );
}

// ---------- Preview Modal (renders the article as readers would see it) ----------
function PreviewModal({ doc, onClose }) {
  // Simulate published article inside the modal
  const cat = categoryById(doc.category);
  return (
    <div className="modal-mask">
      <div className="modal-bar">
        <span className="label">▸ Pré-visualização · não publicado</span>
        <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
          <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: '#aaa392' }}>
            {readingTime(doc.body)} min · {(doc.body || '').replace(/<[^>]+>/g, ' ').split(/\s+/).filter(Boolean).length} palavras
          </span>
          <button onClick={onClose}>Fechar pré-visualização ×</button>
        </div>
      </div>
      <div className="modal-frame">
        <article className="article-shell">
          <header className="article-head">
            {cat && <span className="eyebrow">{cat.name}</span>}
            <h1 className="headline">{doc.title || 'Sem título'}</h1>
            {doc.subtitle && <p className="kicker">{doc.subtitle}</p>}
            <div className="article-meta">
              <span>Por <strong>{doc.author}</strong></span>
              <span className="sep" />
              <span>{fmtDateLong(doc.publishedAt || doc.scheduledFor || new Date().toISOString())}</span>
              <span className="sep" />
              <span>{readingTime(doc.body)} min de leitura</span>
            </div>
          </header>
          {doc.cover && (
            <figure className="cover-figure">
              <div className="img"><img src={doc.cover} alt="" /></div>
              {doc.coverCaption && <figcaption className="cap">{doc.coverCaption}</figcaption>}
            </figure>
          )}
          <div className="article-layout">
            <div />
            <div className="article-body" dangerouslySetInnerHTML={{ __html: doc.body || '<p style="color: var(--ink-4); font-style: italic;">Sem conteúdo ainda — comece a escrever.</p>' }} />
            <div />
          </div>
        </article>
      </div>
    </div>
  );
}

Object.assign(window, { Editor, RichToolbar, CoverUploader, TagInput, PreviewModal });
