import 'package:dio/dio.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import '../../config/env.dart'; final apiClientProvider = Provider((ref) { return ApiClient(); }); class ApiClient { late final Dio _dio; final _storage = const FlutterSecureStorage(); ApiClient() { _dio = Dio(BaseOptions( baseUrl: Env.apiBaseUrl, connectTimeout: const Duration(seconds: 10), receiveTimeout: const Duration(seconds: 30), headers: { 'Content-Type': 'application/json', }, )); _dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) async { // Add auth token if available final token = await _storage.read(key: 'session_token'); if (token != null) { options.headers['Authorization'] = 'Bearer $token'; } handler.next(options); }, onError: (error, handler) { if (error.response?.statusCode == 401) { // Handle unauthorized - clear token and redirect to login _storage.delete(key: 'session_token'); } handler.next(error); }, )); } // Auth Future> signUp({ required String email, required String password, required String name, }) async { final response = await _dio.post('/api/auth/sign-up/email', data: { 'email': email, 'password': password, 'name': name, }); return response.data; } Future> signIn({ required String email, required String password, }) async { final response = await _dio.post('/api/auth/sign-in/email', data: { 'email': email, 'password': password, }); // Store session token if (response.data['token'] != null) { await _storage.write(key: 'session_token', value: response.data['token']); } return response.data; } Future signOut() async { await _dio.post('/api/auth/sign-out'); await _storage.delete(key: 'session_token'); } Future?> getSession() async { try { final response = await _dio.get('/api/auth/session'); return response.data; } catch (_) { return null; } } // Clients Future>> getClients({String? search, String? tag}) async { final response = await _dio.get('/api/clients', queryParameters: { if (search != null) 'search': search, if (tag != null) 'tag': tag, }); return List>.from(response.data); } Future> getClient(String id) async { final response = await _dio.get('/api/clients/$id'); return response.data; } Future> createClient(Map data) async { final response = await _dio.post('/api/clients', data: data); return response.data; } Future> updateClient(String id, Map data) async { final response = await _dio.put('/api/clients/$id', data: data); return response.data; } Future deleteClient(String id) async { await _dio.delete('/api/clients/$id'); } Future markClientContacted(String id) async { await _dio.post('/api/clients/$id/contacted'); } // Emails Future> generateEmail({ required String clientId, required String purpose, String? provider, }) async { final response = await _dio.post('/api/emails/generate', data: { 'clientId': clientId, 'purpose': purpose, if (provider != null) 'provider': provider, }); return response.data; } Future>> getEmails({String? status, String? clientId}) async { final response = await _dio.get('/api/emails', queryParameters: { if (status != null) 'status': status, if (clientId != null) 'clientId': clientId, }); return List>.from(response.data); } Future> updateEmail(String id, Map data) async { final response = await _dio.put('/api/emails/$id', data: data); return response.data; } Future> sendEmail(String id) async { final response = await _dio.post('/api/emails/$id/send'); return response.data; } Future deleteEmail(String id) async { await _dio.delete('/api/emails/$id'); } // Events Future>> getEvents({ String? clientId, String? type, int? upcomingDays, }) async { final response = await _dio.get('/api/events', queryParameters: { if (clientId != null) 'clientId': clientId, if (type != null) 'type': type, if (upcomingDays != null) 'upcoming': upcomingDays.toString(), }); return List>.from(response.data); } Future> createEvent(Map data) async { final response = await _dio.post('/api/events', data: data); return response.data; } Future deleteEvent(String id) async { await _dio.delete('/api/events/$id'); } Future syncClientEvents(String clientId) async { await _dio.post('/api/events/sync/$clientId'); } }