/* ===== Pago na Hora — Assistente "Hora" (chat IA) ===== */

const norm = s => s.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
const sumA = arr => arr.reduce((s, p) => s + p.amount, 0);
const firstName = n => n.split(' ')[0];
const lote = () => 'PG-' + Math.floor(Math.random() * 9000 + 1000);

/* ---- intent engine ---- */
function respond(text, role) {
  const t = norm(text);
  if (role === 'pj') {
    // pay a specific provider
    const pv = PNH.providers.find(p => t.includes(norm(firstName(p.name))));
    if (pv && /pag|pix|envi|transfer|manda|adianta/.test(t)) {
      return [{
        from: 'bot', type: 'action', icon: 'bolt', iconBg: 'var(--green-tint)', iconColor: 'var(--green)',
        title: 'Pagar ' + pv.name, sub: pv.pixType + ' · ' + pv.doc,
        lines: ['Contrato ' + pv.contract.toLowerCase(), 'Valor base R$ ' + PNH.fmt(pv.monthly)],
        amount: pv.monthly,
        buttons: [
          { label: 'Confirmar Pix', kind: 'green', icon: 'bolt', action: { kind: 'pay', who: pv.name, amount: pv.monthly, userEcho: 'Confirmar' } },
          { label: 'Mudar valor', kind: 'ghost', action: { kind: 'noop', userEcho: 'Mudar valor', reply: 'Sem problema — me diz o novo valor (ex: "paga a ' + firstName(pv.name) + ' R$ 3.000").' } },
        ],
      }];
    }
    if (/aprov|pendent|esperando|o que.*falta.*aprov|fila/.test(t)) {
      const aps = PNH.payments.filter(p => p.status === 'aprovar');
      return [
        { from: 'bot', type: 'text', text: 'Você tem ' + aps.length + ' pagamentos aguardando aprovação, somando R$ ' + PNH.fmt(sumA(aps)) + ':' },
        { from: 'bot', type: 'cards', items: aps.map(p => ({ name: p.who, sub: p.desc, amount: p.amount, kind: p.kind, action: { kind: 'pay', who: p.who, amount: p.amount, label: 'Pagar', userEcho: 'Pagar ' + p.who } })) },
        { from: 'bot', type: 'text', text: 'Quer enviar os dois de uma vez?', quick: ['Pagar todos agora', 'Agora não'] },
      ];
    }
    if (/todos agora|paga.*todos|aprova.*todos|tudo de uma vez/.test(t)) {
      const aps = PNH.payments.filter(p => p.status === 'aprovar');
      return [{ from: 'bot', type: 'action', icon: 'bolt', iconBg: 'var(--green-tint)', iconColor: 'var(--green)', title: 'Pagar ' + aps.length + ' entidades', sub: 'Pix em lote', lines: aps.map(p => p.who + ' · R$ ' + PNH.fmt(p.amount)), amount: sumA(aps), buttons: [{ label: 'Confirmar lote', kind: 'green', icon: 'bolt', action: { kind: 'payAll', count: aps.length, amount: sumA(aps), userEcho: 'Confirmar lote' } }] }];
    }
    if (/quanto.*(pag|gast)|gast|total|paguei|junho|m[e ]s/.test(t)) {
      return [
        { from: 'bot', type: 'stat', lbl: 'Pago em junho', val: 'R$ 86.940', sub: 'em 21 pagamentos · ↑ 12% vs. maio', chips: ['R$ 12.000 a aprovar', 'R$ 2.400 agendado', '19 notas recebidas'] },
        { from: 'bot', type: 'text', text: 'Posso te mostrar o que ainda falta aprovar ou quem não assinou contrato.', quick: ['O que falta aprovar?', 'Quem não assinou contrato?'] },
      ];
    }
    if (/quem.*(n[a ]o|falta).*assin|assinatura.*pendent|contrato.*pendent|nao assin/.test(t)) {
      return [
        { from: 'bot', type: 'text', text: '2 contratos estão sem assinatura da outra parte:' },
        { from: 'bot', type: 'cards', items: [
          { name: 'Rafael Costa', sub: 'Por entrega · enviado 28 Mai', kind: 'MEI', badge: 'pendente', action: { kind: 'remind', who: 'Rafael Costa', label: 'Cobrar', userEcho: 'Cobra o Rafael' } },
          { name: 'Diego Martins', sub: 'Recorrente · enviado hoje', kind: 'PJ', badge: 'pendente', action: { kind: 'remind', who: 'Diego Martins', label: 'Cobrar', userEcho: 'Cobra o Diego' } },
        ] },
        { from: 'bot', type: 'text', text: 'Quer que eu mande um lembrete pros dois?', quick: ['Cobrar os dois', 'Não'] },
      ];
    }
    if (/cobrar os dois|lembrete.*dois|cobra.*dois/.test(t)) {
      return [{ from: 'bot', type: 'success', text: 'Lembrete enviado pro Rafael e pro Diego. 📲 Te aviso assim que assinarem.' }];
    }
    if (/relat[o ]rio|contador|export|fech.*m[e ]s|nota/.test(t)) {
      return [{ from: 'bot', type: 'action', icon: 'doc', iconBg: 'var(--blue-50)', iconColor: 'var(--blue-600)', title: 'Relatório de junho.pdf', sub: 'Pronto para o contador', lines: ['R$ 86.940 em 21 pagamentos', '19 notas fiscais anexadas', 'Comprovantes Pix incluídos'], buttons: [{ label: 'Enviar ao contador', kind: 'primary', icon: 'send', action: { kind: 'report', userEcho: 'Manda pro contador' } }, { label: 'Baixar', kind: 'ghost', icon: 'download', action: { kind: 'noop', userEcho: 'Baixar', reply: 'Baixando o relatório de junho… 📄' } }] }];
    }
    if (/pr[o ]xim.*m[e ]s|previs|vou.*(pag|gast)|proje|julho/.test(t)) {
      return [{ from: 'bot', type: 'stat', lbl: 'Previsão para julho', val: 'R$ 89.300', sub: 'baseado nos contratos recorrentes ativos', chips: ['+R$ 2.360 vs. junho', '22 entidades'] }];
    }
    return [{ from: 'bot', type: 'text', text: 'Posso te ajudar a aprovar Pix, ver quanto você gastou, cobrar contrato pendente ou fechar o relatório do contador. O que você precisa?', quick: ['O que falta aprovar?', 'Quanto paguei em junho?', 'Gera o relatório'] }];
  }

  // ---------- PF ----------
  if (/pr[o ]xim.*pix|quando.*(cai|cair|receb)|pr[o ]ximo recebiment/.test(t)) {
    const next = PNH.receivables.find(r => r.status === 'agendado') || PNH.receivables[0];
    return [
      { from: 'bot', type: 'action', icon: 'wallet', iconBg: 'var(--green-tint)', iconColor: 'var(--green)', title: next.from, sub: next.desc, lines: ['Previsto para ' + next.date, 'Pix · sua chave CPF'], amount: next.amount, buttons: [{ label: 'Ver contrato', kind: 'ghost', icon: 'contract', action: { kind: 'noop', userEcho: 'Ver contrato', reply: 'Abri o contrato da ' + next.from + ' no seu painel. ✍️' } }] },
      { from: 'bot', type: 'text', text: 'Quer que eu te avise quando cair?', quick: ['Pode avisar', 'Quanto recebi esse mês?'] },
    ];
  }
  if (/pode avisar|me avisa|avisa.*cair/.test(t)) {
    return [{ from: 'bot', type: 'success', text: 'Combinado! Te aviso aqui assim que o Pix cair. 🔔' }];
  }
  if (/quanto.*receb|recebi.*m[e ]s|receb.*junho|total.*receb/.test(t)) {
    const pago = PNH.receivables.filter(r => r.status === 'pago');
    return [
      { from: 'bot', type: 'stat', lbl: 'Recebido em junho', val: 'R$ ' + PNH.fmt(sumA(pago)), sub: pago.length + ' pagamentos de ' + new Set(pago.map(p => p.from)).size + ' entidades', chips: ['R$ 5.800 a receber', '5 entidades ativas'] },
      { from: 'bot', type: 'text', text: 'Quer o extrato em PDF ou o comprovante de algum específico?', quick: ['Manda meu comprovante da Lumen', 'Baixar extrato'] },
    ];
  }
  if (/comprovante|recibo/.test(t)) {
    const r = PNH.receivables.find(x => t.includes(norm(x.from.split(' ')[0]))) || PNH.receivables.find(x => x.status === 'pago');
    return [{ from: 'bot', type: 'success', text: 'Pronto! Mandei o comprovante da ' + r.from + ' (R$ ' + PNH.fmt(r.amount) + ') aqui e pro seu e‑mail. 📎', doc: 'Comprovante ' + r.id + '.pdf' }];
  }
  if (/baixar extrato|extrato/.test(t)) {
    return [{ from: 'bot', type: 'success', text: 'Gerei seu extrato de junho com todos os recebimentos. 📄', doc: 'Extrato_junho.pdf' }];
  }
  if (/assin|contrato|falta.*assin/.test(t)) {
    return [{ from: 'bot', type: 'action', icon: 'contract', iconBg: 'var(--blue-50)', iconColor: 'var(--blue-600)', title: 'Contrato · Lumen Co.', sub: 'Projeto visual — etapa 2', lines: ['R$ 3.200 ao assinar', 'Aguardando só a sua assinatura'], buttons: [{ label: 'Assinar agora', kind: 'green', icon: 'check', action: { kind: 'sign', who: 'Lumen Co.', userEcho: 'Assinar agora' } }, { label: 'Ler antes', kind: 'ghost', action: { kind: 'noop', userEcho: 'Ler antes', reply: 'Abri o contrato completo da Lumen Co. no seu painel pra você ler. 📑' } }] }];
  }
  if (/chave pix|alterar.*chave|mudar.*chave/.test(t)) {
    return [{ from: 'bot', type: 'text', text: 'Sua chave Pix atual é o CPF. Quer trocar por celular, e‑mail ou aleatória? É só me dizer qual.', quick: ['Trocar para celular', 'Manter CPF'] }];
  }
  return [{ from: 'bot', type: 'text', text: 'Posso te dizer quando cai seu próximo Pix, quanto você recebeu, mandar comprovante ou avisar de contrato pra assinar. O que você quer saber?', quick: ['Quando cai meu próximo Pix?', 'Quanto recebi esse mês?', 'Falta eu assinar algo?'] }];
}

function actionReply(action) {
  switch (action.kind) {
    case 'pay': return [{ from: 'bot', type: 'success', text: 'Pix de R$ ' + PNH.fmt(action.amount) + ' enviado para ' + action.who + '. ✅', doc: 'Comprovante ' + lote() + '.pdf' }];
    case 'payAll': return [{ from: 'bot', type: 'success', text: action.count + ' Pix enviados, somando R$ ' + PNH.fmt(action.amount) + '. ✅ Cada parte já recebeu o comprovante.', doc: 'Lote ' + lote() }];
    case 'remind': return [{ from: 'bot', type: 'success', text: 'Lembrete enviado pro ' + action.who + ' assinar o contrato. 📲' }];
    case 'report': return [{ from: 'bot', type: 'success', text: 'Relatório de junho enviado pro seu contador. ✅ Coloquei você em cópia.' }];
    case 'sign': return [{ from: 'bot', type: 'success', text: 'Contrato da ' + action.who + ' assinado! ✍️ Agora é só aguardar o pagamento cair na sua conta.', doc: 'Contrato Lumen Co.pdf' }];
    case 'noop': return [{ from: 'bot', type: 'text', text: action.reply || 'Feito!' }];
    default: return [{ from: 'bot', type: 'text', text: 'Feito!' }];
  }
}

/* ---- message rendering ---- */
function AMsg({ m, onAction, onQuick }) {
  const me = m.from === 'me';
  return (
    <div className={'amsg' + (me ? ' me' : '')}>
      <div className={'aav ' + (me ? 'me' : 'bot')}>
        {me ? (m.acct || 'EU') : <Icon name="spark" size={18} color="#fff" />}
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
        {m.type === 'text' && <div className="abubble">{m.text}</div>}

        {m.type === 'stat' && (
          <div className="a-stat">
            <div className="lbl">{m.lbl}</div>
            <div className="val mono tnum">{m.val}</div>
            <div className="sub">{m.sub}</div>
            {m.chips && <div className="a-chips">{m.chips.map((c, i) => <span key={i}>{c}</span>)}</div>}
          </div>
        )}

        {m.type === 'cards' && (
          <div className="a-cards">
            {m.items.map((it, i) => (
              <div className="acard" key={i}>
                <Avatar name={it.name} size={34} />
                <div className="nm" style={{ fontWeight: 700, fontSize: 13.5, minWidth: 0 }}>{it.name}<small style={{ display: 'block', fontWeight: 500, color: 'var(--ink-3)', fontSize: 12 }}>{it.sub}</small></div>
                {it.amount != null
                  ? <div className="amt" style={{ fontSize: 13.5 }}>R$ {PNH.fmt(it.amount)}</div>
                  : <span className="amt"><Badge status={it.badge} /></span>}
                {it.action && <button className="btn btn-green btn-sm" style={{ padding: '6px 12px', marginLeft: 10 }} onClick={() => onAction(it.action)}>{it.action.label}</button>}
              </div>
            ))}
          </div>
        )}

        {m.type === 'action' && (
          <div className="a-action">
            <div className="row1">
              <span className="ic" style={{ width: 42, height: 42, borderRadius: 11, background: m.iconBg, display: 'grid', placeItems: 'center', flex: 'none' }}><Icon name={m.icon} size={20} color={m.iconColor} /></span>
              <div style={{ flex: 1, minWidth: 0 }}><div style={{ fontWeight: 800, fontSize: 15 }}>{m.title}</div><div className="sec mono" style={{ fontSize: 12 }}>{m.sub}</div></div>
              {m.amount != null && <div className="mono tnum" style={{ fontWeight: 800, fontSize: 18 }}>R$ {PNH.fmt(m.amount)}</div>}
            </div>
            <div className="lines">{m.lines.map((l, i) => <div key={i}>• {l}</div>)}</div>
            <div className="btns">
              {m.buttons.map((b, i) => (
                <button key={i} className={'btn btn-' + b.kind + ' btn-sm'} onClick={() => onAction(b.action)}>
                  {b.icon && <Icon name={b.icon} size={14} color={b.kind === 'green' || b.kind === 'primary' ? '#fff' : undefined} />} {b.label}
                </button>
              ))}
            </div>
          </div>
        )}

        {m.type === 'success' && (
          <div className="a-success">
            {m.text}
            {m.doc && <div className="a-doc"><Icon name="doc" size={15} color="var(--blue-600)" /> {m.doc} <Icon name="download" size={14} color="var(--ink-3)" /></div>}
          </div>
        )}

        {m.quick && <div className="aquick">{m.quick.map((q, i) => <button key={i} onClick={() => onQuick(q)}>{q}</button>)}</div>}
      </div>
    </div>
  );
}

function Assistant({ role }) {
  const acct = role === 'pj' ? 'EN' : 'MA';
  const seed = () => ([{
    from: 'bot', type: 'text',
    text: role === 'pj'
      ? 'Oi! Sou a Hora ⚡ sua assistente da Pago na Hora. Posso aprovar Pix, te dizer quanto você gastou, cobrar contrato pendente e fechar o relatório do contador.'
      : 'Oi! Sou a Hora ⚡ sua assistente. Posso te dizer quando cai seu próximo Pix, quanto você recebeu, mandar comprovante e avisar de contrato pra assinar.',
    quick: role === 'pj'
      ? ['O que falta aprovar?', 'Quanto paguei em junho?', 'Quem não assinou contrato?']
      : ['Quando cai meu próximo Pix?', 'Quanto recebi esse mês?', 'Falta eu assinar algo?'],
  }]);

  const [msgs, setMsgs] = useState(seed);
  const [typing, setTyping] = useState(false);
  const [input, setInput] = useState('');
  const streamRef = useRef(null);

  useEffect(() => {
    const el = streamRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [msgs, typing]);

  const push = m => setMsgs(x => [...x, m]);

  const botReply = (replies) => {
    setTyping(true);
    setTimeout(() => {
      setTyping(false);
      replies.forEach((r, i) => setTimeout(() => push({ ...r, acct }), i * 520));
    }, 650 + Math.random() * 400);
  };

  const send = (text) => {
    if (!text.trim()) return;
    push({ from: 'me', type: 'text', text, acct });
    setInput('');
    botReply(respond(text, role));
  };

  const doAction = (action) => {
    push({ from: 'me', type: 'text', text: action.userEcho || action.label, acct });
    botReply(actionReply(action));
  };

  const suggestions = role === 'pj'
    ? ['O que falta aprovar?', 'Paga a Marina', 'Quem não assinou contrato?', 'Gera o relatório pro contador']
    : ['Quando cai meu próximo Pix?', 'Manda meu comprovante da Lumen', 'Falta eu assinar algo?'];

  return (
    <div className="asst">
      <div className="asst-stream" ref={streamRef}>
        <div className="asst-inner">
          {msgs.map((m, i) => <AMsg key={i} m={m} onAction={doAction} onQuick={send} />)}
          {typing && (
            <div className="amsg">
              <div className="aav bot"><Icon name="spark" size={18} color="#fff" /></div>
              <div className="atyping"><i></i><i></i><i></i></div>
            </div>
          )}
        </div>
      </div>
      <div className="asst-foot">
        <div className="inner">
          <div className="asst-suggest">
            {suggestions.map((s, i) => <button key={i} onClick={() => send(s)}>{s}</button>)}
          </div>
          <div className="asst-input">
            <Icon name="spark" size={18} color="var(--violet)" />
            <input value={input} onChange={e => setInput(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') send(input); }} placeholder={role === 'pj' ? 'Peça pra Hora aprovar, pagar, cobrar…' : 'Pergunte sobre seus recebimentos…'} />
            <button className="snd" disabled={!input.trim()} onClick={() => send(input)}><Icon name="send" size={18} color="#fff" /></button>
          </div>
        </div>
      </div>
    </div>
  );
}

window.Assistant = Assistant;
