import env from '#start/env'

const MISTRAL_API = 'https://api.mistral.ai/v1'
// Modèle chat rapide et bon en français pour générer du texte court.
// `mistral-small-latest` est ~10x moins cher que `mistral-large` et
// largement suffisant pour 3 paragraphes de relance.
const GENERATION_MODEL = 'mistral-small-latest'

export type RelanceTone = 'amical' | 'courtois' | 'ferme' | 'mise_en_demeure'

export type GenerateRelanceInput = {
  /** Tonalité ciblée — guide le ton du modèle. */
  tone: RelanceTone
  /** Position de l'étape dans le plan (J+3, J+10…). Influence l'urgence. */
  offsetDays: number
  /** Brief libre rédigé par l'utilisateur (ex. "rappelle qu'on accepte les virements"). */
  prompt: string
  /** Contexte du plan, pour cohérence (ex. nom du plan, étapes voisines). */
  planContext?: string
}

export type GenerateRelanceOutput = {
  subject: string
  body: string
}

const TONE_GUIDANCE: Record<RelanceTone, string> = {
  amical:
    "Ton chaleureux et bienveillant, presque comme un message à un partenaire de confiance. Pas de pression. On commence par 'Bonjour' suivi du prénom si dispo, sinon du nom de l'entreprise.",
  courtois:
    'Ton professionnel et factuel. Poli, neutre, pas de chaleur excessive ni de menace. Standard B2B.',
  ferme:
    "Ton ferme et direct. Rappelle l'engagement contractuel. Reste poli mais sans formule de politesse excessive. Pas d'agressivité.",
  mise_en_demeure:
    "Ton formel et juridique. Mentionne explicitement 'mise en demeure', un délai de paiement (8 jours), et les conséquences légales (pénalités de retard, voie judiciaire). Reste factuel, pas émotionnel.",
}

const SYSTEM_PROMPT = `Tu rédiges des emails de relance de factures impayées en français pour une TPE-PME.

Règles strictes :
- Toujours en français.
- Toujours tutoyer le **destinataire** ? NON, vouvoie systématiquement (B2B France).
- Reste concis : 4 à 8 phrases maximum pour le corps.
- Ne saute jamais de salutation ni de signature.
- Insère naturellement les variables fournies (sans les commenter).
- Si le prénom du contact n'est pas dispo, retombe sur une formule générale ("Bonjour,").

Variables disponibles à insérer (utilise la syntaxe Mustache exacte) :
- {{client.name}} : raison sociale du client
- {{client.contactFirstName}} : prénom du contact (peut être vide → fallback "Bonjour,")
- {{client.contactLastName}} : nom du contact (peut être vide)
- {{numero}} : numéro de la facture
- {{amount}} : montant TTC formaté ("1 240,00 €")
- {{dueDate}} : date d'échéance ("15/04/2026")
- {{issueDate}} : date d'émission
- {{daysLate}} : nombre de jours de retard (entier)
- {{user.fullName}} : nom de l'expéditeur (la TPE)
- {{user.companyName}} : nom de l'entreprise expéditrice
- {{signature}} : bloc signature de l'expéditeur

Tu retournes un JSON strict avec deux clés : "subject" (max 100 caractères) et "body" (max 2000 caractères).`

/**
 * Génère un email de relance via Mistral. Retourne `{ subject, body }`
 * avec des placeholders Mustache prêts à être interpolés à l'envoi.
 *
 * Coût : ~0.0001 € par appel sur `mistral-small-latest` (négligeable).
 */
export async function generateRelance(input: GenerateRelanceInput): Promise<GenerateRelanceOutput> {
  const apiKey = env.get('MISTRAL_API_KEY', '')
  if (!apiKey) {
    throw new Error('MISTRAL_API_KEY manquante : génération IA indisponible.')
  }

  const userMessage = [
    `Tonalité ciblée : ${input.tone} — ${TONE_GUIDANCE[input.tone]}`,
    `Position dans le plan : J${input.offsetDays >= 0 ? '+' : ''}${input.offsetDays} (${
      input.offsetDays < 0
        ? "rappel avant l'échéance"
        : input.offsetDays === 0
          ? 'jour de l\'échéance'
          : `${input.offsetDays} jours après l'échéance`
    }).`,
    input.planContext ? `Contexte du plan : ${input.planContext}` : null,
    '',
    'Brief de l\'utilisateur :',
    input.prompt.trim() || '(aucun brief — génère un message standard pour cette tonalité et ce timing)',
  ]
    .filter(Boolean)
    .join('\n')

  const res = await fetch(`${MISTRAL_API}/chat/completions`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: GENERATION_MODEL,
      messages: [
        { role: 'system', content: SYSTEM_PROMPT },
        { role: 'user', content: userMessage },
      ],
      response_format: {
        type: 'json_schema',
        json_schema: {
          name: 'relance_email',
          strict: true,
          schema: {
            type: 'object',
            additionalProperties: false,
            properties: {
              subject: { type: 'string' },
              body: { type: 'string' },
            },
            required: ['subject', 'body'],
          },
        },
      },
      temperature: 0.7,
    }),
  })

  if (!res.ok) {
    const text = await res.text()
    throw new Error(`Mistral génération relance → HTTP ${res.status}: ${text}`)
  }

  const json = (await res.json()) as {
    choices?: { message?: { content?: string } }[]
  }
  const content = json?.choices?.[0]?.message?.content
  if (typeof content !== 'string') {
    throw new Error('Mistral chat: pas de content string dans la réponse')
  }

  const parsed = JSON.parse(content) as GenerateRelanceOutput
  return {
    subject: parsed.subject.slice(0, 200),
    body: parsed.body.slice(0, 5000),
  }
}
