import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import '../models/cycle_entry.dart'; class SyncService { static const String _baseUrl = 'http://localhost:8090'; // Push data to backend Future pushSyncData(String userId, List entries) async { try { final url = Uri.parse('$_baseUrl/sync/push'); final payload = { 'userId': userId, 'entries': entries.map((e) => _cycleEntryToJson(e)).toList(), }; final response = await http.post( url, headers: {'Content-Type': 'application/json'}, body: jsonEncode(payload), ); if (response.statusCode == 200) { debugPrint('Sync Push Successful'); } else { debugPrint('Sync Push Failed: ${response.body}'); } } catch (e) { debugPrint('Sync Push Error: $e'); } } // Pull data from backend Future> pullSyncData(String userId) async { try { final url = Uri.parse('$_baseUrl/sync/pull?userId=$userId'); final response = await http.get(url); if (response.statusCode == 200) { final data = jsonDecode(response.body); final List entriesJson = data['entries'] ?? []; return entriesJson.map((json) => _jsonToCycleEntry(json)).toList(); } } catch (e) { debugPrint('Sync Pull Error: $e'); } return []; } // Helpers (Adapters) Map _cycleEntryToJson(CycleEntry entry) { // Convert boolean symptoms to list of strings final symptomsList = []; if (entry.hasHeadache) symptomsList.add('headache'); if (entry.hasBloating) symptomsList.add('bloating'); if (entry.hasBreastTenderness) symptomsList.add('breastTenderness'); if (entry.hasFatigue) symptomsList.add('fatigue'); if (entry.hasAcne) symptomsList.add('acne'); if (entry.hasLowerBackPain) symptomsList.add('lowerBackPain'); if (entry.hasConstipation) symptomsList.add('constipation'); if (entry.hasDiarrhea) symptomsList.add('diarrhea'); if (entry.hasInsomnia) symptomsList.add('insomnia'); return { 'id': entry.id, 'date': entry.date.toIso8601String(), 'flowIntensity': entry.flowIntensity?.name, 'isPeriodDay': entry.isPeriodDay, 'symptoms': jsonEncode(symptomsList), 'moods': jsonEncode(entry.mood != null ? [entry.mood!.name] : []), 'notes': entry.notes, 'createdAt': entry.createdAt.toIso8601String(), 'updatedAt': entry.updatedAt.toIso8601String(), }; } CycleEntry _jsonToCycleEntry(Map json) { // FlowIntensity enum parsing FlowIntensity? flow; if (json['flowIntensity'] != null) { flow = FlowIntensity.values.firstWhere( (e) => e.name == json['flowIntensity'], orElse: () => FlowIntensity.medium, ); } // Mood parsing MoodLevel? mood; final moodsList = _parseList(json['moods']); if (moodsList.isNotEmpty) { try { mood = MoodLevel.values.firstWhere((e) => e.name == moodsList.first); } catch (_) {} } final symptoms = _parseList(json['symptoms']); return CycleEntry( id: json['id'], date: DateTime.parse(json['date']), flowIntensity: flow, isPeriodDay: json['isPeriodDay'] == true, mood: mood, hasHeadache: symptoms.contains('headache'), hasBloating: symptoms.contains('bloating'), hasBreastTenderness: symptoms.contains('breastTenderness'), hasFatigue: symptoms.contains('fatigue'), hasAcne: symptoms.contains('acne'), hasLowerBackPain: symptoms.contains('lowerBackPain'), hasConstipation: symptoms.contains('constipation'), hasDiarrhea: symptoms.contains('diarrhea'), hasInsomnia: symptoms.contains('insomnia'), notes: json['notes'], createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt']) : DateTime.now(), updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : DateTime.now(), ); } List _parseList(dynamic jsonVal) { if (jsonVal == null) return []; if (jsonVal is String) { try { return List.from(jsonDecode(jsonVal)); } catch (_) { return []; } } return List.from(jsonVal); } }