import 'package:dio/dio.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:logger/logger.dart'; import 'package:real_estate_mobile/core/constants/api_constants.dart'; import 'package:real_estate_mobile/core/network/api_client.dart'; import 'package:real_estate_mobile/core/network/api_exceptions.dart'; import 'package:real_estate_mobile/features/messaging/data/models/messaging_models.dart'; final _log = Logger(printer: PrettyPrinter(methodCount: 0)); class MessagingRepository { final Dio _dio = ApiClient.instance.dio; /// GET /messages/conversations Future> getConversations() async { try { final response = await _dio.get(ApiConstants.conversations); final data = response.data['data'] as List; return data .map((e) => Conversation.fromJson(e as Map)) .toList(); } on DioException catch (e) { if (e.error is ApiException) throw e.error as ApiException; throw ApiException( message: e.message ?? 'Failed to fetch conversations', statusCode: e.response?.statusCode, ); } catch (e, stack) { _log.e('Conversation parsing error', error: e, stackTrace: stack); throw ApiException(message: 'Failed to parse conversations: $e'); } } /// POST /messages/conversations Future startConversation(String agentProfileId) async { try { final response = await _dio.post( ApiConstants.conversations, data: {'agentProfileId': agentProfileId}, ); return Conversation.fromJson( response.data['data'] as Map); } on DioException catch (e) { if (e.error is ApiException) throw e.error as ApiException; throw ApiException( message: e.message ?? 'Failed to start conversation', statusCode: e.response?.statusCode, ); } } /// GET /messages/conversations/:id Future getConversation(String id) async { try { final response = await _dio.get('${ApiConstants.conversations}/$id'); return Conversation.fromJson( response.data['data'] as Map); } on DioException catch (e) { if (e.error is ApiException) throw e.error as ApiException; throw ApiException( message: e.message ?? 'Failed to fetch conversation', statusCode: e.response?.statusCode, ); } } /// GET /messages/conversations/:id/messages?page=&limit= Future<({List messages, PaginationInfo pagination})> getMessages( String conversationId, { int page = 1, int limit = 50, }) async { try { final response = await _dio.get( '${ApiConstants.conversations}/$conversationId/messages', queryParameters: {'page': page, 'limit': limit}, ); final data = response.data['data'] as Map; final messages = (data['messages'] as List) .map((e) => ChatMessage.fromJson(e as Map)) .toList(); final pagination = PaginationInfo.fromJson( data['pagination'] as Map); return (messages: messages, pagination: pagination); } on DioException catch (e) { if (e.error is ApiException) throw e.error as ApiException; throw ApiException( message: e.message ?? 'Failed to fetch messages', statusCode: e.response?.statusCode, ); } } /// POST /messages/conversations/:id/messages Future sendMessage( String conversationId, { required String content, MessageType type = MessageType.text, }) async { try { final response = await _dio.post( '${ApiConstants.conversations}/$conversationId/messages', data: { 'content': content, 'messageType': type.toApiString(), }, ); return ChatMessage.fromJson( response.data['data'] as Map); } on DioException catch (e) { if (e.error is ApiException) throw e.error as ApiException; throw ApiException( message: e.message ?? 'Failed to send message', statusCode: e.response?.statusCode, ); } } /// PATCH /messages/conversations/:id/read Future markAsRead(String conversationId) async { try { await _dio.patch('${ApiConstants.conversations}/$conversationId/read'); } on DioException catch (e) { if (e.error is ApiException) throw e.error as ApiException; throw ApiException( message: e.message ?? 'Failed to mark as read', statusCode: e.response?.statusCode, ); } } /// GET /messages/unread-count Future getUnreadCount() async { try { final response = await _dio.get(ApiConstants.unreadCount); return response.data['data']['unreadCount'] as int? ?? 0; } on DioException catch (e) { if (e.error is ApiException) throw e.error as ApiException; throw ApiException( message: e.message ?? 'Failed to fetch unread count', statusCode: e.response?.statusCode, ); } } } final messagingRepositoryProvider = Provider((ref) { return MessagingRepository(); });