/* global React, Icon, Button, Card, brl */

// ─── Dashboard · Faixa HOJE + alertas honestos ───────────────────────────────
// O dashboard antigo mostrava 59 "críticos" — 50 deles produtos de venda sem
// estoque numa base que NUNCA foi contada. Alerta que mente treina a ignorar
// alerta, e os 2 insumos zerados (esses SIM confiáveis — a OP sempre baixou)
// sumiam no meio. Aqui a hierarquia é por CONFIABILIDADE e AÇÃO, não por
// quantidade.

// Percentual só com base mínima: "+566,7%" sobre 3 clientes impressiona e não
// informa. Abaixo do corte, mostra o absoluto e a variação em unidades.
const PCT_BASE_MIN = 10;
function fmtVariacao(atual, anterior) {
  const a = Number(atual) || 0, b = Number(anterior) || 0;
  const dif = a - b;
  if (b < PCT_BASE_MIN) {
    if (!dif) return { texto: 'estável', tone: 'up' };
    return { texto: `${dif > 0 ? '+' : ''}${dif} vs ${b}`, tone: dif >= 0 ? 'up' : 'down' };
  }
  const pct = (dif / b) * 100;
  return { texto: `${pct > 0 ? '+' : ''}${pct.toFixed(1)}%`, tone: pct >= 0 ? 'up' : 'down' };
}

const hojeIsoDash = () => new Date().toISOString().slice(0, 10);

// ── Faixa 1 · HOJE ──────────────────────────────────────────────────────────
// O que muda o que ela faz AGORA. Cada item leva à tela que resolve.
function FaixaHoje({ onNav }) {
  const [d, setD] = React.useState(null);
  const [erro, setErro] = React.useState('');

  const carregar = React.useCallback(async () => {
    if (!window.tmSupabase) return;
    setErro('');
    const sb = window.tmSupabase;
    const hoje = hojeIsoDash();
    try {
      const [rec, cob, ped, ops, bal, pcs] = await Promise.all([
        sb.from('contas_receber').select('valor, valor_recebido, vencimento').eq('status', 'Em aberto').lte('vencimento', hoje),
        sb.from('cobrancas').select('id, valor, metodo').eq('status', 'pendente'),
        sb.from('pedidos').select('id, transportador').eq('status', 'Atendido'),
        sb.from('ordens_producao').select('id, numero, status, data_prevista').in('status', ['enviada', 'em_producao']),
        sb.from('balancos').select('id, numero, status').in('status', ['aberto', 'contado']),
        sb.from('pedidos_compra').select('id, numero, status, nf_entrada_chave').in('status', ['recebido', 'recebido_parcial']),
      ]);
      const titulos = rec.data || [];
      const saldo = titulos.reduce((a, t) => a + ((Number(t.valor) || 0) - (Number(t.valor_recebido) || 0)), 0);
      const vencidos = titulos.filter(t => String(t.vencimento || '') < hoje).length;
      // etiqueta: cotação aplicada e etiqueta não comprada (jsonb → filtra aqui)
      const semEtiqueta = (ped.data || []).filter(p => {
        const t = p.transportador || {};
        return t.me_servico_id && !t.me_etiqueta_id;
      }).length;
      const opsAtrasadas = (ops.data || []).filter(o => o.data_prevista && String(o.data_prevista) < hoje).length;
      const comprasSemNota = (pcs.data || []).filter(p => !String(p.nf_entrada_chave || '').trim()).length;
      setD({
        titulos: { n: titulos.length, vencidos, valor: saldo },
        cobrancas: { n: (cob.data || []).length, valor: (cob.data || []).reduce((a, c) => a + (Number(c.valor) || 0), 0) },
        semEtiqueta,
        ops: { n: (ops.data || []).length, atrasadas: opsAtrasadas },
        balancos: (bal.data || []).length,
        comprasSemNota,
      });
    } catch (e) { setErro(String((e && e.message) || e)); }
  }, []);

  React.useEffect(() => { carregar(); }, [carregar]);

  if (erro) {
    return (
      <Card title="Hoje">
        <div style={{ padding: '18px 4px', fontSize: 12.5, color: 'var(--tm-fg-3)' }}>
          Não consegui carregar as pendências de hoje. <a href="#" onClick={(e) => { e.preventDefault(); carregar(); }}
            style={{ color: 'var(--tm-brand-champagne)' }}>Tentar de novo</a>
        </div>
      </Card>
    );
  }
  if (!d) {
    return <Card title="Hoje"><div style={{ padding: '18px 4px', fontSize: 12.5, color: 'var(--tm-fg-4)' }}>Carregando…</div></Card>;
  }

  const itens = [];
  if (d.titulos.n > 0) itens.push({
    icon: 'alert-triangle', tone: d.titulos.vencidos > 0 ? 'danger' : 'warning',
    valor: `R$ ${brl(d.titulos.valor)}`,
    label: d.titulos.vencidos > 0
      ? `${d.titulos.vencidos} título${d.titulos.vencidos > 1 ? 's' : ''} vencido${d.titulos.vencidos > 1 ? 's' : ''}${d.titulos.n > d.titulos.vencidos ? ` · ${d.titulos.n - d.titulos.vencidos} vence hoje` : ''}`
      : `${d.titulos.n} vencendo hoje`,
    nav: 'financeiro/contas-receber',
  });
  if (d.cobrancas.n > 0) itens.push({
    icon: 'qr-code', tone: 'info', valor: `R$ ${brl(d.cobrancas.valor)}`,
    label: `${d.cobrancas.n} cobrança${d.cobrancas.n > 1 ? 's' : ''} aguardando pagamento`,
    nav: 'financeiro/contas-receber',
  });
  if (d.semEtiqueta > 0) itens.push({
    icon: 'truck', tone: 'warning', valor: String(d.semEtiqueta),
    label: `pedido${d.semEtiqueta > 1 ? 's' : ''} com frete cotado sem etiqueta`,
    nav: 'pedidos/faturados',
  });
  if (d.ops.atrasadas > 0) itens.push({
    icon: 'factory', tone: 'danger', valor: String(d.ops.atrasadas),
    label: `ordem${d.ops.atrasadas > 1 ? 'ns' : ''} de produção atrasada${d.ops.atrasadas > 1 ? 's' : ''}`,
    nav: 'estoque/producao',
  });
  else if (d.ops.n > 0) itens.push({
    icon: 'factory', tone: 'info', valor: String(d.ops.n),
    label: `ordem${d.ops.n > 1 ? 'ns' : ''} de produção em andamento`, nav: 'estoque/producao',
  });
  if (d.comprasSemNota > 0) itens.push({
    icon: 'file-down', tone: 'warning', valor: String(d.comprasSemNota),
    label: `compra${d.comprasSemNota > 1 ? 's' : ''} recebida${d.comprasSemNota > 1 ? 's' : ''} sem nota lançada`,
    nav: 'nf/entradas',
  });
  if (d.balancos > 0) itens.push({
    icon: 'clipboard-check', tone: 'warning', valor: String(d.balancos),
    label: `balanço${d.balancos > 1 ? 's' : ''} aberto${d.balancos > 1 ? 's' : ''} sem aplicar`,
    nav: 'estoque/balanco',
  });

  const cor = (t) => t === 'danger' ? 'var(--tm-danger)' : t === 'warning' ? 'var(--tm-warning)' : 'var(--tm-info)';

  return (
    <Card title="Hoje" right={<Button variant="ghost" size="sm" icon="refresh-cw" onClick={carregar} title="Atualizar" />}>
      {itens.length === 0 ? (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 4px' }}>
          <Icon name="check-circle" size={18} style={{ color: 'var(--tm-success)' }} />
          <div style={{ fontSize: 13.5 }}>
            <b>Nada pendente hoje.</b>{' '}
            <span style={{ color: 'var(--tm-fg-3)' }}>Sem títulos vencendo, cobranças aguardando, envios ou produção em atraso.</span>
          </div>
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: `repeat(${Math.min(itens.length, 4)}, 1fr)`, gap: 10 }}>
          {itens.map((it, i) => (
            <div key={i} onClick={() => onNav(it.nav)} className="clickable"
              style={{ cursor: 'pointer', padding: '11px 13px', borderRadius: 8, background: 'var(--tm-bg-2)',
                       border: '1px solid var(--tm-line-1)', borderLeft: `3px solid ${cor(it.tone)}` }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 7, marginBottom: 3 }}>
                <Icon name={it.icon} size={13} style={{ color: cor(it.tone) }} />
                <span style={{ fontSize: 17, fontWeight: 700, color: 'var(--tm-fg-1)', fontVariantNumeric: 'tabular-nums' }}>{it.valor}</span>
              </div>
              <div style={{ fontSize: 11.5, color: 'var(--tm-fg-3)', lineHeight: 1.4 }}>{it.label}</div>
            </div>
          ))}
        </div>
      )}
    </Card>
  );
}

// ── Alertas por CONFIABILIDADE ──────────────────────────────────────────────
// Insumo primeiro (confiável: a OP sempre baixou). Produto de venda agrupado
// numa linha só, com a ressalva e o convite pro Balanço — que é a solução real.
const TETO_GRUPO = 5;

function AlertasOperacao({ onNav }) {
  const [d, setD] = React.useState(null);
  const [erro, setErro] = React.useState('');

  const carregar = React.useCallback(async () => {
    if (!window.tmSupabase) return;
    setErro('');
    const sb = window.tmSupabase;
    const hoje = hojeIsoDash();
    const ha5 = new Date(Date.now() - 5 * 86400000).toISOString();
    try {
      const [zerados, baixos, venc, travados, semCusto] = await Promise.all([
        sb.from('produtos').select('nome, sku, tipo').or('estoque.eq.0,estoque.is.null'),
        sb.from('produtos').select('nome, sku, tipo, estoque, estoque_minimo').gt('estoque', 0),
        sb.from('contas_receber').select('referencia, cliente_nome, valor, valor_recebido, vencimento').eq('status', 'Em aberto').lt('vencimento', hoje),
        sb.from('pedidos').select('numero, cliente_nome, created_at').eq('status', 'Em andamento').lt('created_at', ha5),
        sb.from('produtos').select('nome, sku, tipo').or('custo.eq.0,custo.is.null'),
      ]);
      const ehIns = (p) => (p.tipo || 'venda') === 'insumo';
      const zer = zerados.data || [];
      const abaixo = (baixos.data || []).filter(p => Number(p.estoque_minimo) > 0 && Number(p.estoque) <= Number(p.estoque_minimo));
      setD({
        insumosZerados: zer.filter(ehIns),
        vendaZerados: zer.filter(p => !ehIns(p)),
        insumosBaixos: abaixo.filter(ehIns),
        vendaBaixos: abaixo.filter(p => !ehIns(p)),
        vencidos: venc.data || [],
        travados: travados.data || [],
        insumosSemCusto: (semCusto.data || []).filter(ehIns),
      });
    } catch (e) { setErro(String((e && e.message) || e)); }
  }, []);

  React.useEffect(() => { carregar(); }, [carregar]);

  if (erro) return (
    <Card title="Alertas">
      <div style={{ padding: '16px 4px', fontSize: 12.5, color: 'var(--tm-fg-3)' }}>
        Não consegui carregar os alertas. <a href="#" onClick={(e) => { e.preventDefault(); carregar(); }}
          style={{ color: 'var(--tm-brand-champagne)' }}>Tentar de novo</a>
      </div>
    </Card>
  );
  if (!d) return <Card title="Alertas"><div style={{ padding: '16px 4px', fontSize: 12.5, color: 'var(--tm-fg-4)' }}>Carregando…</div></Card>;

  const saldoVenc = d.vencidos.reduce((a, c) => a + ((Number(c.valor) || 0) - (Number(c.valor_recebido) || 0)), 0);
  const linhas = [];

  // 1) CONFIÁVEL: insumo. A produção baixa insumo desde sempre — falta aqui é real.
  if (d.insumosZerados.length) linhas.push({
    tone: 'danger', icon: 'package-x', confiavel: true,
    titulo: `${d.insumosZerados.length} insumo${d.insumosZerados.length > 1 ? 's' : ''} sem estoque`,
    itens: d.insumosZerados.slice(0, TETO_GRUPO).map(p => `${p.nome} (${p.sku})`),
    resto: Math.max(0, d.insumosZerados.length - TETO_GRUPO),
    acao: { label: 'Ver insumos', nav: 'produtos/insumos' },
  });
  if (d.insumosBaixos.length) linhas.push({
    tone: 'warning', icon: 'package', confiavel: true,
    titulo: `${d.insumosBaixos.length} insumo${d.insumosBaixos.length > 1 ? 's' : ''} abaixo do mínimo`,
    itens: d.insumosBaixos.slice(0, TETO_GRUPO).map(p => `${p.nome} — ${p.estoque} un.`),
    resto: Math.max(0, d.insumosBaixos.length - TETO_GRUPO),
    acao: { label: 'Sugestão de compra', nav: 'estoque/sugestao' },
  });
  if (d.insumosSemCusto.length) linhas.push({
    tone: 'warning', icon: 'dollar-sign', confiavel: true,
    titulo: `${d.insumosSemCusto.length} insumo${d.insumosSemCusto.length > 1 ? 's' : ''} sem custo cadastrado`,
    itens: d.insumosSemCusto.slice(0, TETO_GRUPO).map(p => `${p.nome} (${p.sku})`),
    resto: Math.max(0, d.insumosSemCusto.length - TETO_GRUPO),
    acao: { label: 'Ver insumos', nav: 'produtos/insumos' },
    nota: 'Sem custo, a nota de remessa e a ficha técnica saem sem valor.',
  });

  // 2) DINHEIRO
  if (d.vencidos.length) linhas.push({
    tone: 'danger', icon: 'alert-triangle', confiavel: true,
    titulo: `${d.vencidos.length} título${d.vencidos.length > 1 ? 's' : ''} vencido${d.vencidos.length > 1 ? 's' : ''} · R$ ${brl(saldoVenc)}`,
    itens: d.vencidos.slice(0, TETO_GRUPO).map(c => `${c.referencia || c.cliente_nome} — R$ ${brl((Number(c.valor) || 0) - (Number(c.valor_recebido) || 0))}`),
    resto: Math.max(0, d.vencidos.length - TETO_GRUPO),
    acao: { label: 'Contas a receber', nav: 'financeiro/contas-receber' },
  });
  if (d.travados.length) linhas.push({
    tone: 'warning', icon: 'clock', confiavel: true,
    titulo: `${d.travados.length} pedido${d.travados.length > 1 ? 's' : ''} parado${d.travados.length > 1 ? 's' : ''} há mais de 5 dias`,
    itens: d.travados.slice(0, TETO_GRUPO).map(p => `${p.numero} — ${p.cliente_nome || 'sem cliente'}`),
    resto: Math.max(0, d.travados.length - TETO_GRUPO),
    acao: { label: 'Pedidos em aberto', nav: 'pedidos/abertos' },
  });

  const nVenda = d.vendaZerados.length + d.vendaBaixos.length;

  return (
    <Card title="Alertas" right={<Button variant="ghost" size="sm" icon="refresh-cw" onClick={carregar} title="Atualizar" />}>
      {linhas.length === 0 && nVenda === 0 && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 4px' }}>
          <Icon name="check-circle" size={18} style={{ color: 'var(--tm-success)' }} />
          <div style={{ fontSize: 13.5 }}><b>Nenhum alerta.</b> <span style={{ color: 'var(--tm-fg-3)' }}>Estoque, títulos e pedidos em dia.</span></div>
        </div>
      )}

      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {linhas.map((l, i) => (
          <div key={i} style={{ padding: '10px 12px', borderRadius: 8, background: 'var(--tm-bg-2)',
                                border: '1px solid var(--tm-line-1)', borderLeft: `3px solid var(--tm-${l.tone})` }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
              <Icon name={l.icon} size={14} style={{ color: `var(--tm-${l.tone})` }} />
              <span style={{ fontSize: 13, fontWeight: 600 }}>{l.titulo}</span>
              <span style={{ flex: 1 }} />
              <Button variant="ghost" size="sm" onClick={() => onNav(l.acao.nav)}>{l.acao.label}</Button>
            </div>
            <div style={{ fontSize: 11.5, color: 'var(--tm-fg-3)', marginTop: 4, lineHeight: 1.6 }}>
              {l.itens.join(' · ')}{l.resto > 0 ? ` · +${l.resto}` : ''}
              {l.nota && <div style={{ marginTop: 2, color: 'var(--tm-fg-4)' }}>{l.nota}</div>}
            </div>
          </div>
        ))}

        {/* 3) NÃO CONFIÁVEL: produto de venda. Uma linha só, com a ressalva e o
            caminho da solução — nunca 50 linhas fingindo urgência. */}
        {nVenda > 0 && (
          <div style={{ padding: '10px 12px', borderRadius: 8, background: 'var(--tm-bg-2)',
                        border: '1px dashed var(--tm-line-2)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
              <Icon name="help-circle" size={14} style={{ color: 'var(--tm-fg-4)' }} />
              <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--tm-fg-2)' }}>
                {d.vendaZerados.length} produto{d.vendaZerados.length !== 1 ? 's' : ''} de venda sem estoque
                {d.vendaBaixos.length > 0 ? ` · ${d.vendaBaixos.length} abaixo do mínimo` : ''}
              </span>
              <span style={{ flex: 1 }} />
              <Button variant="secondary" size="sm" icon="clipboard-check" onClick={() => onNav('estoque/balanco')}>Fazer balanço</Button>
            </div>
            <div style={{ fontSize: 11.5, color: 'var(--tm-fg-4)', marginTop: 4, lineHeight: 1.5 }}>
              Número <b>não confiável</b>: o estoque de venda nunca foi contado — vendas B2B antigas não baixaram.
              O balanço corrige de uma vez; até lá, este número não é alerta.
            </div>
          </div>
        )}
      </div>
    </Card>
  );
}

// ── Painel por pessoa: seletor rápido (CONVENIÊNCIA, não segurança) ─────────
// ⚠️ Isto NÃO é controle de acesso — as permissões de verdade não são aplicadas
// (item conhecido da fila). É só qual painel a pessoa vê por padrão, e qualquer
// um abre o completo num clique. Reusa os PRESETS que o Dashboard já tem (e a
// persistência que já existe em dashboard_preferencias) — nada de um segundo
// sistema paralelo de visibilidade.
function presetSugerido(profile) {
  const p = String((profile && (profile.perfil || profile.cargo)) || '').toLowerCase();
  if (p.indexOf('admin') >= 0 || p.indexOf('gestor') >= 0 || p.indexOf('diretor') >= 0) return 'completo';
  if (p.indexOf('financ') >= 0) return 'financeiro';
  if (p.indexOf('vend') >= 0 || p.indexOf('comercial') >= 0 || p.indexOf('represent') >= 0) return 'comercial';
  if (p.indexOf('estoq') >= 0 || p.indexOf('produ') >= 0 || p.indexOf('logi') >= 0 || p.indexOf('expedi') >= 0) return 'operacional';
  return 'completo';
}

// Qual preset corresponde ao conjunto de widgets atual (pra o seletor refletir
// a realidade em vez de mentir um rótulo).
function presetAtual(widgets, presets) {
  const w = [...(widgets || [])].sort().join(',');
  const achado = Object.keys(presets).find(k => [...presets[k].widgets].sort().join(',') === w);
  return achado || 'personalizado';
}

function SeletorPainel({ presets, atual, onEscolher }) {
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
      <span style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>Painel:</span>
      <select className="input" value={atual} onChange={(e) => onEscolher(e.target.value)}
        title="Preferência de exibição — não altera permissões de acesso"
        style={{ height: 30, padding: '0 8px', fontSize: 12, width: 'auto' }}>
        {atual === 'personalizado' && <option value="personalizado">Personalizado</option>}
        {Object.keys(presets).map(k => <option key={k} value={k}>{presets[k].label}</option>)}
      </select>
    </div>
  );
}

Object.assign(window, { FaixaHoje, AlertasOperacao, SeletorPainel, presetSugerido, presetAtual, fmtVariacao, PCT_BASE_MIN });
