import 'dart:convert'; import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/extension/extention.dart'; import 'package:agrilink_vocpro/data/model/dht_graphic_response.dart'; import 'package:agrilink_vocpro/data/model/jwt_token_response.dart'; import 'package:agrilink_vocpro/data/model/login_response.dart'; import 'package:agrilink_vocpro/data/model/npk1_graphic_response.dart'; import 'package:agrilink_vocpro/data/model/npk2_graphic_response.dart'; import 'package:agrilink_vocpro/data/model/relay_response.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/data/model/switch_relay_response.dart'; import 'package:dio/dio.dart'; import 'package:jwt_decoder/jwt_decoder.dart'; import 'package:shared_preferences/shared_preferences.dart'; class AppService { final Dio _dioWithoutInterceptor = Dio( BaseOptions( baseUrl: AppConstant.baseUrl, connectTimeout: Duration(seconds: 5), receiveTimeout: Duration(seconds: 5), ), ); Future login({ required String username, required String password, String rememberMe = 'false', }) async { final SharedPreferences pref = await SharedPreferences.getInstance(); final String basicAuth = 'Basic ${base64Encode(utf8.encode('$username:$password'))}'; FormData formData = FormData.fromMap({ 'remember_me': rememberMe, }); try { final response = await _dioWithoutInterceptor.post( '/auth/login', data: formData, options: Options( headers: { 'Authorization': basicAuth, }, ), ); if (response.statusCode == 200) { final data = LoginResponse.fromJson(response.data); final decodedToken = JwtTokenResponse.fromJson(JwtDecoder.decode(data.data!.jwtToken!)); pref.setString('token', data.data!.token!); pref.setString('jwtToken', data.data!.jwtToken!); pref.setString('username', decodedToken.user?.username ?? 'unknown'); pref.setString('email', decodedToken.user?.email ?? 'unknown'); pref.setString('fullName', decodedToken.user?.fullname ?? 'unknown'); pref.setBool('isLoggedIn', true); return data; } else { throw Exception('Failed to load data'); } } on DioException catch (e) { final String errorMessage; if (e.response?.data != null) { errorMessage = e.response?.data['message'] ?? 'Something went wrong'; } else { errorMessage = 'Something went wrong'; } throw (errorMessage); } } // logout Future logout() async { final SharedPreferences pref = await SharedPreferences.getInstance(); final String auth = 'Bearer ${pref.getString('token')}'; try { final response = await _dioWithoutInterceptor.post( '/auth/logout', options: Options( headers: {'Authorization': auth}, ), ); if (response.statusCode == 200) { final data = LoginResponse.fromJson(response.data); pref.remove('token'); pref.remove('jwtToken'); pref.remove('username'); pref.remove('email'); pref.remove('fullName'); pref.setBool('isLoggedIn', false); return data; } else { throw Exception('Failed to load data'); } } on DioException catch (e) { final String errorMessage = e.response?.data['message']; throw (errorMessage); } } Future getRelayStatus() async { final SharedPreferences pref = await SharedPreferences.getInstance(); final String auth = 'Bearer ${pref.getString('token')}'; try { await Future.delayed(const Duration(seconds: 3)); final response = await _dioWithoutInterceptor.get( '/api/relay/get-relay', options: Options( headers: {'Authorization': auth}, ), ); if (response.statusCode == 200) { final data = RelayResponse.fromJson(response.data); return data; } else { throw Exception('Failed to load data'); } } on DioException catch (e) { final errorMessage = e.response?.data['message']; throw (errorMessage); } } // switch relay Future switchRelay( {required int relayNumber, required int state}) async { final SharedPreferences pref = await SharedPreferences.getInstance(); final String auth = 'Bearer ${pref.getString('token')}'; try { final response = await _dioWithoutInterceptor.post( '/api/relay/set-relay', data: { 'id': relayNumber, 'state': state, }, options: Options( headers: {'Authorization': auth}, ), ); if (response.statusCode == 200 || response.statusCode == 201) { final data = SwitchRelayResponse.fromJson(response.data); return data; } else { throw Exception('Failed to load data'); } } on DioException catch (e) { final errorMessage = e.response?.data['message']; throw (errorMessage); } } //get grafik data dht Future getGrafikDataDht({ required String metric, }) async { final SharedPreferences pref = await SharedPreferences.getInstance(); final String auth = 'Bearer ${pref.getString('token')}'; String date = DateTime.now().toString(); final formatedDate = dateFormatterShort(date); try { final result = await _dioWithoutInterceptor.get( '/api/sensor/getData?metric=$metric&range[start]=$formatedDate&range[end]=$formatedDate&range[time_range]=HOURLY&sensor=dht', options: Options( headers: {'Authorization': auth}, ), ); if (result.statusCode == 200) { final data = DhtGraphicResponse.fromJson(result.data); return data; } else { throw Exception('Failed to load data'); } } on DioException catch (e) { final errorMessage = e.response?.data['message']; throw (errorMessage); } } // get grafik data npk1 Future getGraphicDataNpk1( {required String metric}) async { final SharedPreferences pref = await SharedPreferences.getInstance(); final String auth = 'Bearer ${pref.getString('token')}'; String date = DateTime.now().toString(); final formatedDate = dateFormatterShort(date); try { final result = await _dioWithoutInterceptor.get( '/api/sensor/getData?metric=$metric&range[start]=$formatedDate&range[end]=$formatedDate&range[time_range]=HOURLY&sensor=npk1', options: Options( headers: {'Authorization': auth}, ), ); if (result.statusCode == 200) { final data = Npk1GraphicResponse.fromJson(result.data); return data; } else { throw Exception('Failed to load data'); } } on DioException catch (e) { final errorMessage = e.response?.data['message']; throw (errorMessage); } } // get grafik data npk2 Future getGraphicDataNpk2( {required String metric}) async { final SharedPreferences pref = await SharedPreferences.getInstance(); final String auth = 'Bearer ${pref.getString('token')}'; String date = DateTime.now().toString(); final formatedDate = dateFormatterShort(date); try { final result = await _dioWithoutInterceptor.get( '/api/sensor/getData?metric=$metric&range[start]=$formatedDate&range[end]=$formatedDate&range[time_range]=HOURLY&sensor=npk2', options: Options( headers: {'Authorization': auth}, ), ); if (result.statusCode == 200) { final data = Npk2GraphicResponse.fromJson(result.data); return data; } else { throw Exception('Failed to load data'); } } on DioException catch (e) { final errorMessage = e.response?.data['message']; throw (errorMessage); } } // get latest data Future getLatestData() async { final SharedPreferences pref = await SharedPreferences.getInstance(); final String auth = 'Bearer ${pref.getString('token')}'; try { final result = await _dioWithoutInterceptor.get( '/api/sensor/getLatest', options: Options( headers: {'Authorization': auth}, ), ); if (result.statusCode == 200) { final data = LatestDataResponse.fromJson(result.data); return data; } else { throw Exception('Failed to load data'); } } on DioException catch (e) { final errorMessage = e.response?.data['message']; throw (errorMessage); } } }