import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:image_picker/image_picker.dart'; import 'package:marco/helpers/services/storage/local_storage.dart'; import 'package:intl/intl.dart'; class ApiService { static const String baseUrl = "https://stageapi.marcoaiot.com/api"; // ===== Common Helpers ===== static Future _getToken() async { final token = LocalStorage.getJwtToken(); if (token == null) { print("No JWT token found. Please log in."); } return token; } static Map _headers(String token) => { 'Content-Type': 'application/json', 'Authorization': 'Bearer $token', }; static Future _getRequest(String endpoint, {Map? queryParams}) async { final token = await _getToken(); if (token == null) return null; final uri = Uri.parse("$baseUrl$endpoint").replace(queryParameters: queryParams); print('GET request: $uri'); try { return await http.get(uri, headers: _headers(token)); } catch (e) { print("HTTP GET Exception: $e"); return null; } } static dynamic _parseResponse(http.Response response, {String label = ''}) { print("$label Response: ${response.body}"); if (response.statusCode == 200) { final json = jsonDecode(response.body); if (json['success'] == true) return json['data']; print("API Error: ${json['message']}"); } else { print("HTTP Error [$label]: ${response.statusCode}"); } return null; } // ===== API Calls ===== static Future?> getProjects() async { final response = await _getRequest("/project/list"); return response != null ? _parseResponse(response, label: 'Projects') : null; } static Future?> getEmployeesByProject(int projectId) async { final response = await _getRequest("/attendance/project/team", queryParams: {"projectId": "$projectId"}); return response != null ? _parseResponse(response, label: 'Employees') : null; } static Future?> getAttendanceLogs( int projectId, { DateTime? dateFrom, DateTime? dateTo, }) async { final query = { "projectId": "$projectId", if (dateFrom != null) "dateFrom": DateFormat('yyyy-MM-dd').format(dateFrom), if (dateTo != null) "dateTo": DateFormat('yyyy-MM-dd').format(dateTo), }; final response = await _getRequest("/attendance/project/team", queryParams: query); return response != null ? _parseResponse(response, label: 'Attendance Logs') : null; } static Future?> getAttendanceLogView(int id) async { final response = await _getRequest("/attendance/log/attendance/$id"); return response != null ? _parseResponse(response, label: 'Attendance Log Details') : null; } static Future?> getRegularizationLogs(int projectId) async { final response = await _getRequest("/attendance/regularize", queryParams: {"projectId": "$projectId"}); return response != null ? _parseResponse(response, label: 'Regularization') : null; } // ===== Upload Image ===== static Future uploadAttendanceImage( int id, int employeeId, XFile? imageFile, double latitude, double longitude, { required String imageName, required int projectId, String comment = "", required int action, bool imageCapture = true, // <- add this flag }) async { final token = await _getToken(); if (token == null) return false; try { Map? imageObject; if (imageCapture && imageFile != null) { final bytes = await imageFile.readAsBytes(); final base64Image = base64Encode(bytes); final fileSize = await imageFile.length(); final contentType = "image/${imageFile.path.split('.').last}"; imageObject = { "fileName": '$imageName', "contentType": '$contentType', "fileSize": fileSize, "description": "Employee attendance photo", "base64Data": '$base64Image', }; } final now = DateTime.now(); final body = { "id": id, "employeeId": employeeId, "projectId": projectId, "markTime": DateFormat('hh:mm a').format(now), "comment": comment, "action": action, "date": DateFormat('yyyy-MM-dd').format(now), }; // Only include latitude and longitude if imageCapture is true if (imageCapture) { body["latitude"] = '$latitude'; body["longitude"] = '$longitude'; } // Only add imageObject if it's not null if (imageObject != null) { body["image"] = imageObject; } print("Attendance Image Upload Body: $body"); final response = await http.post( Uri.parse("$baseUrl/attendance/record-image"), headers: _headers(token), body: jsonEncode(body), ); print("Attendance Image Upload Response: ${response.body}"); final json = jsonDecode(response.body); if (response.statusCode == 200 && json['success'] == true) { return true; } else { print("Failed to upload image. API Error: ${json['message']}"); } } catch (e) { print("Exception during image upload: $e"); } return false; } // ===== Utilities ===== static String generateImageName(int employeeId, int count) { final now = DateTime.now(); final dateStr = DateFormat('yyyyMMdd_HHmmss').format(now); final imageNumber = count.toString().padLeft(3, '0'); return "${employeeId}_${dateStr}_$imageNumber.jpg"; } }