import type { OcrProvider, OcrResult } from '#services/ocr/ocr_provider'

const SAMPLE_CLIENT_NAMES = [
  'Boulangerie Martin SARL',
  'Atelier Durand',
  'Cabinet Rousseau',
  'Garage Lemoine',
  'Studio Lefèvre',
  'Pharmacie Bertrand',
  'Imprimerie Moreau',
] as const

function rand<T>(arr: readonly T[]): T {
  return arr[Math.floor(Math.random() * arr.length)]!
}

function randomAmountCents(): number {
  // entre 80 € et 8 000 €, multiple de 50 cts pour rester crédible
  return Math.floor(((Math.random() * 7920 + 80) * 100) / 50) * 50
}

function numeroFromFilename(filename: string): string {
  const match = filename.match(/(\d{2,5})/u)
  const yr = new Date().getFullYear()
  const seq = match?.[1] ?? Math.floor(Math.random() * 9000 + 1000).toString()
  return `F-${yr}-${seq.padStart(4, '0')}`
}

function isoDaysFromNow(days: number): string {
  const d = new Date()
  d.setDate(d.getDate() + days)
  d.setHours(9, 0, 0, 0)
  return d.toISOString()
}

function slugify(s: string): string {
  return s
    .toLowerCase()
    .replace(/sarl|sa|sas/giu, '')
    .replace(/[^a-z]+/giu, '-')
    .replace(/^-+|-+$/gu, '')
}

/**
 * Implémentation OCR mock : génère des champs plausibles depuis le filename
 * + injecte volontairement quelques confidences basses (~30 %) pour signaler
 * "champ douteux" dans l'UI de review.
 *
 * Aucun appel réseau, aucun PDF téléchargé. Quand Mistral arrive, on swap
 * cette classe via le container Adonis sans toucher au reste.
 */
export class MockOcrProvider implements OcrProvider {
  async extract(input: {
    storageKey: string | null
    filename: string
  }): Promise<OcrResult> {
    const clientName = rand(SAMPLE_CLIENT_NAMES)
    // 30 % de chance d'avoir un email douteux (low confidence) — déclenche
    // la pastille "à vérifier" dans la UI de review.
    const emailLowConf = Math.random() < 0.3
    const email = emailLowConf ? null : `compta@${slugify(clientName)}.fr`

    return {
      fields: {
        clientName: { value: clientName, confidence: 0.95 },
        clientEmail: {
          value: email,
          confidence: emailLowConf ? 0.42 : 0.88,
        },
        numero: { value: numeroFromFilename(input.filename), confidence: 0.97 },
        amountTtcCents: { value: randomAmountCents(), confidence: 0.93 },
        issueDate: {
          value: isoDaysFromNow(-15 - Math.floor(Math.random() * 10)),
          confidence: 0.9,
        },
        dueDate: {
          value: isoDaysFromNow(15 + Math.floor(Math.random() * 20)),
          confidence: emailLowConf ? 0.65 : 0.92,
        },
      },
      rawProviderResponse: { provider: 'mock', filename: input.filename },
    }
  }
}
