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
  /** Nom du plan parent — donne du contexte au modèle (ex. "Clients fidèles"). */
  planName?: string
  /** Description du plan parent — quand utiliser ce plan, ICP visé. */
  planDescription?: 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 française.

# Règles de rédaction
- Toujours en français.
- Vouvoie systématiquement le destinataire (B2B France).
- Concis : 4 à 8 phrases maximum pour le corps.
- Une salutation au début, et termine TOUJOURS le corps par {{signature}} sur sa propre ligne. **Ne jamais réécrire le nom de l'expéditeur ni l'entreprise à la main après {{signature}}** : la variable contient déjà tout (nom + entreprise + formule de politesse choisie par l'utilisateur).

# Syntaxe des variables — IMPORTANT
- Utilise UNIQUEMENT la substitution simple \`{{nom.de.variable}}\`.
- N'utilise JAMAIS la syntaxe de sections \`{{#var}}...{{/var}}\`, \`{{^var}}...{{/var}}\`, ni aucune syntaxe conditionnelle. Notre interpréteur ne fait que de la substitution simple — toute syntaxe avancée s'affichera telle quelle dans l'email final.
- Tu n'es **PAS obligé** d'utiliser toutes les variables. Choisis celles qui rendent le message naturel et utile. Mieux vaut un message simple et clair qu'un message bourré de variables.

# Variables disponibles
- {{client.name}} : raison sociale du client (toujours rempli)
- {{client.contactFirstName}} : prénom du contact (peut être vide à l'envoi — dans ce cas la variable s'efface silencieusement, donc préfère une formule qui marche dans les deux cas, ex. "Bonjour {{client.contactFirstName}}," où l'absence du prénom donne juste "Bonjour ,")
- {{client.contactLastName}} : nom du contact (peut être vide)
- {{numero}} : numéro de la facture
- {{amount}} : montant TTC formaté (ex. "1 240,00 €")
- {{dueDate}} : date d'échéance (ex. "15/04/2026")
- {{issueDate}} : date d'émission
- {{daysLate}} : jours de retard (entier — peut être négatif si la relance est avant échéance)
- {{user.fullName}} : nom de l'expéditeur (rarement utile dans le corps si on a déjà {{signature}})
- {{user.companyName}} : nom de l'entreprise expéditrice
- {{signature}} : bloc signature complet — termine TOUJOURS le corps par cette variable

# Format de retour
JSON strict avec deux clés :
- "subject" : sujet (max 100 caractères, naturel, peut contenir {{numero}})
- "body" : corps de l'email`

/**
 * 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 offsetExplanation =
    input.offsetDays < 0
      ? `${Math.abs(input.offsetDays)} jours **avant** l'échéance (rappel anticipé)`
      : input.offsetDays === 0
        ? "le **jour J** de l'échéance"
        : `${input.offsetDays} jours **après** l'échéance (la facture est en retard)`

  const userMessage = [
    '# Plan parent',
    input.planName ? `Nom : ${input.planName}` : 'Nom : (non précisé)',
    input.planDescription
      ? `Description : ${input.planDescription}`
      : 'Description : (aucune)',
    '',
    '# Cette relance',
    `Tonalité : ${input.tone} → ${TONE_GUIDANCE[input.tone]}`,
    `Timing : J${input.offsetDays >= 0 ? '+' : ''}${input.offsetDays} → ${offsetExplanation}.`,
    '',
    "# Brief de l'utilisateur",
    input.prompt.trim() ||
      '(aucun brief — rédige un message standard pour cette tonalité et ce timing, en restant naturel)',
  ].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),
  }
}
