import { db } from '../db/index.js'; import type { Country } from '../plans.js'; import type { City } from '../plans.js'; import type { Airport, Airline } from '../flights.js'; // --- Countries --- export function listCountries(query?: string): (Country & { id: number })[] { if (!query?.trim()) { return db.all( 'SELECT id, name, country_code FROM countries ORDER BY name' ); } const pattern = `%${query.trim()}%`; return db.all( `SELECT id, name, country_code FROM countries WHERE name LIKE ? COLLATE NOCASE OR country_code LIKE ? COLLATE NOCASE ORDER BY name LIMIT 200`, [pattern, pattern] ); } export function createCountry(name: string, countryCode: string): Country & { id: number } { db.run('INSERT INTO countries (name, country_code) VALUES (?, ?)', [ name.trim(), countryCode.trim().toUpperCase() ]); return db.get( 'SELECT id, name, country_code FROM countries WHERE country_code = ?', [countryCode.trim().toUpperCase()] )!; } export function updateCountry(id: number, name: string, countryCode: string): void { db.run('UPDATE countries SET name = ?, country_code = ? WHERE id = ?', [ name.trim(), countryCode.trim().toUpperCase(), id ]); } export function deleteCountry(id: number): void { db.run('DELETE FROM countries WHERE id = ?', [id]); } // --- Cities --- export function listCities(query?: string, countryCode?: string): City[] { if (!query?.trim()) { if (countryCode?.trim()) { return db.all( 'SELECT id, name, country, country_code, population FROM cities WHERE country_code = ? ORDER BY name LIMIT 200', [countryCode.trim().toUpperCase()] ); } return db.all( 'SELECT id, name, country, country_code, population FROM cities ORDER BY name LIMIT 200' ); } const pattern = `%${query.trim()}%`; if (countryCode?.trim()) { return db.all( `SELECT id, name, country, country_code, population FROM cities WHERE (name LIKE ? COLLATE NOCASE OR country LIKE ? COLLATE NOCASE) AND country_code = ? ORDER BY name LIMIT 200`, [pattern, pattern, countryCode.trim().toUpperCase()] ); } return db.all( `SELECT id, name, country, country_code, population FROM cities WHERE name LIKE ? COLLATE NOCASE OR country LIKE ? COLLATE NOCASE ORDER BY name LIMIT 200`, [pattern, pattern] ); } export function createCity( name: string, country: string, countryCode: string, population?: number | null ): City { const maxId = db.get<{ max: number }>('SELECT COALESCE(MAX(id), 0) + 1 as max FROM cities'); const id = maxId?.max ?? 1; db.run( 'INSERT INTO cities (id, name, country, country_code, population) VALUES (?, ?, ?, ?, ?)', [id, name.trim(), country.trim(), countryCode.trim().toUpperCase(), population ?? null] ); return db.get('SELECT * FROM cities WHERE id = ?', [id])!; } export function updateCity( id: number, name: string, country: string, countryCode: string, population?: number | null ): void { db.run('UPDATE cities SET name = ?, country = ?, country_code = ?, population = ? WHERE id = ?', [ name.trim(), country.trim(), countryCode.trim().toUpperCase(), population ?? null, id ]); } export function deleteCity(id: number): void { db.run('DELETE FROM cities WHERE id = ?', [id]); } // --- Airports --- export function listAirports(query?: string): Airport[] { if (!query?.trim()) { return db.all('SELECT * FROM airports ORDER BY name LIMIT 200'); } const pattern = `%${query.trim()}%`; return db.all( `SELECT * FROM airports WHERE name LIKE ? COLLATE NOCASE OR iata_code LIKE ? COLLATE NOCASE OR icao_code LIKE ? COLLATE NOCASE OR city LIKE ? COLLATE NOCASE OR country LIKE ? COLLATE NOCASE ORDER BY name LIMIT 200`, [pattern, pattern, pattern, pattern, pattern] ); } export function createAirport( name: string, country: string, countryCode: string, iataCode?: string | null, icaoCode?: string | null, city?: string | null, latitude?: number | null, longitude?: number | null, timezone?: string | null ): Airport { db.run( `INSERT INTO airports (name, city, country, country_code, iata_code, icao_code, latitude, longitude, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ name.trim(), city?.trim() ?? null, country.trim(), countryCode.trim().toUpperCase(), iataCode?.trim() ?? null, icaoCode?.trim() ?? null, latitude ?? null, longitude ?? null, timezone?.trim() ?? null ] ); return db.get('SELECT * FROM airports WHERE id = last_insert_rowid()')!; } export function updateAirport( id: number, name: string, country: string, countryCode: string, iataCode?: string | null, icaoCode?: string | null, city?: string | null, latitude?: number | null, longitude?: number | null, timezone?: string | null ): void { db.run( `UPDATE airports SET name = ?, city = ?, country = ?, country_code = ?, iata_code = ?, icao_code = ?, latitude = ?, longitude = ?, timezone = ? WHERE id = ?`, [ name.trim(), city?.trim() ?? null, country.trim(), countryCode.trim().toUpperCase(), iataCode?.trim() ?? null, icaoCode?.trim() ?? null, latitude ?? null, longitude ?? null, timezone?.trim() ?? null, id ] ); } export function deleteAirport(id: number): void { db.run('DELETE FROM airports WHERE id = ?', [id]); } // --- Airlines --- export function listAirlines(query?: string): Airline[] { if (!query?.trim()) { return db.all('SELECT * FROM airlines ORDER BY name LIMIT 200'); } const pattern = `%${query.trim()}%`; return db.all( `SELECT * FROM airlines WHERE name LIKE ? COLLATE NOCASE OR iata_code LIKE ? COLLATE NOCASE OR icao_code LIKE ? COLLATE NOCASE OR country LIKE ? COLLATE NOCASE ORDER BY name LIMIT 200`, [pattern, pattern, pattern, pattern] ); } export function createAirline( name: string, country?: string | null, countryCode?: string | null, iataCode?: string | null, icaoCode?: string | null ): Airline { db.run( 'INSERT INTO airlines (name, country, country_code, iata_code, icao_code) VALUES (?, ?, ?, ?, ?)', [ name.trim(), country?.trim() ?? null, countryCode?.trim()?.toUpperCase() ?? null, iataCode?.trim() ?? null, icaoCode?.trim() ?? null ] ); return db.get('SELECT * FROM airlines WHERE id = last_insert_rowid()')!; } export function updateAirline( id: number, name: string, country?: string | null, countryCode?: string | null, iataCode?: string | null, icaoCode?: string | null ): void { db.run( 'UPDATE airlines SET name = ?, country = ?, country_code = ?, iata_code = ?, icao_code = ? WHERE id = ?', [ name.trim(), country?.trim() ?? null, countryCode?.trim()?.toUpperCase() ?? null, iataCode?.trim() ?? null, icaoCode?.trim() ?? null, id ] ); } export function deleteAirline(id: number): void { db.run('DELETE FROM airlines WHERE id = ?', [id]); } // --- Tour Operators --- export interface TourOperator { id: number; name: string; website: string | null; highlight_color: string | null; created_at: string; updated_at: string; } export function listTourOperators(query?: string): TourOperator[] { if (!query?.trim()) { return db.all('SELECT * FROM tour_operators ORDER BY name'); } const pattern = `%${query.trim()}%`; return db.all( `SELECT * FROM tour_operators WHERE name LIKE ? COLLATE NOCASE OR website LIKE ? COLLATE NOCASE ORDER BY name LIMIT 200`, [pattern, pattern] ); } export function createTourOperator( name: string, website?: string | null, highlightColor?: string | null ): TourOperator { db.run('INSERT INTO tour_operators (name, website, highlight_color) VALUES (?, ?, ?)', [ name.trim(), website?.trim() ?? null, highlightColor?.trim() ?? null ]); return db.get('SELECT * FROM tour_operators WHERE id = last_insert_rowid()')!; } export function updateTourOperator( id: number, name: string, website?: string | null, highlightColor?: string | null ): void { db.run( `UPDATE tour_operators SET name = ?, website = ?, highlight_color = ?, updated_at = datetime('now') WHERE id = ?`, [name.trim(), website?.trim() ?? null, highlightColor?.trim() ?? null, id] ); } export function deleteTourOperator(id: number): void { db.run('DELETE FROM tour_operators WHERE id = ?', [id]); } export function getTourOperatorByName(name: string): TourOperator | null { return ( db.get('SELECT * FROM tour_operators WHERE name = ? COLLATE NOCASE', [ name.trim() ]) ?? null ); }