import type { Place } from './types' export interface BookingLink { url: string label: string provider: string } /** Normalise un nom de ville pour l'inclure dans une URL slug. */ function slugify(label: string): string { return label .normalize('NFD').replace(/\p{Diacritic}/gu, '') .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, '') } /** Extrait le nom de ville avant la virgule ("Lille, France" -> "Lille"). */ function cityName(label: string): string { return label.split(',')[0]?.trim() ?? label.trim() } /** Format de date que Kombo et CheckMyBus acceptent tous les deux. */ function dateISO(d: Date): string { return d.toISOString().slice(0, 10) } /** Kombo comprend les noms de ville en clair : pas de mapping de gares a maintenir. */ export function buildKomboLink(from: Place, to: Place, date: Date): BookingLink { const f = encodeURIComponent(cityName(from.label)) const t = encodeURIComponent(cityName(to.label)) const d = dateISO(date) return { url: `https://www.kombo.co/fr/app/outward/1/1/18/${d}/${f}/${t}/0/0/results`, label: 'Reserver sur Kombo', provider: 'Kombo', } } /** * CheckMyBus accepte un fallback avec UUID zeros quand on ne connait pas * son identifiant interne : le nom + les coordonnees suffisent a lancer * la recherche. Le fragment porte tout, y compris la date. */ export function buildCheckMyBusLink(from: Place, to: Place, date: Date): BookingLink { const zeroId = '00000000-0000-0000-0000-000000000000' const encodeStop = (p: Place) => encodeURIComponent(`${cityName(p.label)}, France`) + `%24${p.lat}%2C${p.lon}` + `%24${zeroId}%24${zeroId}%24true%24false` const fromSlug = slugify(cityName(from.label)) const toSlug = slugify(cityName(to.label)) const d = dateISO(date) const fragment = [ `departureDate=${d}`, `origin=${encodeStop(from)}`, `destination=${encodeStop(to)}`, 'sortValue=Relevance', 'sortOrder=ascending', 'adults=1', ].join('&') return { url: `https://www.checkmybus.fr/${fromSlug}/${toSlug}?mode=search#${fragment}`, label: 'Chercher sur CheckMyBus', provider: 'CheckMyBus', } } /** Chargemap : on ouvre juste la page d'accueil du planificateur. */ export function buildChargemapLink(): BookingLink { return { url: 'https://chargemap.com/map', label: 'Ouvrir Chargemap', provider: 'Chargemap', } } /** Retourne le lien approprie pour le mode donne, ou null si aucun. */ export function buildBookingLink( mode: 'train' | 'bus' | 'electric_car' | 'bike', from: Place, to: Place, date: Date, ): BookingLink | null { switch (mode) { case 'train': return buildKomboLink(from, to, date) case 'bus': return buildCheckMyBusLink(from, to, date) case 'electric_car': return buildChargemapLink() case 'bike': return null } }