/* global window */
/* ============================================================
   Central de Agentes — modelo de dados
   Agentes (esteiras), MCPs (tools globais), edges (pipeline),
   parque de LLMs, execuções, resultados e prompts versionados.
   ============================================================ */

// ---------- Formatadores pt-BR ----------
const fmtBRL = (n) =>
  new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(n);
const fmtNum = (n) => new Intl.NumberFormat("pt-BR").format(n);
const fmtTokens = (n) => {
  if (n >= 1e6) return (n / 1e6).toFixed(2).replace(".", ",") + "M";
  if (n >= 1e3) return (n / 1e3).toFixed(1).replace(".", ",") + "k";
  return String(n);
};

// ---------- Status / semáforo ----------
const STATUS = {
  ok:    { key: "ok",    label: "Operacional", orb: "#5fd0a6", glow: "rgba(95,208,166,.5)",   fg: "#15803d", bg: "#ecfdf3", ring: "#bbf7d0" },
  warn:  { key: "warn",  label: "Atenção",     orb: "#e3b25b", glow: "rgba(227,178,91,.5)",   fg: "#92400e", bg: "#fffbeb", ring: "#fde68a" },
  error: { key: "error", label: "Falha",       orb: "#e07a82", glow: "rgba(224,122,130,.55)", fg: "#b91c1c", bg: "#fef2f2", ring: "#fecaca" },
};

// ---------- Parque de LLMs ----------
const LLMS = {
  "gpt-4o":   { id: "gpt-4o",   name: "GPT-4o",          vendor: "OpenAI",            ctx: "128K", costIn: 2.50, costOut: 10.00, speed: "Rápido", color: "#10a37f", glyph: "AI" },
  "claude":   { id: "claude",   name: "Claude Sonnet 4", vendor: "Anthropic",         ctx: "200K", costIn: 3.00, costOut: 15.00, speed: "Equilibrado", color: "#d97757", glyph: "✳" },
  "gemini":   { id: "gemini",   name: "Gemini 1.5 Pro",  vendor: "Google",            ctx: "1M",   costIn: 1.25, costOut: 5.00,  speed: "Rápido", color: "#3f7df6", glyph: "◆" },
  "deepseek": { id: "deepseek", name: "DeepSeek V3",     vendor: "DeepSeek",          ctx: "64K",  costIn: 0.27, costOut: 1.10,  speed: "Econômico", color: "#4d6bfe", glyph: "🜨" },
  "llama":    { id: "llama",    name: "Llama 3.1 70B",   vendor: "Local · on-premise",ctx: "128K", costIn: 0.00, costOut: 0.00,  speed: "Privado", color: "#8b5cf6", glyph: "△" },
};
const LLM_LIST = ["gpt-4o", "claude", "gemini", "deepseek", "llama"];

// ---------- helpers de geração ----------
function spark(seed, n = 24, base = 50, amp = 30) {
  const out = [];
  let s = seed;
  for (let i = 0; i < n; i++) {
    s = (s * 9301 + 49297) % 233280;
    const r = s / 233280;
    out.push(Math.max(4, Math.round(base + Math.sin(i / 2.4 + seed) * amp * 0.5 + (r - 0.5) * amp)));
  }
  return out;
}
const ago = (label) => label;

// MCP icon = nome lucide; "fig" controla a microanimação (spin | bob | pulse | orbit)
function mcp(id, name, icon, status, fig, latency) {
  return { id, name, icon, status, fig, latency };
}

// ---------- AGENTES ----------
const AGENTS = [
  {
    id: "nf",
    name: "Processamento de Notas Fiscais",
    short: "Esteira Fiscal",
    role: "Captura, OCR e validação fiscal de NF-e / NFS-e",
    status: "ok",
    llm: "gpt-4o",
    pos: { x: 140, y: 150 },
    accent: "#8fb3d4",
    mcps: [
      mcp("nf-ocr", "OCR Documentos", "scan-line", "ok", "scan", "180 ms"),
      mcp("nf-sefaz", "SEFAZ · NF-e", "file-check", "ok", "pulse", "320 ms"),
      mcp("nf-erp", "TOTVS Protheus", "database", "ok", "bob", "210 ms"),
    ],
    metrics: {
      tokensDay: 1_842_000, tokensMonth: 41_300_000,
      calls: 412, cost: 92.4, costMonth: 2710,
      p95: "2,1 s", success: 99.1, saved: "48 h/sem",
    },
    spark: spark(7, 24, 60, 34),
    prompt: `Você é o Agente de Processamento de Notas Fiscais da NN.ai.

Objetivo: receber documentos fiscais (NF-e, NFS-e, NFC-e), extrair os campos estruturados e validar contra as regras fiscais vigentes.

Para cada documento:
1. Faça OCR e identifique o tipo de documento.
2. Extraia: CNPJ emitente/destinatário, número, série, data de emissão, CFOP, CST/CSOSN, valores (produtos, impostos, total) e itens.
3. Valide a chave de acesso de 44 dígitos junto à SEFAZ.
4. Classifique a operação (entrada/saída, mercadoria/serviço).
5. Sinalize divergências de imposto acima de R$ 0,01.

Responda SEMPRE em JSON aderente ao schema fiscal-v3. Nunca invente campos ausentes — marque como null e abra exceção.`,
    versions: [
      { v: 4, author: "Fran Castilho", date: "28/05/2026 14:12", note: "Validação de chave de 44 dígitos na SEFAZ", added: 3, removed: 1 },
      { v: 3, author: "Bruno Lima",    date: "19/05/2026 09:40", note: "Schema fiscal-v3 + tolerância R$ 0,01", added: 6, removed: 2 },
      { v: 2, author: "Fran Castilho", date: "02/05/2026 16:55", note: "Classificação entrada/saída", added: 4, removed: 0 },
      { v: 1, author: "Bruno Lima",    date: "21/04/2026 11:08", note: "Versão inicial", added: 18, removed: 0 },
    ],
    recent: [
      { time: "há 2 min",  title: "Lote 04/2026 · 38 NF-e",        status: "ok",    summary: "38 documentos processados, 0 divergências", tokens: 41200, dur: "1,9 s" },
      { time: "há 14 min", title: "NF-e 2026/0412 · Distrib. Souza", status: "ok",   summary: "Validada e classificada (entrada/mercadoria)", tokens: 1180, dur: "1,7 s" },
      { time: "há 31 min", title: "NFS-e 889 · Consultoria ABC",    status: "warn",  summary: "ISS divergente em R$ 4,20 — exceção aberta", tokens: 1340, dur: "2,2 s" },
      { time: "há 1 h",    title: "Lote 03/2026 · 51 NF-e",         status: "ok",    summary: "51 documentos, 1 chave inválida descartada", tokens: 52800, dur: "2,4 s" },
    ],
    runs: [
      { id: "RUN-9F21", started: "10:42:18", trigger: "Webhook · e-mail fiscal", dur: "1,9 s", tokens: 41200, cost: 1.94, status: "ok" },
      { id: "RUN-9F18", started: "10:28:04", trigger: "API · upload manual",     dur: "1,7 s", tokens: 1180,  cost: 0.06, status: "ok" },
      { id: "RUN-9F12", started: "10:11:55", trigger: "Agendado · 10h",          dur: "2,2 s", tokens: 1340,  cost: 0.07, status: "warn" },
      { id: "RUN-9F03", started: "09:40:31", trigger: "Webhook · e-mail fiscal", dur: "2,4 s", tokens: 52800, cost: 2.48, status: "ok" },
    ],
  },
  {
    id: "concilia",
    name: "Conciliação Contábil",
    short: "Esteira Fiscal",
    role: "Classifica lançamentos e concilia extratos bancários",
    status: "warn",
    llm: "claude",
    pos: { x: 660, y: 130 },
    accent: "#7ea3cc",
    mcps: [
      mcp("cc-plano", "Plano de Contas", "book-open", "ok", "bob", "90 ms"),
      mcp("cc-of", "Open Finance", "landmark", "warn", "pulse", "1,8 s"),
      mcp("cc-erp", "TOTVS Protheus", "database", "ok", "bob", "240 ms"),
    ],
    metrics: {
      tokensDay: 980_000, tokensMonth: 22_400_000,
      calls: 188, cost: 141.3, costMonth: 4180,
      p95: "3,8 s", success: 96.4, saved: "31 h/sem",
    },
    spark: spark(13, 24, 52, 40),
    prompt: `Você é o Agente de Conciliação Contábil da NN.ai.

Receba lançamentos do ERP e movimentações bancárias (via Open Finance) e produza a conciliação.

Regras:
1. Faça o match por valor + data (janela de ±2 dias) + descrição normalizada.
2. Para débitos sem nota, sugira a conta contábil mais provável usando o histórico do cliente.
3. Marque divergências e itens não conciliados com justificativa.
4. Nunca concilie automaticamente valores acima de R$ 10.000 — encaminhe para revisão humana.

Devolva o resultado em JSON com: conciliados[], pendentes[], sugestoes[].`,
    versions: [
      { v: 3, author: "Bruno Lima",    date: "26/05/2026 10:20", note: "Teto de R$ 10k para revisão humana", added: 2, removed: 0 },
      { v: 2, author: "Fran Castilho", date: "12/05/2026 15:31", note: "Match por descrição normalizada", added: 5, removed: 3 },
      { v: 1, author: "Bruno Lima",    date: "28/04/2026 08:50", note: "Versão inicial", added: 14, removed: 0 },
    ],
    recent: [
      { time: "há 6 min",  title: "Conciliação · Cliente Marília SA", status: "warn", summary: "47 conciliados, 6 pendentes (Open Finance lento)", tokens: 18400, dur: "4,1 s" },
      { time: "há 22 min", title: "Fechamento parcial · abril",        status: "ok",   summary: "312 lançamentos conciliados", tokens: 88200, dur: "3,6 s" },
      { time: "há 48 min", title: "Sugestão de contas · 18 débitos",   status: "ok",   summary: "18 sugestões com confiança média 91%", tokens: 9100, dur: "2,9 s" },
    ],
    runs: [
      { id: "RUN-7C55", started: "10:39:02", trigger: "Pipeline · NF concluída", dur: "4,1 s", tokens: 18400, cost: 0.92, status: "warn" },
      { id: "RUN-7C49", started: "10:18:44", trigger: "Agendado · diário",        dur: "3,6 s", tokens: 88200, cost: 4.41, status: "ok" },
      { id: "RUN-7C40", started: "09:51:10", trigger: "API · revisão",            dur: "2,9 s", tokens: 9100,  cost: 0.46, status: "ok" },
    ],
  },
  {
    id: "triagem",
    name: "Triagem de Currículos",
    short: "Esteira de Pessoas",
    role: "Lê CVs, pontua aderência à vaga e ranqueia candidatos",
    status: "ok",
    llm: "gemini",
    pos: { x: 140, y: 560 },
    accent: "#9bbcd9",
    mcps: [
      mcp("tr-parser", "Parser de CV", "file-text", "ok", "scan", "140 ms"),
      mcp("tr-ats", "ATS · LinkedIn", "users", "ok", "orbit", "420 ms"),
      mcp("tr-vagas", "Banco de Vagas", "briefcase", "ok", "bob", "110 ms"),
    ],
    metrics: {
      tokensDay: 2_310_000, tokensMonth: 38_900_000,
      calls: 96, cost: 22.7, costMonth: 690,
      p95: "5,2 s", success: 98.0, saved: "27 h/sem",
    },
    spark: spark(21, 24, 48, 36),
    prompt: `Você é o Agente de Triagem de Currículos da NN.ai.

Para cada vaga aberta, leia os currículos recebidos e produza um ranking de aderência.

Critérios:
1. Compare formação, experiência e competências com os requisitos da vaga.
2. Pontue de 0 a 100 com justificativa por critério.
3. Sinalize lacunas e red flags (gaps, rotatividade).
4. NUNCA use idade, gênero, origem ou foto na pontuação — viés zero.

Saída: lista ordenada com score, resumo de 2 linhas e recomendação (avançar/banco/recusar).`,
    versions: [
      { v: 2, author: "Fran Castilho", date: "24/05/2026 13:02", note: "Cláusula anti-viés explícita", added: 2, removed: 0 },
      { v: 1, author: "Bruno Lima",    date: "30/04/2026 17:14", note: "Versão inicial", added: 12, removed: 0 },
    ],
    recent: [
      { time: "há 9 min",  title: "Vaga · Analista Contábil Pleno", status: "ok", summary: "62 CVs triados, 8 recomendados", tokens: 124000, dur: "5,0 s" },
      { time: "há 38 min", title: "Vaga · Estágio Fiscal",          status: "ok", summary: "140 CVs triados, 15 recomendados", tokens: 268000, dur: "5,4 s" },
      { time: "há 2 h",    title: "Vaga · Auxiliar de Depto Pessoal", status: "ok", summary: "44 CVs triados, 5 recomendados", tokens: 86000, dur: "4,7 s" },
    ],
    runs: [
      { id: "RUN-3A77", started: "10:33:51", trigger: "ATS · nova candidatura", dur: "5,0 s", tokens: 124000, cost: 0.62, status: "ok" },
      { id: "RUN-3A71", started: "10:05:12", trigger: "Lote · vaga publicada",   dur: "5,4 s", tokens: 268000, cost: 1.34, status: "ok" },
      { id: "RUN-3A60", started: "08:48:40", trigger: "ATS · nova candidatura",  dur: "4,7 s", tokens: 86000,  cost: 0.43, status: "ok" },
    ],
  },
  {
    id: "contratos",
    name: "Geração de Contratos",
    short: "Esteira de Pessoas",
    role: "Monta minutas, aplica cláusulas e envia para assinatura",
    status: "ok",
    llm: "deepseek",
    pos: { x: 660, y: 560 },
    accent: "#6f93bf",
    mcps: [
      mcp("ct-tpl", "Templates Jurídicos", "file-signature", "ok", "bob", "70 ms"),
      mcp("ct-sign", "Assinatura Digital", "pen-tool", "ok", "pulse", "260 ms"),
      mcp("ct-cofre", "Cofre de Documentos", "folder-lock", "ok", "bob", "150 ms"),
    ],
    metrics: {
      tokensDay: 540_000, tokensMonth: 12_100_000,
      calls: 58, cost: 4.3, costMonth: 132,
      p95: "3,1 s", success: 99.6, saved: "19 h/sem",
    },
    spark: spark(33, 24, 40, 28),
    prompt: `Você é o Agente de Geração de Contratos da NN.ai.

A partir dos dados de uma contratação aprovada, monte a minuta do contrato.

Regras:
1. Selecione o template correto (CLT, PJ, estágio, aditivo).
2. Preencha partes, objeto, prazo, remuneração e cláusulas obrigatórias.
3. Aplique a política de cláusulas vigente (confidencialidade, LGPD, rescisão).
4. Gere a versão para revisão humana ANTES de enviar para assinatura.

Saída: documento em markdown jurídico + checklist de cláusulas aplicadas.`,
    versions: [
      { v: 5, author: "Bruno Lima",    date: "27/05/2026 11:45", note: "Cláusula LGPD atualizada", added: 4, removed: 2 },
      { v: 4, author: "Fran Castilho", date: "15/05/2026 09:22", note: "Suporte a aditivo", added: 7, removed: 1 },
      { v: 3, author: "Bruno Lima",    date: "06/05/2026 14:00", note: "Checklist de cláusulas", added: 3, removed: 0 },
      { v: 2, author: "Fran Castilho", date: "29/04/2026 10:30", note: "Template PJ", added: 5, removed: 1 },
      { v: 1, author: "Bruno Lima",    date: "22/04/2026 16:18", note: "Versão inicial", added: 16, removed: 0 },
    ],
    recent: [
      { time: "há 4 min",  title: "Contrato CLT · M. Andrade",   status: "ok", summary: "Minuta gerada, 12 cláusulas, aguardando revisão", tokens: 8600, dur: "2,9 s" },
      { time: "há 26 min", title: "Aditivo · Consultoria ABC",   status: "ok", summary: "Aditivo de prazo gerado e enviado", tokens: 5400, dur: "2,4 s" },
      { time: "há 1 h",    title: "Contrato PJ · R. Nogueira",   status: "ok", summary: "Minuta + checklist completos", tokens: 7200, dur: "3,0 s" },
    ],
    runs: [
      { id: "RUN-5D33", started: "10:38:09", trigger: "Pipeline · Candidato aprovado", dur: "2,9 s", tokens: 8600, cost: 0.01, status: "ok" },
      { id: "RUN-5D29", started: "10:16:47", trigger: "API · solicitação RH",           dur: "2,4 s", tokens: 5400, cost: 0.01, status: "ok" },
      { id: "RUN-5D20", started: "09:33:02", trigger: "Pipeline · Candidato aprovado",  dur: "3,0 s", tokens: 7200, cost: 0.01, status: "ok" },
    ],
  },
  {
    id: "atendimento",
    name: "Atendimento ao Cliente",
    short: "Esteira de Relacionamento",
    role: "Responde dúvidas, abre chamados e notifica via WhatsApp / e-mail",
    status: "error",
    llm: "llama",
    pos: { x: 1180, y: 360 },
    accent: "#5f84b3",
    mcps: [
      mcp("at-wa", "WhatsApp API", "message-circle", "error", "pulse", "—"),
      mcp("at-kb", "Base de Conhecimento", "book-open", "ok", "bob", "120 ms"),
      mcp("at-crm", "CRM", "contact", "ok", "orbit", "300 ms"),
      mcp("at-mail", "E-mail", "mail", "ok", "bob", "180 ms"),
    ],
    metrics: {
      tokensDay: 3_120_000, tokensMonth: 64_800_000,
      calls: 1287, cost: 0.0, costMonth: 0,
      p95: "1,4 s", success: 74.2, saved: "62 h/sem",
    },
    spark: spark(41, 24, 55, 44),
    prompt: `Você é o Agente de Atendimento ao Cliente da NN.ai.

Atenda dúvidas de clientes da contabilidade por WhatsApp e e-mail.

Regras:
1. Responda com base APENAS na Base de Conhecimento oficial.
2. Para temas fiscais sensíveis, abra chamado e escale para um contador humano.
3. Registre toda interação no CRM.
4. Tom cordial, formal e objetivo. Sem promessas de prazo sem confirmação.

Quando não souber, diga que vai verificar e abra o chamado — nunca invente.`,
    versions: [
      { v: 3, author: "Fran Castilho", date: "25/05/2026 19:05", note: "Escalonamento de temas sensíveis", added: 3, removed: 1 },
      { v: 2, author: "Bruno Lima",    date: "10/05/2026 12:40", note: "Registro automático no CRM", added: 2, removed: 0 },
      { v: 1, author: "Fran Castilho", date: "01/05/2026 09:00", note: "Versão inicial", added: 13, removed: 0 },
    ],
    recent: [
      { time: "há 1 min",  title: "WhatsApp · falha de conexão", status: "error", summary: "Token da WhatsApp API expirado — fila represada (34)", tokens: 0, dur: "—" },
      { time: "há 12 min", title: "Chamado #4821 · DAS atrasado", status: "ok",    summary: "Respondido e escalado para contador", tokens: 2200, dur: "1,3 s" },
      { time: "há 25 min", title: "E-mail · 2ª via de boleto",     status: "ok",    summary: "Resolvido automaticamente", tokens: 900, dur: "1,1 s" },
    ],
    runs: [
      { id: "RUN-1B90", started: "10:41:55", trigger: "WhatsApp · mensagem", dur: "—",    tokens: 0,    cost: 0.0, status: "error" },
      { id: "RUN-1B88", started: "10:29:31", trigger: "WhatsApp · mensagem", dur: "1,3 s", tokens: 2200, cost: 0.0, status: "ok" },
      { id: "RUN-1B81", started: "10:16:12", trigger: "E-mail · entrada",    dur: "1,1 s", tokens: 900,  cost: 0.0, status: "ok" },
    ],
  },
];

// ---------- EDGES (pipeline) ----------
const EDGES = [
  { from: "nf",        to: "concilia",    label: "Lançamentos validados" },
  { from: "concilia",  to: "atendimento", label: "Resumo financeiro" },
  { from: "triagem",   to: "contratos",   label: "Candidato aprovado" },
  { from: "contratos", to: "atendimento", label: "Onboarding" },
];

window.AgentData = { AGENTS, EDGES, LLMS, LLM_LIST, STATUS, fmtBRL, fmtNum, fmtTokens };
