import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; import '../config/app_config.dart'; import '../models/user.dart'; class AuthService { // Singleton pattern static final AuthService _instance = AuthService._internal(); factory AuthService() => _instance; AuthService._internal(); String? _token; User? _currentUser; String? get token => _token; User? get currentUser => _currentUser; bool get isAuthenticated => _token != null; // Load token from local storage Future loadToken() async { final prefs = await SharedPreferences.getInstance(); _token = prefs.getString(AppConfig.tokenKey); final userJson = prefs.getString(AppConfig.userKey); if (userJson != null) { _currentUser = User.fromJson(jsonDecode(userJson)); } } // Save token to local storage Future _saveToken(String token, User user) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(AppConfig.tokenKey, token); await prefs.setString(AppConfig.userKey, jsonEncode(user.toJson())); _token = token; _currentUser = user; } // Clear token (logout) Future clearToken() async { final prefs = await SharedPreferences.getInstance(); await prefs.remove(AppConfig.tokenKey); await prefs.remove(AppConfig.userKey); _token = null; _currentUser = null; } // Register Future> register({ required String name, required String email, required String password, required String passwordConfirmation, String? phone, }) async { try { final response = await http.post( Uri.parse('${AppConfig.baseUrl}/register'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: jsonEncode({ 'name': name, 'email': email, 'password': password, 'password_confirmation': passwordConfirmation, 'phone': phone, }), ); final data = jsonDecode(response.body); if (response.statusCode == 201 && data['success'] == true) { final token = data['data']['token']; final user = User.fromJson(data['data']['user']); await _saveToken(token, user); return {'success': true, 'message': data['message']}; } else { return { 'success': false, 'message': data['message'] ?? 'Registrasi gagal', 'errors': data['errors'], }; } } catch (e) { return {'success': false, 'message': 'Error: $e'}; } } // Login Future> login({ required String email, required String password, }) async { try { final response = await http.post( Uri.parse('${AppConfig.baseUrl}/login'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: jsonEncode({'email': email, 'password': password}), ); final data = jsonDecode(response.body); if (response.statusCode == 200 && data['success'] == true) { final token = data['data']['token']; final user = User.fromJson(data['data']['user']); await _saveToken(token, user); return {'success': true, 'message': data['message']}; } else { return {'success': false, 'message': data['message'] ?? 'Login gagal'}; } } catch (e) { return {'success': false, 'message': 'Error: $e'}; } } // Logout Future> logout() async { try { if (_token == null) { await clearToken(); return {'success': true}; } final response = await http.post( Uri.parse('${AppConfig.baseUrl}/logout'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer $_token', }, ); await clearToken(); if (response.statusCode == 200) { return {'success': true, 'message': 'Logout berhasil'}; } else { return {'success': true}; // Still clear local token } } catch (e) { await clearToken(); // Clear local token anyway return {'success': true}; } } // Get current user Future getCurrentUser() async { if (_token == null) return null; try { final response = await http.get( Uri.parse('${AppConfig.baseUrl}/user'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { final user = User.fromJson(jsonDecode(response.body)); _currentUser = user; return user; } return null; } catch (e) { return null; } } // Update profile Future> updateProfile({ required String name, required String email, String? phone, }) async { try { final response = await http.put( Uri.parse('${AppConfig.baseUrl}/profile/update'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer $_token', }, body: jsonEncode({ 'name': name, 'email': email, 'phone': phone, }), ); final data = jsonDecode(response.body); if (response.statusCode == 200 && data['success'] == true) { final user = User.fromJson(data['data']); final prefs = await SharedPreferences.getInstance(); await prefs.setString(AppConfig.userKey, jsonEncode(user.toJson())); _currentUser = user; return {'success': true, 'message': data['message']}; } else { return { 'success': false, 'message': data['message'] ?? 'Gagal update profil', 'errors': data['errors'], }; } } catch (e) { return {'success': false, 'message': 'Error: $e'}; } } // Change password Future> changePassword({ required String password, required String passwordConfirmation, }) async { try { final response = await http.put( Uri.parse('${AppConfig.baseUrl}/profile/update'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer $_token', }, body: jsonEncode({ 'name': _currentUser?.name ?? '', 'email': _currentUser?.email ?? '', 'password': password, 'password_confirmation': passwordConfirmation, }), ); final data = jsonDecode(response.body); if (response.statusCode == 200 && data['success'] == true) { return {'success': true, 'message': 'Password berhasil diubah'}; } else { return { 'success': false, 'message': data['message'] ?? 'Gagal mengubah password', 'errors': data['errors'], }; } } catch (e) { return {'success': false, 'message': 'Error: $e'}; } } }