import 'dart:convert';
import 'dart:io';
import 'package:comwell_key_app/hotel_information/models/hotel.dart';
import 'package:comwell_key_app/domain/models/housekeeping.dart';
import 'package:comwell_key_app/domain/models/notification_permission.dart';
import 'package:comwell_key_app/presentation/screens/pregistration/prereg_request_model.dart';
import 'package:comwell_key_app/services/http_client.dart';
import 'package:comwell_key_app/services/models/booking_dto.dart';
import 'package:comwell_key_app/services/models/simple_user_dto.dart';
import 'package:comwell_key_app/services/models/user_dto.dart';
import 'package:comwell_key_app/services/utils/api_endpoints.dart';
import 'package:comwell_key_app/up_sales/models/addon_list.dart';
import 'package:comwell_key_app/up_sales/models/dto/up_sales_dto.dart';
import 'package:comwell_key_app/utils/json.dart';
import 'package:comwell_key_app/utils/l10n_utils.dart';
import 'package:comwell_key_app/utils/locator.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:package_info_plus/package_info_plus.dart';
class Api {
final ComwellHttpClient _client = locator.get();
Dio get dio => _client.dio;
Api();
// Get current locale globally
Locale get _currentLocale {
final navigatorKey = locator<GlobalKey<NavigatorState>>();
final languageCode = navigatorKey.currentContext!.strings.localeName;
final countryCode = switch (languageCode) {
'en' => 'US',
'da' => 'DK',
_ => 'DK',
};
return Locale(languageCode, countryCode);
}
Future<Response<dynamic>> logout() async {
return await dio.post(ApiEndpoints.logout);
}
Future<List<BookingDTO>> fetchPastBookingsForUser() async {
final body = {
"skip": 0,
"limit": 100,
};
final json = jsonEncode(body);
final response = await dio.get<List<dynamic>>(ApiEndpoints.getPastBookings, data: json);
return response.data!.map((e) => BookingDTO.fromJson(e as Json)).toList();
}
Future<List<BookingDTO>> fetchCancelledBookingsForUser() async {
final body = {
"skip": 0,
"limit": 100,
};
final json = jsonEncode(body);
final response = await dio.get<List<dynamic>>(ApiEndpoints.getCancelledBookings, data: json);
return response.data!.map((e) => BookingDTO.fromJson(e as Json)).toList();
}
Future<List<BookingDTO>> fetchCurrentBookingsForUser() async {
final body = {
"skip": 0,
"limit": 100,
};
final json = jsonEncode(body);
final response = await dio.get<List<dynamic>>(ApiEndpoints.getCurrentBookings, data: json);
return response.data!.map((e) => BookingDTO.fromJson(e as Json)).toList();
}
Future<Response<dynamic>> fetchProfileSettings() async {
final response = await dio.get<dynamic>(ApiEndpoints.getGuestProfile);
return response;
}
Future<void> deleteProfile() {
return dio.delete<void>(ApiEndpoints.deleteGuest);
}
Future<Response<dynamic>> signupForComwellClub() async {
final response = await dio.post<dynamic>(ApiEndpoints.clubSignup);
return response;
}
Future<Response<dynamic>> preArrival(PreregRequestDto request) async {
final json = jsonEncode(request);
debugPrint("json: $json");
final response = await dio.post<dynamic>(ApiEndpoints.preArrivalByToken, data: json);
return response;
}
Future<Response<dynamic>> getNotificationPermissions() async {
final response = await dio.get<dynamic>(
'${ApiEndpoints.communicationPreference}?permissionAreas=club',
);
return response;
}
Future<BookingDTO> findBookingByConfirmationId(String confirmationId, String lastName) async {
final body = {
"confirmationNumber": confirmationId,
"lastName": lastName,
};
final data = jsonEncode(body);
final response = await dio.post<Json>(ApiEndpoints.findBookingByConfirmationId, data: data);
return BookingDTO.fromJson(response.data!);
}
Future<dynamic> updateNotificationPreferences(
Iterable<NotificationPermission> notificationPermissions,
) {
final permissions = {
for (var permission in notificationPermissions) permission.code.toString(): permission.given,
};
final simpleUserDto = SimpleUserDto(permissions: permissions);
return updateUser(simpleUserDto);
}
Future<dynamic> updateUser(SimpleUserDto updatedUser) {
final json = jsonEncode(updatedUser);
debugPrint("Updated user: $json");
final response = dio.put<void>(
ApiEndpoints.updateGuestData,
data: json,
);
return response;
}
Future<dynamic> getHotelInfo(String hotelCode) async {
final cultureString = _currentLocale.toString().replaceAll('_', '-');
final url = '${ApiEndpoints.getHotelInfo}?hotelCode=$hotelCode&culture=$cultureString';
final response = await dio.get<Json>(url);
return response;
}
Future<Json?> checkIn(String confirmationNumber) async {
final body = {
"confirmationNumber": confirmationNumber,
};
final data = jsonEncode(body);
final response = await dio.post<Json>(ApiEndpoints.checkIn, data: data);
return response.data;
}
Future<Json?> checkOut(String confirmationNumber) async {
final body = {
"confirmationNumber": confirmationNumber,
};
final data = jsonEncode(body);
final response = await dio.post<Json>(ApiEndpoints.checkOut, data: data);
return response.data;
}
Future<Json?> orderHousekeeping(Housekeeping housekeeping) async {
final body = {
"hotelCode": housekeeping.hotelCode,
"roomNumber": housekeeping.roomNumber,
"cleaning": housekeeping.cleaning,
"soap": housekeeping.soap,
"towels": housekeeping.towels,
"trash": housekeeping.trash,
"refill": housekeeping.refill,
};
final data = jsonEncode(body);
final response = await dio.post<Json>(ApiEndpoints.orderHousekeeping, data: data);
return response.data;
}
Future<void> sendContact(String hotelCode) async {}
Future<void> bookSpa(Hotel hotel) async {
await Future<void>.delayed(const Duration(seconds: 2));
// TODO implement
}
Future<String> createEndpointRegistration() async {
final response = await dio.post<String>(ApiEndpoints.createEndpointRegistration);
final json = jsonDecode(response.data!) as Map<String, dynamic>;
return json["invitationCode"]! as String;
}
Future<void> provisionKey(String confirmationNumber, String hotelCode) async {
await dio.post<void>(
ApiEndpoints.provisionKey,
data: {'confirmationNumber': confirmationNumber, 'hotelCode': hotelCode},
);
}
Future<BookingDTO?> getBookingDetails(String confirmationNumber, String hotelCode) async {
final uri = Uri.parse(ApiEndpoints.getBookingDetails).replace(
queryParameters: {
'confirmationNumber': confirmationNumber,
'hotelCode': hotelCode,
},
);
final response = await dio.get<Json>(uri.toString());
debugPrint("Response: ${response.data}");
return BookingDTO.fromJson(response.data!);
}
Future<Json> postRoomSelection(String confirmationNumber, String userId) async {
final body = {
"confirmationNumber": confirmationNumber,
"userId": userId,
};
final data = jsonEncode(body);
final response = await dio.post<Json>('ApiEndpoints.roomSelection', data: data);
return response.data!;
}
Future<UpSalesDTO> fetchUpSales(String confirmationNumber, String hotelCode) async {
final body = {
"confirmationNumber": confirmationNumber,
"property": hotelCode,
"culture": _currentLocale.toString().replaceAll('_', '-'),
};
final data = jsonEncode(body);
final response = await dio.post<Json>(ApiEndpoints.upSales, data: data);
return UpSalesDTO.fromJson(response.data!);
}
Future<void> addUpSalesToBooking(
String confirmationNumber,
String hotelCode,
String roomType,
List<AddOnList> selectedUpSales,
) async {
final body = {
"confirmationNumber": confirmationNumber,
"property": hotelCode,
"roomType": roomType,
"addOnList": selectedUpSales,
};
final data = jsonEncode(body);
await dio.post<void>(ApiEndpoints.addUpSalesToBooking, data: data);
return;
}
Future<void> removeGuestsFromBooking(
String confirmationNumber,
String hotelCode,
int guestId,
) async {
final body = {
"hotelCode": hotelCode,
"confirmationNumber": confirmationNumber,
"personId": guestId,
};
final data = jsonEncode(body);
debugPrint("Data: $data");
await dio.post<void>(ApiEndpoints.removeGuestsFromBooking, data: data);
}
Future<String> createRoomSharingLink(
String confirmationNumber,
String hotelCode,
int sharingType,
) async {
final body = {
"confirmationNumber": confirmationNumber,
"hotelCode": hotelCode,
"sharingType": sharingType,
};
final data = jsonEncode(body);
final response = await dio.post<String>(ApiEndpoints.createRoomSharingLink, data: data);
debugPrint("Response: $response");
return response.data!;
}
Future<BookingDTO> consumeRoomSharingLink(String sharingId, String hotelCode) async {
final uri = Uri.parse(ApiEndpoints.consumeRoomSharingLink).replace(
queryParameters: {
'sharingId': sharingId,
'hotelCode': hotelCode,
},
);
final response = await dio.get<Json>(uri.toString());
return BookingDTO.fromJson(response.data!);
}
Future<void> registerDeviceAndProfileSymplify(String token) async {
final symplifyUrl = dotenv.env['SYMPLIFY_URL'];
final apiKey = dotenv.env['SYMPLIFY_API_KEY'];
final customerId = dotenv.env['SYMPLIFY_CUSTOMER_ID'];
final packageInfo = await PackageInfo.fromPlatform();
final packageName = packageInfo.packageName;
debugPrint('Package name: $packageName');
//App type 6 is Firebase
//https://apidocs.symplify.com/#233ad620-28d7-4d19-b394-cfcac0ed2a49
final profileResponse = await fetchProfileSettings();
final profileData = profileResponse.data as Json;
final profile = UserDto.fromJson(profileData);
String emailAddress = '';
String firstName = '';
String lastName = '';
if (Platform.isIOS) {
emailAddress = '${profile.email}IOS-test';
firstName = '${profile.firstName}IOS-test';
lastName = '${profile.lastName}IOS-test';
} else {
emailAddress = '${profile.email}Android-test';
firstName = '${profile.firstName}Android-test';
lastName = '${profile.lastName}Android-test';
}
final body = {
"originalId": emailAddress,
"firstName": firstName,
"lastName": lastName,
"emailAddress": emailAddress,
"deviceInfo": [
{
"devicetoken": token,
"appType": "6",
},
],
};
final data = jsonEncode(body);
await dio.put<void>(
'$symplifyUrl/$customerId/apps/$packageName/devices',
data: data,
options: Options(
headers: {
'X-Carma-Authentication-Token': apiKey,
'Content-Type': 'application/json',
},
),
);
return;
}
}