import 'package:http/http.dart' as http; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'dart:core'; import 'dart:convert'; import 'transport_helper.dart'; class ApiHandler { // TODO: Split next line for better Error Handling static final String baseUrl = dotenv.get("VBB_API_URL"); static final String accessID = dotenv.get("VBB_API_KEY"); // TODO: function calls for the following API calls // - [x] location.name: findStations // - [ ] location.nearbystops // - [ ] location.details // - [ ] departureBoard // - [ ] multiDepartureBoard // - [ ] journeyDetails //static Future> findStations(String locationName) async { static Future> findStations( String locationName, { int? maxStations = 5, }) async { String urlPath = '/api/fahrinfo/latest/location.name'; Uri url = Uri.https(baseUrl, urlPath, { 'accessId': accessID, 'input': locationName, 'maxNo': maxStations.toString(), 'type': 'S', // Station/Stops only }); //print(url); var jsonResponse = await http.get( url, headers: {'Accept': 'application/json'}, ); final httpPackageJson = json.decode(jsonResponse.body) as Map; //print(httpPackageJson["stopLocationOrCoordLocation"]); List stationList = httpPackageJson["stopLocationOrCoordLocation"] .map( (x) => Station.fromJson(x["StopLocation"]), ) .toList() .cast(); return stationList; } static Future> nearbyStations( String latitude, String longitude, { int? maxStations = 5, }) async { String urlPath = '/api/fahrinfo/latest/location.nearbystops'; Uri url = Uri.https(baseUrl, urlPath, { 'accessId': accessID, 'originCoordLat': latitude, 'originCoordLong': longitude, 'maxNo': maxStations.toString(), 'type': 'S', // Station/Stops only }); var jsonResponse = await http.get( url, headers: {'Accept': 'application/json'}, ); final httpPackageJson = json.decode(jsonResponse.body) as Map; final stationList = httpPackageJson["stopLocationOrCoordLocation"].map( (x) => Station.fromJson(x["StopLocation"]), ); return stationList; } static Future> departures( String stationId, { int? maxDepartures = -1, int? duration = 0, }) async { String urlPath = '/api/fahrinfo/latest/departureBoard'; String stationString = stationId.replaceAll(' ', '%20'); // reform for URL Uri url = Uri.https(baseUrl, urlPath, { 'accessId': accessID, 'id': stationString, ////'time': /current time //time from which departures will be shown 'duration': duration.toString(), //interval time in minutes 'maxJourneys': maxDepartures.toString(), //'type': 'S', // Station/Stops only }); var jsonResponse = await http.get( url, headers: {'Accept': 'application/json'}, ); final httpPackageJson = json.decode(jsonResponse.body) as Map; // try { List departureList = httpPackageJson["Departure"] .map( (x) => Departure.fromJson(x), ) .toList() .cast(); return departureList; // } catch (e) { // // TODO: logging // // empty response // print('Error: $e'); // // print( // // 'Response for Station-id "$stationString" contains no field "Departure": $httpPackageJson', // // ); // return []; // } } static Future> departuresAggregate( List stationList, { int? maxDepartures = -1, int? duration = -1, }) async { String urlPath = '/api/fahrinfo/latest/multiDepartureBoard'; String stationListString = stationList .reduce((value, element) => value + '|' + element) .replaceAll(' ', '%20'); // reform for URL Uri url = Uri.https(baseUrl, urlPath, { 'accessId': accessID, 'id': stationListString, ////'time': /current time //time from which departures will be shown 'duration': duration.toString(), //interval time in minutes 'maxJourneys': maxDepartures.toString(), 'type': 'S', // Station/Stops only }); var jsonResponse = await http.get( url, headers: {'Accept': 'application/json'}, ); final httpPackageJson = json.decode(jsonResponse.body) as Map; List departureList = httpPackageJson["Departure"].map( (x) => Departure.fromJson(x), ); return departureList; } static Future> trip( String originId, String destinationId, { String? via, String? viaID, String? date, String? time, int? maxChange, int? minChangeTime, int? maxChangeTime, bool? arrivalTime, // int? products, // which transport modi to use - ignore for now // String rtMode, // wherether to use real time data // String trainFilter, }) async { String urlPath = '/api/fahrinfo/latest/trip'; String startId = originId.replaceAll(' ', '%20'); // reform for URL String endId = destinationId.replaceAll(' ', '%20'); // reform for URL Uri url = Uri.https(baseUrl, urlPath, { 'accessId': accessID, 'originId': startId, 'destId': endId, ////'time': /current time //time from which departures will be shown 'time': time.toString(), //interval time in minutes 'maxChange': maxChange.toString(), 'type': 'S', // Station/Stops only }); var jsonResponse = await http.get( url, headers: {'Accept': 'application/json'}, ); final httpPackageJson = json.decode(jsonResponse.body) as Map; final idList = httpPackageJson["Trip"].map( (x) => x["LegList"]["Leg"].map((y) => y["JourneyDetail"]["ref"]), ); return idList; } static Future> tripDetail( String id, { String? date, String? fromId, int? fromIdx, String? toId, int? toIdx, }) async { String urlPath = '/api/fahrinfo/latest/journeyDetail'; Uri url = Uri.https(baseUrl, urlPath, { 'accessId': accessID, 'id': id, 'fromId': fromId, 'toId': toId, }); var jsonResponse = await http.get( url, headers: {'Accept': 'application/json'}, ); final httpPackageJson = json.decode(jsonResponse.body) as Map; final idList = httpPackageJson["Stops"]["Stop"].map((x) => x["id"]); return idList; } }