import 'dart:convert'; import 'package:http/http.dart' as http; import '../utils/constants.dart'; import '../models/user.dart'; import '../models/allarme.dart'; import '../models/sito.dart'; import '../models/statistiche.dart'; class ApiService { static final ApiService _instance = ApiService._internal(); factory ApiService() => _instance; ApiService._internal(); String? _authToken; void setAuthToken(String token) => _authToken = token; void clearAuthToken() => _authToken = null; Map _getHeaders({bool includeAuth = true}) { final headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', }; if (includeAuth && _authToken != null) { headers['Authorization'] = 'Bearer $_authToken'; } return headers; } Future> _handleResponse(http.Response response) async { if (response.statusCode >= 200 && response.statusCode < 300) { return json.decode(utf8.decode(response.bodyBytes)); } else { final error = json.decode(utf8.decode(response.bodyBytes)); throw Exception(error['detail'] ?? 'Errore sconosciuto'); } } Future> login(String email, String password) async { final response = await http.post( Uri.parse('${AppConstants.apiBaseUrl}/auth/login'), headers: _getHeaders(includeAuth: false), body: json.encode({'email': email, 'password': password}), ); return _handleResponse(response); } Future getCurrentUser() async { final response = await http.get( Uri.parse('${AppConstants.apiBaseUrl}/auth/me'), headers: _getHeaders(), ); final data = await _handleResponse(response); return User.fromJson(data); } Future registerFcmToken(String fcmToken) async { final response = await http.post( Uri.parse('${AppConstants.apiBaseUrl}/auth/register-fcm-token'), headers: _getHeaders(), body: json.encode({'fcm_token': fcmToken}), ); await _handleResponse(response); } Future getAllarmi({ int page = 1, int pageSize = 20, String? severita, String? stato, }) async { final queryParams = { 'page': page.toString(), 'page_size': pageSize.toString(), if (severita != null) 'severita': severita, if (stato != null) 'stato': stato, }; final uri = Uri.parse('${AppConstants.apiBaseUrl}/allarmi') .replace(queryParameters: queryParams); final response = await http.get(uri, headers: _getHeaders()); final data = await _handleResponse(response); return AllarmeListResponse.fromJson(data); } Future getAllarme(int id) async { final response = await http.get( Uri.parse('${AppConstants.apiBaseUrl}/allarmi/$id'), headers: _getHeaders(), ); final data = await _handleResponse(response); return Allarme.fromJson(data); } Future updateAllarme(int id, {String? stato}) async { final body = {}; if (stato != null) body['stato'] = stato; final response = await http.patch( Uri.parse('${AppConstants.apiBaseUrl}/allarmi/$id'), headers: _getHeaders(), body: json.encode(body), ); final data = await _handleResponse(response); return Allarme.fromJson(data); } Future getSito(int sitoId) async { final response = await http.get( Uri.parse('${AppConstants.apiBaseUrl}/siti/$sitoId'), headers: _getHeaders(), ); final data = await _handleResponse(response); return Sito.fromJson(data); } Future> getSiti({String? tipo}) async { final queryParams = {}; if (tipo != null) queryParams['tipo'] = tipo; final uri = Uri.parse('${AppConstants.apiBaseUrl}/siti') .replace(queryParameters: queryParams.isNotEmpty ? queryParams : null); final response = await http.get(uri, headers: _getHeaders()); final data = await _handleResponse(response); final items = (data['items'] as List) .map((item) => Sito.fromJson(item as Map)) .toList(); return items; } Future getAllarmiBySito(int sitoId, {int page = 1, int pageSize = 20}) async { final queryParams = { 'page': page.toString(), 'page_size': pageSize.toString(), }; final uri = Uri.parse('${AppConstants.apiBaseUrl}/allarmi/sito/$sitoId') .replace(queryParameters: queryParams); final response = await http.get(uri, headers: _getHeaders()); final data = await _handleResponse(response); return AllarmeListResponse.fromJson(data); } Future getStatistiche() async { final response = await http.get( Uri.parse('${AppConstants.apiBaseUrl}/statistiche'), headers: _getHeaders(), ); final data = await _handleResponse(response); return Statistiche.fromJson(data); } Future getAllarmiPerGiorno({int giorni = 30}) async { final uri = Uri.parse('${AppConstants.apiBaseUrl}/statistiche/allarmi-per-giorno') .replace(queryParameters: {'giorni': giorni.toString()}); final response = await http.get(uri, headers: _getHeaders()); final data = await _handleResponse(response); return AllarmiPerGiornoResponse.fromJson(data); } }