import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:path_provider/path_provider.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/notification/firebase_notification_manger.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:http/http.dart' as http; import 'package:test_sa/modules/cx_module/chat/model/chat_attachment_model.dart'; import 'api_client.dart'; import 'model/chat_login_response_model.dart'; import 'model/chat_participant_model.dart'; import 'model/get_search_user_chat_model.dart'; import 'model/get_single_user_chat_list_model.dart'; import 'model/get_user_login_token_model.dart' as userLoginTokenModel; import 'model/user_chat_history_model.dart'; // import 'package:mohem_flutter_app/api/api_client.dart'; // import 'package:mohem_flutter_app/app_state/app_state.dart'; // import 'package:mohem_flutter_app/classes/consts.dart'; // import 'package:mohem_flutter_app/classes/utils.dart'; // import 'package:mohem_flutter_app/exceptions/api_exception.dart'; // import 'package:mohem_flutter_app/main.dart'; // import 'package:mohem_flutter_app/models/chat/chat_user_image_model.dart'; // import 'package:mohem_flutter_app/models/chat/create_group_request.dart' as createGroup; // import 'package:mohem_flutter_app/models/chat/get_group_chat_history.dart'; // import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; // import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart' as groups; // import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart'; // import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user; // import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; class ChatApiClient { static final ChatApiClient _instance = ChatApiClient._internal(); ChatApiClient._internal(); factory ChatApiClient() => _instance; ChatLoginResponse? chatLoginResponse; Future getChatLoginToken(int moduleId, int requestId, String title, String employeeNumber, String assigneeEmployeeNumber) async { String platform; if (Platform.isIOS) { platform = "IOS"; } else { if (await FirebaseNotificationManger.isGoogleServicesAvailable()) { platform = "GOOGLE"; } else { platform = "HUAWEI"; } } Response response = await ApiClient().postJsonForResponse(URLs.chatSdkToken, { "apiKey": URLs.chatApiKey, "employeeNumber": employeeNumber, "assigneeEmployeeNumber": assigneeEmployeeNumber, "userDetails": {"userName": ApiManager.instance.user?.username, "email": ApiManager.instance.user?.email}, "contextEnabled": true, "moduleCode": moduleId.toString(), "referenceId": requestId.toString(), // "referenceType": "ticket", "title": title, "deviceToken": FirebaseNotificationManger.token, "isHuaweiDevice": platform == "HUAWEI", "platform": platform, "voIPToken": null }); if (!kReleaseMode) { // logger.i("login-res: " + response.body); } if (response.statusCode == 200) { chatLoginResponse = ChatLoginResponse.fromJson(jsonDecode(response.body)); } return chatLoginResponse; } Future loadParticipants(int moduleId, int referenceId, String? assigneeEmployeeNumber) async { Response response = await ApiClient().getJsonForResponse("${URLs.chatHubUrlApi}/chat/context/$moduleId/$referenceId?assigneeEmployeeNumber=$assigneeEmployeeNumber", token: chatLoginResponse!.token); if (!kReleaseMode) { // logger.i("login-res: " + response.body); } if (response.statusCode == 200) { return ChatParticipantModel.fromJson(jsonDecode(response.body)); } else { return null; } } Future> viewAllDocuments(int moduleId, int referenceId) async { Response response = await ApiClient().getJsonForResponse("${URLs.chatHubUrlApi}/attachments/conversation?referenceId=$referenceId&moduleCode=$moduleId", token: chatLoginResponse!.token); if (response.statusCode == 200) { List data = jsonDecode(response.body)["response"]; return data.map((elemet) => ChatAttachment.fromJson(elemet)).toList(); } else { return []; } } Future> loadChatHistory(int moduleId, int referenceId, String myId, String otherId) async { Response response = await ApiClient().postJsonForResponse( "${URLs.chatHubUrlApi}/UserChatHistory/GetUserChatHistory/$myId/$otherId/0", {"moduleCode": moduleId.toString(), "referenceId": referenceId.toString()}, token: chatLoginResponse!.token); try { if (response.statusCode == 200) { List data = jsonDecode(response.body); return data.map((elemet) => SingleUserChatModel.fromJson(elemet)).toList(); // return UserChatHistoryModel.fromJson(jsonDecode(response.body)); } else { return []; } } catch (ex) { return []; } } /* Future sendTextMessage(String message, int conversationId) async { try { Response response = await ApiClient().postJsonForResponse("${URLs.chatHubUrlApi}/chat/conversations/$conversationId/messages", {"content": message, "messageType": "Text"}, token: chatLoginResponse!.token); if (response.statusCode == 200) { return ChatResponse.fromJson(jsonDecode(response.body)); } else { return null; } } catch (ex) { print(ex); return null; } }*/ // Future getChatMemberFromSearch(String searchParam, int cUserId, int pageNo) async { // ChatUserModel chatUserModel; // Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatLoginTokenUrl}getUserWithStatusAndFavAsync", {"employeeNumber": cUserId, "userName": searchParam, "pageNumber": pageNo}, // token: AppState().chatDetails!.response!.token); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // chatUserModel = chatUserModelFromJson(response.body); // return chatUserModel; // } // //Get User Recent Chats // Future getRecentChats() async { // try { // Response response = // // // // await ApiManager.instance.get(URLs.getAllRequestsAndCount,h); // // // await ApiClient().getJsonForResponse( // "${ApiConsts.chatRecentUrl}getchathistorybyuserid", // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // return ChatUserModel.fromJson( // json.decode(response.body), // ); // } catch (e) { // throw e; // } // } // // Get Favorite Users // Future getFavUsers() async { // Response favRes = await ApiClient().getJsonForResponse( // "${ApiConsts.chatFavUser}getFavUserById/${AppState().chatDetails!.response!.id}", // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + favRes.body); // } // return ChatUserModel.fromJson(json.decode(favRes.body)); // } // //Get User Chat History // Future getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async { // try { // Response response = await ApiClient().getJsonForResponse( // "${ApiConsts.chatSingleUserHistoryUrl}GetUserChatHistory/$senderUID/$receiverUID/$paginationVal", // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // return response; // } catch (e) { // getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal); // throw e; // } // } // //Favorite Users // Future favUser({required int userID, required int targetUserID}) async { // Response response = await ApiClient().postJsonForResponse("${ApiConsts.chatFavUser}addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); // return favoriteChatUser; // } // //UnFavorite Users // Future unFavUser({required int userID, required int targetUserID}) async { // try { // Response response = await ApiClient().postJsonForResponse( // "${ApiConsts.chatFavUser}deleteFavUser", // {"targetUserId": targetUserID, "userId": userID}, // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body); // return favoriteChatUser; // } catch (e) { // e as APIException; // throw e; // } // } // Upload Chat Media Future uploadMedia(String userId, File file, String fileSource, {Map? jsonData}) async { dynamic request = MultipartRequest('POST', Uri.parse('${URLs.chatHubUrlApi}/attachments/upload')); request.fields.addAll({'userId': userId, 'fileSource': fileSource}); if (jsonData != null) { request.fields.addAll(jsonData); } request.files.add(await MultipartFile.fromPath('file', file.path)); request.headers.addAll({'Authorization': 'Bearer ${chatLoginResponse!.token}'}); StreamedResponse response = await request.send(); String data = await response.stream.bytesToString(); if (!kReleaseMode) { print("uploadMedia: $data"); } return jsonDecode(data); } // // Download File For Chat // Future downloadURL({required String fileName, required String fileTypeDescription, required int fileSource,required String url}) async { // Response response = await ApiClient().postJsonForResponse( // "${ApiConsts.chatMediaImageUploadUrl}download", // {"fileType": fileTypeDescription, "fileName": fileName, "fileSource": fileSource}, // token: AppState().chatDetails!.response!.token, // ); // Uint8List data = Uint8List.fromList(response.bodyBytes); // return data; // } // Download File For Chat Future downloadURL(String url, {required String fileName, required String fileTypeDescription, required int fileSource}) async { Response response = await ApiClient().postJsonForResponse( url, {"fileType": fileTypeDescription, "fileName": fileName, "fileSource": fileSource}, token: chatLoginResponse!.token, ); Uint8List data = Uint8List.fromList(response.bodyBytes); return data; } /// Downloads a file from a secure URL that uses a 302 redirect. /// /// [url]: The initial URL that requires the authorization token. /// [token]: The Bearer token for authorization. /// [saveFileName]: The name to give the downloaded file (e.g., 'my-document.pdf'). Future downloadFileWithHttp(String url, {required String fileName, required String fileTypeDescription, required int fileSource}) async { final client = http.Client(); File? file; try { final request = http.Request('GET', Uri.parse(url)); request.headers['Authorization'] = 'Bearer ${chatLoginResponse!.token}'; // This is the most important part: prevent automatic redirection. request.followRedirects = false; final streamedResponse = await client.send(request); // --- Step 2: Check the response and handle the redirect --- // Check for a 302 redirect status. if (streamedResponse.statusCode == 302) { // Get the new URL from the 'Location' header. final redirectUrl = streamedResponse.headers['location']; if (redirectUrl == null) { throw Exception('302 Redirect did not contain a Location header.'); } final fileResponse = await http.get(Uri.parse(redirectUrl), headers: {'Authorization': 'Bearer ${chatLoginResponse!.token}'}); if (fileResponse.statusCode == 200) { // Get a safe directory to save the file. final dir = await getTemporaryDirectory(); file = File('${dir.path}/$fileName'); // Write the file to disk. await file.writeAsBytes(fileResponse.bodyBytes); print("File downloaded successfully and saved to: ${file.path}"); } else { // The download from the final URL failed. throw Exception('Failed to download from redirect URL. Status: ${fileResponse.statusCode}'); } } // Handle cases where the server might just send the file directly. else if (streamedResponse.statusCode == 200) { print("Server sent file directly without redirect."); final dir = await getTemporaryDirectory(); file = File('${dir.path}/$fileName'); await file.writeAsBytes(await streamedResponse.stream.toBytes()); print("File downloaded successfully and saved to: ${file.path}"); } // Handle other error statuses. else { throw Exception('Failed to initiate download. Status: ${streamedResponse.statusCode}'); } } catch (e) { print("An error occurred during download: $e"); } finally { // Always close the client to free up resources. client.close(); } return file; } // //Get Chat Users & Favorite Images // Future> getUsersImages({required List encryptedEmails}) async { // List imagesData = []; // Response response = await ApiClient().postJsonForResponse( // "${ApiConsts.chatUserImages}images", // {"encryptedEmails": encryptedEmails, "fromClient": false}, // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // if (response.statusCode == 200) { // imagesData = chatUserImageModelFromJson(response.body); // } else if (response.statusCode == 500 || response.statusCode == 504) { // getUsersImages(encryptedEmails: encryptedEmails); // } else { // Utils.showToast("Something went wrong while loading images"); // imagesData = []; // } // return imagesData; // } // // //group chat apis start here. // Future getGroupsByUserId() async { // try { // Response response = await ApiClient().getJsonForResponse( // "${ApiConsts.getGroupByUserId}${AppState().chatDetails!.response!.id}", // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // return groups.GetUserGroups.fromRawJson(response.body); // } catch (e) { // //if fail api returning 500 hence just printing here // print(e); // throw e; // } // } // Future deleteGroup(int? groupId) async { // try { // Response response = await ApiClient().postJsonForResponse( // ApiConsts.deleteGroup, // {"groupId": groupId}, // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // return response; // } catch (e) { // //if fail api returning 500 hence just printing here // print(e); // throw e; // } // } // Future updateGroupAdmin(int? groupId, List groupList) async { // try { // Response response = await ApiClient().postJsonForResponse( // ApiConsts.updateGroupAdmin, // {"groupId": groupId, "groupUserList": groupList}, // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // return response; // } catch (e) { // //if fail api returning 500 hence just printing here // print(e); // throw e; // } // } // Future> getGroupChatHistory(int? groupId, List groupList) async { // try { // Response response = await ApiClient().postJsonForResponse( // ApiConsts.getGroupChatHistoryAsync, // {"groupId": groupId, "targetUserList": groupList, "CurrentId": AppState().chatDetails!.response!.id}, // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // List groupChat = []; // List groupChatData = json.decode(response.body); // for (var i in groupChatData) { // groupChat.add(GetGroupChatHistoryAsync.fromJson(i)); // } // // groupChat.sort((a, b) => b.createdDate!.compareTo(a.createdDate!)); // return groupChat; // // for(GetGroupChatHistoryAsync i in groupChat) { // // return GetGroupChatHistoryAsync.fromJson(jsonEncode(i)); // // } // } catch (e) { // //if fail api returning 500 hence just printing here // print(e); // throw e; // } // } // Future addGroupAndUsers(createGroup.CreateGroupRequest request) async { // try { // Response response = await ApiClient().postJsonForResponse( // ApiConsts.addGroupsAndUsers, // request, // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // return response.body; // } catch (e) { // //if fail api returning 500 hence just printing here // print(e); // throw e; // } // } // Future updateGroupAndUsers(createGroup.CreateGroupRequest request) async { // try { // Response response = await ApiClient().postJsonForResponse( // ApiConsts.updateGroupsAndUsers, // request, // token: AppState().chatDetails!.response!.token, // ); // if (!kReleaseMode) { // logger.i("res: " + response.body); // } // return response.body; // } catch (e) { // //if fail api returning 500 hence just printing here // print(e); // throw e; // } // } }