'use strict'

/**
 * sync-knowledge.js
 * Constrói o nó de conhecimento da Secretária IA com dados reais do banco
 * e sincroniza com o motor NewWhats via API REST.
 *
 * Fluxo:
 *  1. Lê dados do DB Alemão (clubes, planos, parceiros, promoções, sorteio, vagas)
 *  2. Monta texto estruturado do knowledge node
 *  3. Chama o motor NewWhats para atualizar o nó (ou cria se não existir)
 *  4. Retorna { ok, preview, agent_id, node_id }
 */

const { query, queryOne } = require('../../database/postgres')

// ── Busca configurações do plugin no banco ────────────────────────────────────
async function getPluginConfig() {
  const rows = await query(
    `SELECT key, value FROM plugin_configs WHERE plugin_id = 'newwhats'`
  )
  const cfg = {}
  for (const r of rows) cfg[r.key] = r.value
  return cfg
}

// ── Chama a API interna do motor NewWhats (/api/secretaria/*) ─────────────────
// Nota: as rotas /api/secretaria/* são internas do motor (não passam pelo proxy
// /api/ext/v1). São acessadas diretamente pela URL do motor configurada no plugin.
async function motorFetch(motorUrl, _integKey, method, path, body) {
  const url = `${motorUrl}/api/secretaria${path}`
  const opts = {
    method,
    headers: { 'Content-Type': 'application/json' },
  }
  if (body) opts.body = JSON.stringify(body)
  const res = await fetch(url, opts)
  if (!res.ok) {
    const txt = await res.text()
    throw new Error(`Motor ${method} /api/secretaria${path} → ${res.status}: ${txt}`)
  }
  return res.json()
}

// ── Monta o texto do knowledge node ──────────────────────────────────────────
async function buildKnowledgeText() {
  const lines = []

  // ── Empresa ──────────────────────────────────────────────────────────────
  lines.push(`=== ALEMÃO CONVENIÊNCIAS ===`)
  lines.push(`Somos uma empresa de conveniências com foco em benefícios para nossos clientes.`)
  lines.push(`Site: alemaoconveniencias.com | Atendimento via WhatsApp`)
  lines.push(``)

  // ── Clubes de Benefícios ─────────────────────────────────────────────────
  const clubes = await query(
    `SELECT id, name, slug, specialty, conditions, rules
     FROM benefit_clubs
     WHERE active = true
     ORDER BY id ASC`
  )

  if (clubes.length) {
    lines.push(`=== CLUBES DE BENEFÍCIOS ===`)
    for (const clube of clubes) {
      lines.push(`\n• ${clube.name} (${clube.specialty})`)

      // Planos do clube
      const planos = await query(
        `SELECT name, price_monthly, max_dependents, features
         FROM club_plans
         WHERE club_id = $1 AND active = true
         ORDER BY price_monthly ASC`,
        [clube.id]
      )
      if (planos.length) {
        lines.push(`  Planos disponíveis:`)
        for (const p of planos) {
          const deps = p.max_dependents > 0 ? ` (até ${p.max_dependents} dependente${p.max_dependents > 1 ? 's' : ''})` : ' (titular)'
          lines.push(`    - ${p.name}${deps}: R$ ${Number(p.price_monthly).toFixed(2).replace('.', ',')}/mês`)
          let features = []
          try { features = typeof p.features === 'string' ? JSON.parse(p.features) : (p.features || []) } catch {}
          if (features.length) lines.push(`      Incluído: ${features.slice(0, 4).join(', ')}`)
        }
      }

      // Parceiros do clube
      const parceiros = await query(
        `SELECT name, specialty, phone, address, discount_percent
         FROM club_partners
         WHERE club_id = $1 AND active = true
         ORDER BY name ASC
         LIMIT 8`,
        [clube.id]
      )
      if (parceiros.length) {
        lines.push(`  Parceiros credenciados:`)
        for (const p of parceiros) {
          const desc = p.discount_percent ? ` — ${p.discount_percent}% desconto` : ''
          const tel  = p.phone ? ` | Tel: ${p.phone}` : ''
          lines.push(`    - ${p.name} (${p.specialty})${desc}${tel}`)
          if (p.address) lines.push(`      Endereço: ${p.address}`)
        }
      }

      if (clube.conditions) lines.push(`  Condições: ${clube.conditions}`)
      if (clube.rules)      lines.push(`  Regras: ${clube.rules}`)
    }
    lines.push(``)
  }

  // ── Sorteio Ativo ─────────────────────────────────────────────────────────
  const sorteio = await queryOne(
    `SELECT titulo, descricao, preco_numero, total_numeros FROM raffles WHERE ativo = 1 LIMIT 1`
  )
  if (sorteio) {
    const countRow = await queryOne(
      `SELECT COUNT(*) AS total FROM tickets t
       JOIN raffles r ON r.id = t.raffle_id
       WHERE r.ativo = 1 AND (t.status = 'sold' OR (t.status = 'reserved' AND t.reserved_until > NOW()))`
    )
    const vendidos  = parseInt(countRow?.total ?? 0, 10)
    const disponiveis = sorteio.total_numeros - vendidos
    lines.push(`=== SORTEIO ATIVO ===`)
    lines.push(`Nome: ${sorteio.titulo}`)
    if (sorteio.descricao) lines.push(`Descrição: ${sorteio.descricao}`)
    lines.push(`Preço por número: R$ ${Number(sorteio.preco_numero).toFixed(2).replace('.', ',')}`)
    lines.push(`Números disponíveis: ${disponiveis} de ${sorteio.total_numeros}`)
    lines.push(`Como comprar: acesse nosso site e escolha seus números favoritos.`)
    lines.push(``)
  }

  // ── Promoções Ativas ──────────────────────────────────────────────────────
  const promos = await query(
    `SELECT nome, descricao, preco_original, preco_promocional
     FROM promotions WHERE ativo = TRUE ORDER BY id ASC`
  )
  if (promos.length) {
    lines.push(`=== PROMOÇÕES ATIVAS ===`)
    for (const p of promos) {
      const economia = p.preco_original && p.preco_promocional
        ? ` (de R$ ${Number(p.preco_original).toFixed(2).replace('.', ',')} por R$ ${Number(p.preco_promocional).toFixed(2).replace('.', ',')})`
        : ''
      lines.push(`• ${p.nome}${economia}`)
      if (p.descricao) lines.push(`  ${p.descricao}`)
    }
    lines.push(``)
  }

  // ── Vagas de Emprego ──────────────────────────────────────────────────────
  const vagas = await query(
    `SELECT title, category, work_mode, job_type, location, salary_hide, salary_min, salary_max
     FROM jobs
     WHERE active = true AND (expires_at IS NULL OR expires_at > NOW())
     ORDER BY published_at DESC
     LIMIT 10`
  )
  if (vagas.length) {
    const modeMap = { presencial: 'Presencial', hibrido: 'Híbrido', remoto: 'Remoto' }
    const typeMap = { clt: 'CLT', pj: 'PJ', freelance: 'Freelance', estagio: 'Estágio', temporario: 'Temporário' }
    lines.push(`=== VAGAS DE EMPREGO DISPONÍVEIS ===`)
    lines.push(`(Temos ${vagas.length} vaga${vagas.length > 1 ? 's' : ''} abertas no momento)`)
    for (const v of vagas) {
      const modo = modeMap[v.work_mode] || v.work_mode
      const tipo = typeMap[v.job_type]  || v.job_type
      const sal  = v.salary_hide || (!v.salary_min && !v.salary_max)
        ? 'A combinar'
        : v.salary_min && v.salary_max
          ? `R$ ${Number(v.salary_min).toLocaleString('pt-BR', { maximumFractionDigits: 0 })}–${Number(v.salary_max).toLocaleString('pt-BR', { maximumFractionDigits: 0 })}`
          : v.salary_min
            ? `A partir de R$ ${Number(v.salary_min).toLocaleString('pt-BR', { maximumFractionDigits: 0 })}`
            : `Até R$ ${Number(v.salary_max).toLocaleString('pt-BR', { maximumFractionDigits: 0 })}`
      const loc  = v.location ? ` | ${v.location}` : ''
      lines.push(`• ${v.title} — ${modo} | ${tipo}${loc} | ${sal}`)
    }
    lines.push(`Para se candidatar, acesse nosso site na seção Vagas.`)
    lines.push(``)
  }

  // ── Informações Gerais ────────────────────────────────────────────────────
  lines.push(`=== ATENDIMENTO ===`)
  lines.push(`Horário: Consulte pelo WhatsApp ou site para horário atualizado.`)
  lines.push(`Carteirinha digital: disponível na área do cliente em nosso site.`)
  lines.push(`Dúvidas sobre pagamento, cancelamento ou benefícios: informe que vai encaminhar para nossa equipe.`)

  return lines.join('\n')
}

// ── Endpoint principal: sincroniza knowledge node no motor ────────────────────
async function syncKnowledge() {
  const cfg = await getPluginConfig()
  const motorUrl = cfg.newwhats_url
  const integKey = cfg.integration_key

  if (!motorUrl || !integKey) {
    throw new Error('Plugin NewWhats não configurado (newwhats_url ou integration_key ausentes)')
  }

  // 1. Monta o texto
  const knowledgeText = await buildKnowledgeText()

  // 2. Busca agentes no motor
  const agents = await motorFetch(motorUrl, integKey, 'GET', '/agents')
  if (!agents.length) throw new Error('Nenhum agente encontrado no motor. Crie um agente na Secretária IA.')

  const agent = agents.find(a => a.active) || agents[0]

  // 3. Busca nós do agente
  const nodes = await motorFetch(motorUrl, integKey, 'GET', `/agents/${agent.id}/nodes`)

  // 4. Encontra o nó de knowledge (ou cria)
  const knowledgeNode = nodes.find(n => n.type === 'knowledge')

  let nodeId
  if (knowledgeNode) {
    // Atualiza nó existente
    await motorFetch(motorUrl, integKey, 'PUT', `/nodes/${knowledgeNode.id}`, {
      title:      'Base de Conhecimento — Alemão Conveniências',
      content:    knowledgeText,
      active:     true,
      sort_order: knowledgeNode.sort_order ?? 3,
    })
    nodeId = knowledgeNode.id
  } else {
    // Cria nó novo
    const created = await motorFetch(motorUrl, integKey, 'POST', `/agents/${agent.id}/nodes`, {
      type:       'knowledge',
      title:      'Base de Conhecimento — Alemão Conveniências',
      content:    knowledgeText,
      sort_order: 3,
    })
    nodeId = created.id
  }

  return {
    ok:       true,
    agent_id: agent.id,
    agent:    agent.name,
    node_id:  nodeId,
    preview:  knowledgeText,
    chars:    knowledgeText.length,
    synced_at: new Date().toISOString(),
  }
}

module.exports = { syncKnowledge, buildKnowledgeText }
