import { getQueue } from '#services/queue'
import app from '@adonisjs/core/services/app'
import logger from '@adonisjs/core/services/logger'

const PAYMENT_THANKS_QUEUE = 'payment-thanks'

/**
 * En tests, on skip l'enqueue BullMQ — les transactions auto-rollback
 * laisseraient des jobs orphelins en Redis sinon, et on ne dépend pas
 * d'une instance Redis live pour rouler les tests. Aligné avec le pattern
 * de `relance_scheduler.shouldEnqueue()`.
 */
function shouldEnqueue(): boolean {
  return app.getEnvironment() !== 'test'
}

/**
 * Enqueue l'envoi de l'email de remerciement pour une facture donnée.
 *
 * À appeler **après commit** de la transaction qui transitionne la facture
 * vers `paid` (check-in confirm, mark-paid manuel). Les controllers gardent
 * la responsabilité de l'idempotence : on n'enqueue que sur transition réelle
 * `* → paid`, pas si la facture était déjà payée.
 *
 * Le job tourne avec un retry exponentiel (5 tentatives, backoff 30s) : si
 * Resend / Mailpit est down, on retente. Échec définitif → log via le hook
 * `worker.on('failed')` côté queue.ts.
 */
export async function enqueuePaymentThanks(invoiceId: string): Promise<void> {
  if (!shouldEnqueue()) return

  try {
    const queue = getQueue(PAYMENT_THANKS_QUEUE)
    await queue.add(
      'send-thanks',
      { invoiceId },
      {
        // BullMQ 5+ interdit `:` dans les custom jobIds → tiret. Idempotency
        // via jobId : 2 enqueue concurrents pour la même invoice → un seul job.
        jobId: `thanks-${invoiceId}`,
        attempts: 5,
        backoff: { type: 'exponential', delay: 30_000 },
        // L'email est non-critique : on ne le rejoue pas indéfiniment, et on
        // garde une trace des derniers jobs failés pour debug.
        removeOnComplete: { age: 24 * 3600, count: 1000 },
        removeOnFail: { age: 7 * 24 * 3600 },
      }
    )
    logger.info({ invoiceId }, 'enqueuePaymentThanks: job enqueué')
  } catch (err) {
    // Ne pas faire échouer la requête HTTP du user pour un problème Redis.
    // Le mark-paid a réussi en DB, c'est l'essentiel ; le remerciement est un
    // « nice to have » qu'on pourra rattraper manuellement si besoin.
    logger.error({ err, invoiceId }, 'enqueuePaymentThanks: échec enqueue (no-op)')
  }
}
