'use strict'

const { Worker } = require('bullmq')
const Redis      = require('ioredis')
const { queryOne, execute } = require('../database/postgres')
const WhatsappLog  = require('../models/WhatsappLog')

const connection = new Redis({
  host: process.env.REDIS_HOST || '127.0.0.1',
  port: process.env.REDIS_PORT || 6379,
  maxRetriesPerRequest: null,
})

const delay = (ms) => new Promise(res => setTimeout(res, ms))

/**
 * Lê URL e token do motor NewWhats.
 * Prioridade: plugin_configs (banco) → variáveis de ambiente → defaults de dev.
 * Isso garante consistência com o proxy REST/WS que também lê do banco.
 */
async function getMotorConfig() {
  try {
    const [urlRow, tokenRow] = await Promise.all([
      queryOne("SELECT value FROM plugin_configs WHERE plugin_id = 'newwhats' AND key = 'newwhats_url'"),
      queryOne("SELECT value FROM plugin_configs WHERE plugin_id = 'newwhats' AND key = 'api_token'"),
    ])
    return {
      apiUrl: urlRow?.value?.replace(/\/$/, '')
               || process.env.NEWWHATS_API_URL
               || 'http://localhost:8008',
      token: tokenRow?.value
              || process.env.NEWWHATS_API_TOKEN
              || 'local',
    }
  } catch {
    // Banco indisponível — usa env var como fallback seguro
    return {
      apiUrl: process.env.NEWWHATS_API_URL || 'http://localhost:8008',
      token:  process.env.NEWWHATS_API_TOKEN || 'local',
    }
  }
}

// ── Worker BullMQ ─────────────────────────────────────────────────────────────

const whatsappWorker = new Worker(
  'whatsapp-notifications',
  async (job) => {
    const { logId, payload } = job.data

    console.log(`[WhatsApp Worker] Job ${job.id} iniciado — número ${payload.number} (logId: ${logId})`)

    await WhatsappLog.updateStatus(logId, 'processing')

    // Rate limit: delay aleatório de 2–10s para evitar ban do WhatsApp
    const randomDelay = Math.floor(Math.random() * 8000) + 2000
    await delay(randomDelay)

    const { apiUrl, token } = await getMotorConfig()

    try {
      const res = await fetch(`${apiUrl}/api/messages/send`, {
        method:  'POST',
        headers: {
          'Content-Type':  'application/json',
          'Authorization': `Bearer ${token}`,
        },
        body: JSON.stringify(payload),
      })

      const resultBody = await res.text()

      if (!res.ok) {
        throw new Error(`HTTP ${res.status}: ${resultBody}`)
      }

      await WhatsappLog.updateStatus(logId, 'sent', resultBody)
      console.log(`[WhatsApp Worker] Job ${job.id} CONCLUÍDO — enviado para ${payload.number}`)
      return resultBody

    } catch (error) {
      console.error(`[WhatsApp Worker] Job ${job.id} FALHOU (tentativa ${job.attemptsMade + 1}):`, error.message)
      const isFinal = job.attemptsMade + 1 >= (job.opts?.attempts ?? 3)
      await WhatsappLog.updateStatus(logId, isFinal ? 'failed' : 'retrying', error.message)

      if (isFinal) {
        console.error(`[WhatsApp Worker] ⚠️  Falha DEFINITIVA no job ${job.id} para ${payload.number} — logId ${logId}`)
        // Persiste falha definitiva para rastreamento e alerta no admin
        execute(
          `INSERT INTO notification_errors (job_id, log_id, phone, error_message, payload)
           VALUES ($1, $2, $3, $4, $5)`,
          [String(job.id), logId ?? null, payload.number ?? null, error.message, JSON.stringify(payload)]
        ).catch(e => console.error('[WhatsApp Worker] Erro ao gravar notification_errors:', e.message))
      }

      throw error // Aciona backoff exponencial do BullMQ
    }
  },
  {
    connection,
    concurrency: parseInt(process.env.WHATSAPP_WORKER_CONCURRENCY || '1', 10),
  }
)

// ── Eventos de ciclo de vida ──────────────────────────────────────────────────

whatsappWorker.on('failed', (job, err) => {
  console.error(`[WhatsApp Worker] Evento failed — job ${job?.id}: ${err.message}`)
})

whatsappWorker.on('completed', (job) => {
  console.log(`[WhatsApp Worker] Evento completed — job ${job.id} removido da fila`)
})

module.exports = whatsappWorker
