import type { Master, MasterDetail, ScoreGrade, SelectivityLevel } from './types'

const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? 'https://api.quantcareers.fr'

// ---------------------------------------------------------------------------
// Types bruts renvoyés par l'API Django (voir openapi.yaml)
// ---------------------------------------------------------------------------
interface ApiScores {
  total: string
  placement: string
  selectivity: string
  network: string
  prestige: string
  international: string
  professors_bonus: string
  alumni_count: number
  computed_at: string
}

interface ApiMaster {
  id: number
  name: string
  country: string
  scores: ApiScores
}

interface ApiMasterDetail extends ApiMaster {
  description: string
  website: string
  duration_months: number | null
  language: string
  tuition_fees: number | null
  application_deadline: string | null
}

// ---------------------------------------------------------------------------
// Adaptateur : transforme la réponse API (brute, numérique) en Master
// d'affichage (grades lettrés, couleurs, barres...) attendu par les
// composants existants (MasterRow, ScorePill, PctBar, CriteriaBars).
//
// Hypothèses faites en l'absence d'équivalent direct côté API — à valider :
//   - scoreGrade (AAA/AA/A/B) ← seuils sur scores.total (/100)
//   - selectivity (Très sélectif/Sélectif/Ouvert) ← seuils sur scores.selectivity (/10)
//   - frontOfficeRate (%) ← scores.placement (/10) × 10
//       (proxy le plus proche de "débouchés front-office" ; l'API n'a pas
//       cette notion précise, seulement un score de placement global)
//   - stageQualityLabel/Rate ← scores.network (/10) × 10
//       (proxy "qualité des stages" via le score de réseau industriel)
//   - school / schoolBadge / schoolColor ← pas d'université "principale"
//       distincte côté API au niveau liste (seulement `country`), donc
//       school = country, badge = 1re lettre du nom, couleur = palette fixe
//   - criteriaHeights/filledCount ← les 6 critères RÉELS de l'API
//       (placement, selectivity, network, prestige, international,
//       professors_bonus), pas les 8 abstraits du mock — le composant
//       CriteriaBars affiche donc 6 barres, toutes "remplies" (données réelles)
// ---------------------------------------------------------------------------

const BADGE_COLORS = ['#0A5AD6', '#1A6B45', '#8B6340', '#5B6472', '#2E75E6', '#B98B4E']

function scoreGradeFromTotal(total: number): ScoreGrade {
  if (total >= 85) return 'AAA'
  if (total >= 70) return 'AA'
  if (total >= 50) return 'A'
  return 'B'
}

function selectivityFromScore(selectivity: number): { level: SelectivityLevel; color: string } {
  if (selectivity >= 8) return { level: 'Très sélectif', color: '#1A6B45' }
  if (selectivity >= 5) return { level: 'Sélectif', color: '#0A5AD6' }
  return { level: 'Ouvert', color: '#7A8FA0' }
}

function stageQualityFromNetwork(network100: number): string {
  if (network100 >= 85) return 'Tier 1'
  if (network100 >= 65) return 'Tier 1–2'
  if (network100 >= 45) return 'Tier 2'
  return 'Tier 3'
}

export function slugify(name: string): string {
  return name
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/(^-|-$)/g, '')
}

function adaptMaster(api: ApiMaster, rank: number): Master {
  const total = parseFloat(api.scores.total)
  const placement = parseFloat(api.scores.placement)
  const selectivityScore = parseFloat(api.scores.selectivity)
  const network = parseFloat(api.scores.network)
  const prestige = parseFloat(api.scores.prestige)
  const international = parseFloat(api.scores.international)
  const professorsBonus = parseFloat(api.scores.professors_bonus)

  const { level: selectivity, color: selectivityColor } = selectivityFromScore(selectivityScore)
  const frontOfficeRate = Math.round(placement * 10)
  const stageQualityRate = Math.round(network * 10)

  const criteriaRaw = [placement, selectivityScore, network, prestige, international, professorsBonus * 2] // bonus profs est /5, ramené sur /10
  const criteriaHeights = criteriaRaw.map((v) => Math.max(4, Math.round((v / 10) * 20)))

  return {
    id: api.id,
    slug: slugify(api.name),
    rank,
    name: api.name,
    fullName: api.name,
    school: api.country,
    schoolBadge: api.name.charAt(0).toUpperCase(),
    schoolColor: BADGE_COLORS[api.id % BADGE_COLORS.length],
    scoreGrade: scoreGradeFromTotal(total),
    scoreValue: total / 10,
    selectivity,
    selectivityColor,
    frontOfficeRate,
    stageQualityLabel: stageQualityFromNetwork(stageQualityRate),
    stageQualityRate,
    criteriaHeights,
    criteriaFilledCount: criteriaHeights.length, // 6 critères réels, tous connus
    isTop3: rank <= 3,

    // Champs de fiche détaillée — remplis séparément par getMasterBySlug()
    description: '',
    duration: '',
    price: '',
    website: '',
    courses: [],
    admissionInfo: undefined,
  }
}

// ---------------------------------------------------------------------------
export async function getMasters(): Promise<Master[]> {
  try {
    const res = await fetch(`${API_BASE}/masters/`, { next: { revalidate: 3600 } })
    if (!res.ok) throw new Error(`HTTP ${res.status}`)
    const data: ApiMaster[] = await res.json()
    return data.map((m, i) => adaptMaster(m, i + 1))
  } catch {
    return STATIC_MASTERS
  }
}

export async function getMasterBySlug(slug: string): Promise<Master | undefined> {
  const masters = await getMasters()
  const base = masters.find((m) => m.slug === slug)
  if (!base) return undefined

  try {
    const res = await fetch(`${API_BASE}/masters/${base.id}/`, { next: { revalidate: 3600 } })
    if (!res.ok) throw new Error(`HTTP ${res.status}`)
    const detail: ApiMasterDetail = await res.json()
    return {
      ...base,
      description: detail.description ?? '',
      website: detail.website ?? '',
      duration: detail.duration_months ? `${detail.duration_months} mois` : 'Non communiqué',
      price: detail.tuition_fees ? `${detail.tuition_fees} € / an` : 'Non communiqué',
      // Pas d'équivalent "liste de cours" côté API pour l'instant.
      courses: [],
      admissionInfo: undefined,
    }
  } catch {
    return base
  }
}

// ---------------------------------------------------------------------------
// Fallback local (dev / API indisponible) — vos données mockées d'origine,
// inchangées, utilisées uniquement si l'appel réseau à l'API échoue
// ---------------------------------------------------------------------------
export const STATIC_MASTERS: Master[] = [
  {
    id: 1,
    slug: 'el-karoui',
    rank: 1,
    name: 'El Karoui',
    fullName: 'El Karoui — Probabilités et Finance',
    school: 'École Polytechnique · Sorbonne Université · Paris',
    schoolBadge: 'X',
    schoolColor: '#C1002A',
    scoreGrade: 'AAA',
    scoreValue: 9.5,
    selectivity: 'Très sélectif',
    selectivityColor: '#1A6B45',
    frontOfficeRate: 91,
    stageQualityLabel: 'Tier 1',
    stageQualityRate: 97,
    criteriaHeights: [18, 16, 20, 14, 17, 12, 15, 11],
    criteriaFilledCount: 8,
    isTop3: true,
    description: "Le master El Karoui est la référence absolue de la finance quantitative en France. Co-habilité par l'École Polytechnique et Sorbonne Université, il forme depuis 1990 les quants des plus grandes banques mondiales. Son niveau mathématique est exceptionnel, avec une emphase forte sur le calcul stochastique et la théorie des probabilités appliquées à la finance.",
    duration: '1 an (M2)',
    price: '243 € / an (frais universitaires)',
    website: 'https://www.lpsm.paris/masters/el-karoui/',
    courses: [
      'Calcul stochastique et théorie des martingales',
      'Pricing des dérivés (modèles de taux, equity, crédit)',
      'Méthodes numériques (Monte Carlo, différences finies)',
      'Gestion des risques et régulation (Bâle III/IV)',
      'Machine Learning pour la finance',
      'Market microstructure et trading haute fréquence',
      'Portfolio optimization et allocation d\'actifs',
      'Programmation C++ et Python avancé',
    ],
    admissionInfo: 'Admission sur dossier + entretien. Niveau attendu : M1 mathématiques ou école d\'ingénieurs avec forte dominante maths (X, Mines, Centrale, ENSAE).',
  },
  {
    id: 2,
    slug: 'masef',
    rank: 2,
    name: 'MASEF',
    fullName: 'MASEF — Mathématiques Appliquées, Statistique, Économie, Finance',
    school: 'Université Paris-Dauphine · PSL · Paris',
    schoolBadge: 'D',
    schoolColor: '#00326B',
    scoreGrade: 'AAA',
    scoreValue: 8.8,
    selectivity: 'Très sélectif',
    selectivityColor: '#1A6B45',
    frontOfficeRate: 84,
    stageQualityLabel: 'Tier 1',
    stageQualityRate: 88,
    criteriaHeights: [16, 20, 14, 18, 12, 16, 10, 13],
    criteriaFilledCount: 7,
    isTop3: true,
    description: "Le MASEF de Paris-Dauphine PSL est l'un des programmes de finance quantitative les plus réputés en Europe. Ancré dans une tradition d'excellence en mathématiques financières, il propose une formation équilibrée entre théorie probabiliste avancée et applications pratiques en salle des marchés. Ses alumni occupent des postes de quant researchers et structureurs dans les principales banques de financement et d'investissement.",
    duration: '1 an (M2)',
    price: '243 € / an (frais universitaires)',
    website: 'https://dauphine.psl.eu/formations/masters/mathematiques-et-applications/m2-mathematiques-appliquees-statistique-economie-finance-masef',
    courses: [
      'Probabilités avancées et processus stochastiques',
      'Finance mathématique et pricing de produits dérivés',
      'Econométrie financière et séries temporelles',
      'Méthodes quantitatives pour la gestion des risques',
      'Algorithmes et simulation (Python, R)',
      'Produits de taux et crédit structuré',
      'Gestion de portefeuille quantitative',
    ],
    admissionInfo: 'Admission sur dossier. Profil recherché : master 1 ou équivalent en mathématiques, avec de solides bases en probabilités et analyse.',
  },
  {
    id: 3,
    slug: 'ensae-fq',
    rank: 3,
    name: 'Finance Quantitative — ENSAE',
    fullName: 'Finance Quantitative et Modélisation',
    school: 'ENSAE Paris · Institut Polytechnique de Paris',
    schoolBadge: 'E',
    schoolColor: '#0068B4',
    scoreGrade: 'AAA',
    scoreValue: 8.6,
    selectivity: 'Très sélectif',
    selectivityColor: '#1A6B45',
    frontOfficeRate: 82,
    stageQualityLabel: 'Tier 1',
    stageQualityRate: 82,
    criteriaHeights: [15, 19, 13, 17, 11, 20, 14, 9],
    criteriaFilledCount: 7,
    isTop3: true,
    description: "Le master Finance Quantitative et Modélisation de l'ENSAE Paris bénéficie du prestige de l'Institut Polytechnique de Paris. Fortement orienté vers la statistique et le machine learning appliqués à la finance, il se distingue par une approche data-driven unique parmi les formations quant françaises. Ses diplômés intègrent aussi bien les desks de trading quantitatif que les fonds systématiques.",
    duration: '1 an (M2) — accessible depuis le cursus ENSAE ou en admission externe',
    price: '243 € / an (frais universitaires)',
    website: 'https://www.ensae.fr/formations/masteres-specialises-et-masters/master-finance-quantitative/',
    courses: [
      'Mathématiques financières et EDS',
      'Machine Learning et Deep Learning pour la finance',
      'Statistique et économétrie avancée',
      'Trading algorithmique et market microstructure',
      'Risque de marché et réglementation prudentielle',
      'Données alternatives et NLP financier',
      'Optimisation stochastique',
      'Python scientifique et C++',
    ],
    admissionInfo: 'Admission sur dossier (CV, relevés de notes, lettre de motivation). Ouvert aux étudiants ENSAE et aux candidats externes avec un M1 en maths/stats/ingénierie.',
  },
  {
    id: 4,
    slug: 'master-203',
    rank: 4,
    name: 'Master 203',
    fullName: 'Master 203 — Ingénierie Financière',
    school: 'Université Paris-Dauphine · PSL · Paris',
    schoolBadge: 'D',
    schoolColor: '#00326B',
    scoreGrade: 'AA',
    scoreValue: 8.2,
    selectivity: 'Très sélectif',
    selectivityColor: '#1A6B45',
    frontOfficeRate: 79,
    stageQualityLabel: 'Tier 1–2',
    stageQualityRate: 74,
    criteriaHeights: [14, 17, 12, 10, 16, 13, 8, 11],
    criteriaFilledCount: 6,
    isTop3: false,
    description: "Le Master 203 Ingénierie Financière de Paris-Dauphine est une formation très complète qui couvre à la fois les aspects quantitatifs et les marchés financiers dans leur ensemble. Il présente la particularité d'accueillir un profil plus diversifié que les masters purement mathématiques, avec des étudiants issus d'écoles de commerce comme d'écoles d'ingénieurs.",
    duration: '1 an (M2)',
    price: '243 € / an (frais universitaires)',
    website: 'https://dauphine.psl.eu/formations/masters/finance/m2-ingenierie-financiere',
    courses: [
      'Produits dérivés et structurés',
      'Modélisation des taux d\'intérêt',
      'Risque de crédit et dérivés de crédit',
      'Gestion quantitative de portefeuille',
      'Finance d\'entreprise avancée',
      'Réglementation financière (MiFID, Bâle)',
      'VBA et Python pour la finance',
    ],
    admissionInfo: 'Admission sur dossier et entretien. Ouvert aux profils ingénieurs, mathématiques et grandes écoles de commerce avec forte composante quantitative.',
  },
  {
    id: 5,
    slug: 'mmmef',
    rank: 5,
    name: 'MMMEF',
    fullName: 'MMMEF — Modélisation Mathématique en Économie et Finance',
    school: 'Université Paris 1 Panthéon-Sorbonne · Paris',
    schoolBadge: 'P',
    schoolColor: '#1B5BAB',
    scoreGrade: 'AA',
    scoreValue: 7.9,
    selectivity: 'Sélectif',
    selectivityColor: '#A86E1E',
    frontOfficeRate: 72,
    stageQualityLabel: 'Tier 2',
    stageQualityRate: 65,
    criteriaHeights: [13, 16, 10, 14, 8, 12, 18, 7],
    criteriaFilledCount: 5,
    isTop3: false,
    description: "Le MMMEF de Paris 1 Panthéon-Sorbonne est un master orienté vers la modélisation économique et financière avec une composante mathématique solide. Il constitue une très bonne porte d'entrée vers la finance quantitative pour des profils universitaires en mathématiques ou économie, avec un bon rapport qualité/accessibilité.",
    duration: '1 an (M2)',
    price: '243 € / an (frais universitaires)',
    website: 'https://formations.pantheonsorbonne.fr/fr/catalogue-des-formations/master-M/master-mathematiques-et-applications-KBURQQ7K/master-2-modelisation-mathematique-en-economie-et-finance-mmmef--KBURR6BV.html',
    courses: [
      'Mathématiques financières',
      'Modèles stochastiques en économie',
      'Économétrie et prévision',
      'Gestion des risques financiers',
      'Optimisation et contrôle stochastique',
      'Simulation numérique (Python, R)',
    ],
    admissionInfo: 'Admission sur dossier. Profil recherché : M1 en mathématiques, mathématiques appliquées ou économie quantitative.',
  },
  {
    id: 6,
    slug: 'strasbourg-maf',
    rank: 6,
    name: 'Mathématiques et Applications — Finance',
    fullName: 'Mathématiques et Applications — Parcours Finance',
    school: 'Université de Strasbourg · Strasbourg',
    schoolBadge: 'S',
    schoolColor: '#C60C30',
    scoreGrade: 'AA',
    scoreValue: 7.6,
    selectivity: 'Sélectif',
    selectivityColor: '#A86E1E',
    frontOfficeRate: 68,
    stageQualityLabel: 'Tier 2',
    stageQualityRate: 60,
    criteriaHeights: [12, 15, 10, 13, 8, 11, 7, 9],
    criteriaFilledCount: 5,
    isTop3: false,
    description: "Le master Mathématiques et Applications — parcours Finance de l'Université de Strasbourg offre une solide formation quantitative dans un cadre universitaire de qualité. Moins parisien que les autres masters du classement, il présente l'avantage d'un accès plus ouvert et d'un coût de vie réduit, tout en maintenant un niveau exigeant en mathématiques financières.",
    duration: '1 an (M2)',
    price: '243 € / an (frais universitaires)',
    website: 'https://mathinfo.unistra.fr/formations/masters/mathematiques-et-applications/',
    courses: [
      'Calcul stochastique appliqué',
      'Finance de marché et produits dérivés',
      'Méthodes numériques en finance',
      'Statistique mathématique',
      'Gestion actif-passif (ALM)',
      'Programmation Python et R',
    ],
    admissionInfo: 'Admission sur dossier. Ouvert aux titulaires d\'un M1 en mathématiques ou équivalent.',
  },
]
