// Ajuda e suporte — versão interna (2026-10-14, pedido do usuário: "a tela de suporte deve ter uma interna e
// uma externa, e a interna deve aparecer a sidebar"). Menu lateral + topo do app; os artigos são lidos do
// help.html (central pública) — o texto fica num lugar só: mudou um artigo lá, muda aqui também.

const SUP_ICONS = { comecar: 'rocket', whatsapp: 'msgs', funil: 'funnel', equipe: 'team', ia: 'sparkles', integracoes: 'link', assinatura: 'wallet', dados: 'shield' };
const supNorm = s => String(s || '').normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase();

async function supLoadArticles() {
  const r = await fetch('help.html', { cache: 'no-cache' });
  if (!r.ok) throw new Error('Não foi possível carregar os artigos.');
  const doc = new DOMParser().parseFromString(await r.text(), 'text/html');
  // Artigos por plano: data-plan="full" não existe no plano Distribuição; data-plan="dist" é só dele
  const dist = !!(window.horosIsDist && window.horosIsDist());
  doc.querySelectorAll(dist ? '[data-plan="full"]' : '[data-plan="dist"]').forEach(el => el.remove());
  const subs = {};
  doc.querySelectorAll('#hccats a').forEach(a => { subs[(a.getAttribute('href') || '').replace('#', '')] = a.querySelector('small')?.textContent || ''; });
  if (dist) subs.funil = 'Leads duplicados';
  return [...doc.querySelectorAll('.hc-sec')].map(sec => ({
    id: sec.id,
    title: sec.querySelector('h2')?.textContent?.trim() || '',
    sub: subs[sec.id] || '',
    items: [...sec.querySelectorAll('.hc-q')].map((d, i) => {
      const a = d.querySelector('.a');
      // Links da central pública que apontam para o site → abrem em outra aba; os do app ficam
      a?.querySelectorAll('a[href]').forEach(l => { if (/^https?:/.test(l.getAttribute('href'))) { l.target = '_blank'; l.rel = 'noopener noreferrer'; } });
      return { key: `${sec.id}-${i}`, q: d.querySelector('summary')?.textContent?.trim() || '', html: a ? a.innerHTML : '', txt: supNorm(d.textContent) };
    }),
  })).filter(s => s.items.length);
}

function SupportPage() {
  const [secs, setSecs] = React.useState(null);
  const [err, setErr] = React.useState('');
  const [q, setQ] = React.useState(() => new URLSearchParams(location.search).get('q') || '');
  const [cat, setCat] = React.useState(null);
  const [open, setOpen] = React.useState({});
  const [form, setForm] = React.useState(() => /[?&]contato=1\b/.test(location.search));
  const [tickets, setTickets] = React.useState(null);
  const [view, setView] = React.useState(null);   // id do chamado aberto

  React.useEffect(() => { supLoadArticles().then(setSecs).catch(e => setErr(e.message)); }, []);

  const words = supNorm(q).split(/\s+/).filter(Boolean);
  const shown = (secs || [])
    .filter(s => !cat || s.id === cat)
    .map(s => ({ ...s, items: words.length ? s.items.filter(it => words.every(w => it.txt.includes(w))) : s.items }))
    .filter(s => s.items.length);
  const total = shown.reduce((n, s) => n + s.items.length, 0);

  // Meus chamados (pela API — funciona até com a conta bloqueada por assinatura)
  React.useEffect(() => { supCall().then(j => setTickets(j.tickets || [])).catch(() => setTickets([])); }, []);
  const from = new URLSearchParams(location.search).get('page') || '';

  return (
    <div className="sup-page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Ajuda e suporte</h1>
          <p className="page-sub">Respostas rápidas sobre o dia a dia no Horos. Não achou? Abra um chamado para o suporte.</p>
        </div>
        <button type="button" className="btn-primary sup-head-btn" onClick={() => setForm(true)}><Icon name="mail" size={15} /> Falar com o suporte</button>
      </div>

      <label className="sup-search">
        <Icon name="search" size={17} />
        <input type="search" value={q} onChange={e => setQ(e.target.value)} placeholder={supIsDist() ? 'Busque: fila, integrações, convidar equipe, cancelar…' : 'Busque: conectar WhatsApp, importar planilha, cancelar…'} aria-label="Buscar na ajuda" />
        {q && <button type="button" onClick={() => setQ('')} aria-label="Limpar busca"><Icon name="close" size={14} /></button>}
      </label>

      {!secs && !err && <div className="sup-cats">{[0,1,2,3,4,5,6,7].map(i => <div key={i} className="sup-cat sup-cat--skel"><SkelLine /></div>)}</div>}
      {err && <div className="sup-empty">{err} <button className="sup-link" onClick={() => location.reload()}>Tentar de novo</button></div>}

      {secs && (
        <>
          {!words.length && (
            <div className="sup-cats">
              {secs.map(s => (
                <button key={s.id} type="button" className={`sup-cat${cat === s.id ? ' on' : ''}`} onClick={() => setCat(c => c === s.id ? null : s.id)}>
                  <span className="sup-cat-ic"><Icon name={SUP_ICONS[s.id] || 'help'} size={17} /></span>
                  <span className="sup-cat-txt"><b>{s.title}</b><small>{s.sub || `${s.items.length} artigos`}</small></span>
                </button>
              ))}
            </div>
          )}
          {(words.length > 0 || cat) && (
            <div className="sup-filter">
              {words.length ? `${total} ${total === 1 ? 'resultado' : 'resultados'} para "${q}"` : secs.find(s => s.id === cat)?.title}
              <button className="sup-link" onClick={() => { setQ(''); setCat(null); }}>Ver todos os assuntos</button>
            </div>
          )}
          {shown.map(s => (
            <section key={s.id} className="sup-sec">
              <h2>{s.title}</h2>
              {s.items.map((it, i) => {
                const isOpen = open[it.key] ?? (words.length > 0 && i < 3);
                return (
                  <div key={it.key} className={`sup-q${isOpen ? ' open' : ''}`}>
                    <button type="button" className="sup-q-head" onClick={() => setOpen(o => ({ ...o, [it.key]: !isOpen }))} aria-expanded={isOpen}>
                      <span>{it.q}</span><Icon name="arrDown" size={15} />
                    </button>
                    {isOpen && <div className="sup-q-body" dangerouslySetInnerHTML={{ __html: it.html }} />}
                  </div>
                );
              })}
            </section>
          ))}
          {!shown.length && <div className="sup-empty">Nada encontrado para essa busca. Tente outra palavra ou fale com o suporte abaixo.</div>}
        </>
      )}

      <div className="sup-contact">
        <div>
          <h2>Não achou o que procurava?</h2>
          <p>Abra um chamado contando o que aconteceu e, se puder, anexe um print da tela. A resposta chega no seu e-mail ({window.HOROS_USER?.email || 'da sua conta'}), em dias úteis.</p>
        </div>
        <div className="sup-contact-btns">
          <button type="button" className="btn-primary" onClick={() => setForm(true)}><Icon name="mail" size={15} /> Escrever para o suporte</button>
        </div>
      </div>

      {tickets && tickets.length > 0 && (
        <section className="sup-sec" id="chamados">
          <h2>Meus chamados</h2>
          <div className="sup-tickets">
            {tickets.map(t => (
              <button type="button" key={t.id} className={`sup-ticket${t.unread_user ? ' unread' : ''}`} onClick={() => setView(t.id)}>
                <span className="sup-ticket-num">#{t.number}</span>
                <span className="sup-ticket-main">
                  <b>{t.subject}</b>
                  <small>{SUP_CATS[t.category] || 'Dúvida'} · {new Date(t.created_at).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' })}{t.attachment_name ? ' · com anexo' : ''}</small>
                </span>
                {t.unread_user && <span className="sup-ticket-new">Nova resposta</span>}
                <span className={`sup-ticket-st sup-ticket-st--${t.status}`}>{SUP_STATUS[t.status] || t.status}</span>
              </button>
            ))}
          </div>
        </section>
      )}

      {view && <SupTicketView id={view} onClose={() => setView(null)} onSeen={id => setTickets(l => (l || []).map(x => x.id === id ? { ...x, unread_user: false } : x))} onReplied={id => setTickets(l => (l || []).map(x => x.id === id ? { ...x, status: 'open' } : x))} />}
      {form && <SupTicketModal page={from} onClose={() => setForm(false)} onSent={t => setTickets(list => [t, ...(list || [])])} />}
    </div>
  );
}

// ── Chamado de suporte (formulário dentro do Horos → /api/support) ──
const SUP_CATS = { duvida: 'Dúvida', problema: 'Algo não está funcionando', whatsapp: 'WhatsApp', integracoes: 'Integrações', assinatura: 'Assinatura e cobrança', vendas: 'Planos e contratação', parceria: 'Parceria e integrações', privacidade: 'Privacidade e dados', sugestao: 'Sugestão', outro: 'Outro assunto' };
const SUP_STATUS = { open: 'Aberto', answered: 'Respondido', closed: 'Resolvido' };
// Plano Distribuição: sem WhatsApp dentro do Horos (assunto e exemplos sem ele)
const supIsDist = () => !!(window.horosIsDist && window.horosIsDist());
async function supCall(body) {
  const tok = window.horosToken ? await window.horosToken() : window.HOROS_SESSION?.access_token;
  const r = await fetch('/api/support', {
    method: body ? 'POST' : 'GET', cache: 'no-store',
    headers: { Authorization: `Bearer ${tok}`, ...(body ? { 'Content-Type': 'application/json' } : {}) },
    body: body ? JSON.stringify(body) : undefined,
  });
  const j = await r.json().catch(() => ({}));
  if (!r.ok) throw new Error(j.error || 'Não foi possível enviar. Tente de novo.');
  return j;
}
function SupTicketView({ id, onClose, onSeen, onReplied }) {
  const [d, setD] = React.useState(null);
  const [err, setErr] = React.useState('');
  const [text, setText] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const load = React.useCallback(() => {
    const tok = window.horosToken ? window.horosToken() : Promise.resolve(window.HOROS_SESSION?.access_token);
    tok.then(t => fetch(`/api/support?id=${encodeURIComponent(id)}`, { cache: 'no-store', headers: { Authorization: `Bearer ${t}` } }))
      .then(r => r.json().then(j => r.ok ? j : Promise.reject(new Error(j.error || 'Erro'))))
      .then(j => { setD(j); onSeen && onSeen(id); }).catch(e => setErr(e.message));
  }, [id]);
  React.useEffect(() => { load(); }, [load]);
  React.useEffect(() => {
    const onKey = e => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);
  const send = async () => {
    setBusy(true); setErr('');
    try { await supCall({ action: 'reply', id, message: text }); setText(''); onReplied && onReplied(id); load(); }
    catch (e) { setErr(e.message); }
    setBusy(false);
  };
  const t = d?.ticket;
  const when = iso => new Date(iso).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });
  return ReactDOM.createPortal(
    <div className="sup-ov" onMouseDown={e => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="sup-modal" role="dialog" aria-label="Chamado">
        <div className="sup-modal-head">
          <span className="sup-cat-ic"><Icon name="mail" size={17} /></span>
          <div><b>{t ? `#${t.number} · ${t.subject}` : 'Carregando…'}</b><small>{t ? `${SUP_CATS[t.category] || ''} · ${SUP_STATUS[t.status] || t.status}` : ''}</small></div>
          <button className="sup-modal-x" onClick={onClose} aria-label="Fechar"><Icon name="close" size={14} /></button>
        </div>
        <div className="sup-modal-body">
          {!d && !err && <div className="sup-modal-note">Carregando…</div>}
          {t && (
            <>
              <div className="sup-msg sup-msg--user"><small>Você · {when(t.created_at)}</small><p>{t.message}</p>{t.attachment_name && <small>Anexo: {t.attachment_name}</small>}</div>
              {d.messages.map(m => (
                <div key={m.id} className={`sup-msg sup-msg--${m.author}`}>
                  <small>{m.author === 'support' ? `${m.author_name || 'Suporte'} · Suporte Horos` : 'Você'} · {when(m.created_at)}</small>
                  <p>{m.body}</p>
                </div>
              ))}
              {!d.messages.some(m => m.author === 'support') && <div className="sup-modal-note">Ainda sem resposta. Respondemos em dias úteis, por aqui e no seu e-mail.</div>}
              <label className="sup-field"><span>{t.status === 'closed' ? 'Ainda precisa de ajuda? Responder reabre o chamado' : 'Responder'}</span>
                <textarea rows={3} value={text} onChange={e => setText(e.target.value)} maxLength={8000} /></label>
            </>
          )}
          {err && <div className="sup-err">{err}</div>}
          {t && <div className="sup-modal-foot"><button className="sup-btn" onClick={onClose}>Fechar</button><button className="btn-primary" onClick={send} disabled={busy || text.trim().length < 2}>{busy ? 'Enviando…' : 'Enviar'}</button></div>}
        </div>
      </div>
    </div>,
    document.body
  );
}

const supFileToB64 = f => new Promise((ok, no) => { const r = new FileReader(); r.onload = () => ok(String(r.result).split(',')[1]); r.onerror = no; r.readAsDataURL(f); });

function SupTicketModal({ page, onClose, onSent }) {
  // support.html?contato=1&assunto=<categoria>&titulo=<assunto>&texto=<mensagem> já abre preenchido
  const pre = new URLSearchParams(location.search);
  const [category, setCategory] = React.useState(() => SUP_CATS[pre.get('assunto')] ? pre.get('assunto') : 'duvida');
  const [subject, setSubject] = React.useState(() => pre.get('titulo') || '');
  const [message, setMessage] = React.useState(() => pre.get('texto') || '');
  const [file, setFile] = React.useState(null);
  const [preview, setPreview] = React.useState(null);
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');
  const [done, setDone] = React.useState(null);
  const fileRef = React.useRef(null);

  React.useEffect(() => {
    const onKey = e => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);
  React.useEffect(() => {
    if (!file || !file.type.startsWith('image/')) { setPreview(null); return; }
    const u = URL.createObjectURL(file); setPreview(u);
    return () => URL.revokeObjectURL(u);
  }, [file]);

  const pick = f => {
    if (!f) return;
    if (!/^image\/(png|jpe?g|webp|gif)$/.test(f.type) && f.type !== 'application/pdf') { setErr('Anexe uma imagem (PNG, JPG, WEBP) ou PDF.'); return; }
    if (f.size > 3 * 1024 * 1024) { setErr('O anexo passa de 3 MB.'); return; }
    setErr(''); setFile(f);
  };
  // Ctrl+V com um print copiado vira anexo
  const onPaste = e => {
    const it = [...(e.clipboardData?.items || [])].find(x => x.type.startsWith('image/'));
    if (it) { e.preventDefault(); const f = it.getAsFile(); pick(new File([f], `print-${Date.now()}.png`, { type: f.type || 'image/png' })); }
  };

  const send = async () => {
    setBusy(true); setErr('');
    try {
      const attachment = file ? { name: file.name, type: file.type, base64: await supFileToB64(file) } : undefined;
      const j = await supCall({ category, subject, message, page, attachment });
      setDone(j.ticket); onSent && onSent(j.ticket);
    } catch (e) { setErr(e.message); }
    setBusy(false);
  };

  return ReactDOM.createPortal(
    <div className="sup-ov" onMouseDown={e => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="sup-modal" role="dialog" aria-label="Falar com o suporte" onPaste={onPaste}>
        <div className="sup-modal-head">
          <span className="sup-cat-ic"><Icon name="mail" size={17} /></span>
          <div><b>{done ? 'Chamado enviado' : 'Falar com o suporte'}</b><small>{done ? `Número #${done.number}` : 'Respondemos no seu e-mail, em dias úteis'}</small></div>
          <button className="sup-modal-x" onClick={onClose} aria-label="Fechar"><Icon name="close" size={14} /></button>
        </div>
        {done ? (
          <div className="sup-modal-body sup-done">
            <span className="sup-done-ic"><Icon name="check" size={22} /></span>
            <p>Recebemos o seu chamado <b>#{done.number}</b>. A resposta chega em <b>{window.HOROS_USER?.email || 'seu e-mail'}</b>.</p>
            <div className="sup-modal-foot"><button className="btn-primary" onClick={onClose}>Fechar</button></div>
          </div>
        ) : (
          <div className="sup-modal-body">
            <label className="sup-field"><span>Sobre o quê?</span>
              <select value={category} onChange={e => setCategory(e.target.value)}>
                {Object.entries(SUP_CATS).filter(([k]) => !(k === 'whatsapp' && supIsDist())).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
              </select></label>
            <label className="sup-field"><span>Assunto</span>
              <input value={subject} onChange={e => setSubject(e.target.value)} maxLength={160} placeholder={supIsDist() ? 'Ex.: os leads do Facebook não estão chegando' : 'Ex.: o WhatsApp desconectou sozinho'} autoFocus /></label>
            <label className="sup-field"><span>O que aconteceu?</span>
              <textarea rows={6} value={message} onChange={e => setMessage(e.target.value)} maxLength={8000} placeholder="Conte o passo a passo: o que você fez, o que esperava e o que apareceu." /></label>
            <div className="sup-field">
              <span>Print da tela <em>(opcional — pode colar com Ctrl+V)</em></span>
              {file ? (
                <div className="sup-file">
                  {preview ? <img src={preview} alt="" /> : <span className="sup-cat-ic"><Icon name="file" size={16} /></span>}
                  <span className="sup-file-name">{file.name}</span>
                  <button type="button" className="sup-link" onClick={() => setFile(null)}>Tirar</button>
                </div>
              ) : (
                <button type="button" className="sup-drop" onClick={() => fileRef.current?.click()}
                  onDragOver={e => e.preventDefault()} onDrop={e => { e.preventDefault(); pick(e.dataTransfer.files?.[0]); }}>
                  <Icon name="paperclip" size={15} /> Anexar imagem ou PDF (até 3 MB)
                </button>
              )}
              <input ref={fileRef} type="file" accept="image/png,image/jpeg,image/webp,image/gif,application/pdf" hidden onChange={e => { pick(e.target.files?.[0]); e.target.value = ''; }} />
            </div>
            <div className="sup-modal-note">Vai junto: a tela de onde você veio{page ? ` (${page})` : ''}, a empresa e o navegador — para não precisarmos perguntar.</div>
            {err && <div className="sup-err">{err}</div>}
            <div className="sup-modal-foot">
              <button type="button" className="sup-btn" onClick={onClose}>Cancelar</button>
              <button type="button" className="btn-primary" onClick={send} disabled={busy || subject.trim().length < 3 || message.trim().length < 10}>{busy ? 'Enviando…' : 'Enviar chamado'}</button>
            </div>
          </div>
        )}
      </div>
    </div>,
    document.body
  );
}

function SupportApp() {
  const [theme, setTheme] = React.useState(() => localStorage.getItem('horos-theme') || 'light');
  const changeTheme = (t) => { setTheme(t); document.documentElement.dataset.theme = t; localStorage.setItem('horos-theme', t); };
  React.useEffect(() => { document.documentElement.dataset.theme = theme; }, []);
  return (
    <div className="app">
      <Sidebar active="help" />
      <div className="main">
        <Topbar theme={theme} onThemeChange={changeTheme} />
        <div className="content">
          <SupportPage />
        </div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<SupportApp />);
