/* global React, Icon, Card, PageHead, Button, EmptyState, brl, fmtDate,
          NATUREZAS_RECEITA, naturezaLabel, naturezaEhReceita */

// ============================================================
// Financeiro › Entradas › Classificar
// ============================================================
// Existe porque 37 títulos precisam do olho dela, e 37 um a um é o número em
// que a correção não acontece — o próprio diagnóstico disse isso.
//
// 🔴 CLASSIFICAR NÃO MEXE EM SALDO, E ISSO É ESTRUTURAL.
// Esta tela grava UMA coluna: `natureza`. Não toca `conta_id`, `valor`,
// `valor_recebido` nem `status`, que são as únicas que o `saldoDaConta`
// (Contas.jsx:38) lê. O saldo das quatro contas é o mesmo antes e depois.
// ⚠️ MOVER de verdade — transferência virar `transferencias`, aporte virar
// `emprestimo_distribuicao` — é a rodada B, e LÁ o saldo vai cair. É o que se
// espera: hoje o app mostra mais dinheiro do que o banco.

const NAT_FILTROS = [
  { id: 'sem',  label: 'Sem natureza' },
  { id: 'com',  label: 'Já classificados' },
  { id: 'tudo', label: 'Todos' },
];

function NatChip({ nat }) {
  if (!nat) {
    // "— precisa de você" no lugar da sugestão, não célula vazia: ausência com
    // nome, nunca símbolo de falta (CLAUDE.md § 7).
    return <span style={{ fontSize: 11, padding: '2px 8px', borderRadius: 20,
      border: '1px solid var(--tm-line-2)', color: 'var(--tm-fg-4)' }}>— precisa de você</span>;
  }
  const receita = naturezaEhReceita(nat);
  return <span style={{ fontSize: 11, padding: '2px 8px', borderRadius: 20,
    background: receita ? 'rgba(201,169,97,.13)' : 'rgba(95,179,122,.13)',
    border: '1px solid ' + (receita ? 'var(--tm-brand-champagne)' : 'var(--tm-success)'),
    color: receita ? 'var(--tm-brand-champagne)' : 'var(--tm-success)' }}>{naturezaLabel(nat)}</span>;
}

function ClassificarEntradas() {
  const [linhas, setLinhas] = React.useState(null);
  const [filtro, setFiltro] = React.useState('sem');
  const [busca, setBusca]   = React.useState('');
  const [marcados, setMarcados] = React.useState({});   // { id: true }
  const [aplicando, setAplicando] = React.useState(false);
  const [erro, setErro] = React.useState('');
  const [recarga, setRecarga] = React.useState(0);      // chave estável, nunca relógio

  React.useEffect(() => {
    let vivo = true;
    if (!window.tmSupabase) return undefined;
    setLinhas(null); setErro('');
    Promise.all([
      window.tmSupabase.from('contas_receber')
        .select('id, referencia, cliente_nome, observacoes, valor, valor_recebido, status, conta_id, data_pagamento, natureza')
        .is('pedido_id', null).order('data_pagamento', { ascending: false }),
      window.tmSupabase.from('contas_bancarias').select('id, nome'),
    ]).then(([cr, cb]) => {
      if (!vivo) return;
      if (cr.error) { setErro(cr.error.message || String(cr.error)); setLinhas([]); return; }
      const nomeConta = {};
      (cb.data || []).forEach(c => { nomeConta[c.id] = c.nome; });
      setLinhas((cr.data || []).map(r => ({ ...r, _conta: nomeConta[r.conta_id] || '—' })));
    }).catch(e => { if (vivo) { setErro(String((e && e.message) || e)); setLinhas([]); } });
    return () => { vivo = false; };
  }, [recarga]);

  const visiveis = React.useMemo(() => {
    const q = busca.trim().toLowerCase();
    return (linhas || []).filter(r => {
      if (filtro === 'sem' && r.natureza) return false;
      if (filtro === 'com' && !r.natureza) return false;
      if (!q) return true;
      return ((r.referencia || '') + ' ' + (r.cliente_nome || '') + ' ' + (r.observacoes || ''))
        .toLowerCase().includes(q);
    });
  }, [linhas, filtro, busca]);

  const sel = visiveis.filter(r => marcados[r.id]);
  const somaSel = sel.reduce((a, r) => a + (Number(r.valor_recebido || r.valor) || 0), 0);
  const semNatureza = (linhas || []).filter(r => !r.natureza);
  const somaSem = semNatureza.reduce((a, r) => a + (Number(r.valor_recebido || r.valor) || 0), 0);

  const todosMarcados = visiveis.length > 0 && visiveis.every(r => marcados[r.id]);
  const marcarTodos = () => {
    const m = { ...marcados };
    visiveis.forEach(r => { if (todosMarcados) delete m[r.id]; else m[r.id] = true; });
    setMarcados(m);
  };

  // 🔴 `natureza` pode voltar a NULL, e não é detalhe: sem isso, marcar errado
  // seria irreversível pela tela e ela teria que escolher entre uma natureza
  // errada e outra. "Ainda não sei" é um estado legítimo, não a ausência de um.
  const aplicar = async (nat) => {
    if (!sel.length || !window.tmSupabase) return;
    setAplicando(true); setErro('');
    const ids = sel.map(r => r.id);
    // Só a coluna `natureza`. Nada de `valor`, `status` ou `conta_id` — é o que
    // torna "classificar não mexe em saldo" verdade por construção.
    const patch = nat === '' ? { natureza: null, devolucao_de_pagar_id: null } : { natureza: nat };
    const { error } = await window.tmSupabase.from('contas_receber').update(patch).in('id', ids);
    setAplicando(false);
    if (error) { setErro('Não consegui gravar: ' + (error.message || error)); return; }
    setMarcados({}); setRecarga(k => k + 1);
  };

  return (
    <div className="canvas">
      <PageHead title="Classificar entradas"
        sub="o que não é venda sai da receita do DRE de caixa" />

      {/* A frase mais importante da tela vem antes de tudo: o medo legítimo é
          "mexer nisso quebra meu saldo". */}
      <div style={{ display: 'flex', gap: 9, alignItems: 'flex-start', marginBottom: 18,
                    background: 'var(--tm-bg-2)', border: '1px solid var(--tm-line-2)',
                    borderLeft: '3px solid var(--tm-success)', borderRadius: 7,
                    padding: '11px 15px', fontSize: 12.5, color: 'var(--tm-fg-2)', lineHeight: 1.7 }}>
        <Icon name="check-circle" size={15} style={{ flexShrink: 0, marginTop: 2, color: 'var(--tm-success)' }} />
        <span>
          <b>Classificar aqui não mexe em saldo nenhum.</b> A natureza diz o que o dinheiro
          <i> é</i>; ela não move, não apaga e não muda valor. O saldo das quatro contas
          continua exatamente o mesmo depois de você classificar tudo.
          <div style={{ marginTop: 4, color: 'var(--tm-fg-4)' }}>
            Mover de fato — transferência virar transferência, aporte virar aporte — é o passo
            seguinte, e lá o saldo <b>vai</b> cair. É o que se espera: hoje o app mostra mais
            dinheiro do que o banco.
          </div>
        </span>
      </div>

      <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap', marginBottom: 14 }}>
        <input className="input" style={{ width: 260 }} value={busca}
          onChange={(e) => setBusca(e.target.value)}
          placeholder="Buscar por nome ou referência…" />
        {NAT_FILTROS.map(f => (
          <button key={f.id} onClick={() => { setFiltro(f.id); setMarcados({}); }}
            style={{
              background: filtro === f.id ? 'rgba(201,169,97,.12)' : 'var(--tm-bg-2)',
              border: '1px solid ' + (filtro === f.id ? 'var(--tm-brand-champagne)' : 'var(--tm-line-2)'),
              color: filtro === f.id ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-2)',
              borderRadius: 7, padding: '7px 12px', fontSize: 12.5, cursor: 'pointer',
            }}>
            {f.label}{f.id === 'sem' && semNatureza.length ? ` (${semNatureza.length})` : ''}
          </button>
        ))}
        <span style={{ flex: 1 }} />
        <span className="muted" style={{ fontSize: 12.5 }}>
          {visiveis.length} título(s){filtro === 'sem' ? ` · R$ ${brl(somaSem)}` : ''}
        </span>
      </div>

      {erro && (
        <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start', fontSize: 12.5,
                      color: 'var(--tm-danger)', marginBottom: 12 }}>
          <Icon name="alert-triangle" size={15} style={{ flexShrink: 0, marginTop: 1 }} />
          <span>{erro}</span>
        </div>
      )}

      {linhas === null ? (
        <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tm-fg-3)' }}>
          <Icon name="loader" size={20} style={{ opacity: .4 }} />
        </div>
      ) : visiveis.length === 0 ? (
        <EmptyState icon="check-circle"
          title={filtro === 'sem' ? 'Nada pendente de classificação' : 'Nenhum título aqui'}
          msg={filtro === 'sem'
            ? 'Todas as entradas sem pedido já têm natureza.'
            : 'Mude o filtro ou a busca.'} />
      ) : (
        <Card>
          <table className="tbl pc-itens" style={{ fontSize: 12.5 }}>
            <colgroup>
              <col style={{ width: 38 }} /><col /><col style={{ width: 130 }} />
              <col style={{ width: 110 }} /><col style={{ width: 80 }} /><col style={{ width: 170 }} />
            </colgroup>
            <thead><tr>
              <th style={{ textAlign: 'center' }}>
                <input type="checkbox" checked={todosMarcados} onChange={marcarTodos}
                  title={todosMarcados ? 'Desmarcar os visíveis' : 'Marcar todos os visíveis'} />
              </th>
              <th>Título</th><th>Conta</th>
              <th className="num right">Valor</th><th className="num right">Recebido</th>
              <th>Natureza</th>
            </tr></thead>
            <tbody>
              {visiveis.map(r => (
                <tr key={r.id} style={marcados[r.id] ? { background: 'rgba(201,169,97,.06)' } : undefined}>
                  <td style={{ textAlign: 'center' }}>
                    <input type="checkbox" checked={!!marcados[r.id]}
                      onChange={() => setMarcados(m => {
                        const n = { ...m }; if (n[r.id]) delete n[r.id]; else n[r.id] = true; return n;
                      })} />
                  </td>
                  <td className="trunca" title={(r.referencia || '') + ' · ' + (r.cliente_nome || '')}>
                    {r.referencia || r.cliente_nome || '(sem texto)'}
                    {r.referencia && r.cliente_nome && (
                      <div className="muted" style={{ fontSize: 10.5 }}>{r.cliente_nome}</div>
                    )}
                  </td>
                  <td className="muted trunca" title={r._conta}>{r._conta}</td>
                  <td className="num right">R$ {brl(r.valor_recebido || r.valor)}</td>
                  <td className="num right muted">{r.data_pagamento ? fmtDate(r.data_pagamento) : '—'}</td>
                  <td><NatChip nat={r.natureza} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      )}

      {/* Barra de ação — só aparece com seleção. Ela mostra o dinheiro ANTES do
          clique e repete que o saldo não muda, porque é a pergunta que ela vai
          fazer toda vez, e a resposta tem que estar onde o clique acontece. */}
      {sel.length > 0 && (
        <div style={{ position: 'sticky', bottom: 0, marginTop: 14,
                      background: 'var(--tm-bg-1)', border: '1px solid var(--tm-line-2)',
                      borderRadius: 10, padding: '13px 16px' }}>
          <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
            <span style={{ fontSize: 13 }}>
              Selecionados: <b style={{ color: 'var(--tm-brand-champagne)' }}>
                {sel.length} título(s) · R$ {brl(somaSel)}</b>
            </span>
            <span style={{ flex: 1 }} />
            {NATUREZAS_RECEITA.map(n => (
              <Button key={n.id} size="sm" variant="secondary" disabled={aplicando}
                title={n.ajuda} onClick={() => aplicar(n.id)}>{n.label}</Button>
            ))}
            <Button size="sm" variant="ghost" disabled={aplicando}
              title="Volta para 'sem natureza' — 'ainda não sei' é um estado legítimo"
              onClick={() => aplicar('')}>Limpar natureza</Button>
            <Button size="sm" variant="ghost" onClick={() => setMarcados({})}>Desmarcar</Button>
          </div>
          <div style={{ marginTop: 6, fontSize: 12, color: 'var(--tm-fg-3)', lineHeight: 1.65 }}>
            Marcando como algo que não é venda, esses <b>R$ {brl(somaSel)}</b> saem da receita
            do DRE de caixa. <b>O saldo das contas não muda</b> — nenhum dinheiro é movido aqui.
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { ClassificarEntradas });
