import 'dart:convert'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/category.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/monthly/monthly_model.dart'; import 'package:didvan/providers/core.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request_helper.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; class MonthlyListState extends CoreProvier { List monthlyItems = []; List _allMonthlyItems = []; String searchQuery = ''; String? startDate; String? endDate; final List selectedCats = []; List categories = []; bool filtering = false; void initCategories() { categories = [ CategoryData( id: 1, label: 'اقتصادی', asset: Assets.economicCategoryIcon, ), CategoryData( id: 2, label: 'سیاسی', asset: Assets.politicalCategoryIcon, ), CategoryData( id: 3, label: 'فناوری', asset: Assets.techCategoryIcon, ), CategoryData( id: 4, label: 'کسب و کار', asset: Assets.businessCategoryIcon, ), CategoryData( id: 5, label: 'زیست‌محیطی', asset: Assets.enviromentalCategoryIcon, ), CategoryData( id: 6, label: 'اجتماعی', asset: Assets.socialCategoryIcon, ), ]; } bool get searching => searchQuery.isNotEmpty; Future fetchMonthlyList() async { appState = AppState.busy; notifyListeners(); try { final url = '${RequestHelper.baseUrl}/monthly'; debugPrint('Fetching monthly list from: $url'); final response = await http.get( Uri.parse(url), headers: { 'Authorization': 'Bearer ${RequestService.token}', 'accept': '*/*', 'Content-Type': 'application/json; charset=UTF-8', }, ).timeout(const Duration(seconds: 30)); debugPrint('Response status code: ${response.statusCode}'); if (response.statusCode == 200) { final jsonData = json.decode(response.body); debugPrint('Decoded JSON: $jsonData'); final List resultList = jsonData['result'] as List; debugPrint('Found ${resultList.length} items'); _allMonthlyItems = resultList.map((item) => MonthlyItem.fromJson(item)).toList(); monthlyItems = _applyFilters(_allMonthlyItems); debugPrint( 'Successfully parsed ${monthlyItems.length} monthly items after filters'); appState = AppState.idle; } else { debugPrint('Request failed with status code: ${response.statusCode}'); appState = AppState.failed; } } catch (e, stackTrace) { debugPrint('Error fetching monthly list: $e'); debugPrint('Stack trace: $stackTrace'); appState = AppState.failed; } notifyListeners(); } void search(String query) { searchQuery = query; var filtered = _allMonthlyItems; if (query.isNotEmpty) { filtered = filtered .where((item) => item.title.toLowerCase().contains(query.toLowerCase()) || item.description.toLowerCase().contains(query.toLowerCase())) .toList(); } monthlyItems = _applyFilters(filtered); notifyListeners(); } Future toggleLike(int id) async { try { final url = '${RequestHelper.baseUrl}/monthly/$id/like'; debugPrint('Toggling like for monthly item: $url'); final index = monthlyItems.indexWhere((item) => item.id == id); if (index != -1) { monthlyItems[index].isLiked = !monthlyItems[index].isLiked; notifyListeners(); } final response = await http.post( Uri.parse(url), headers: { 'Authorization': 'Bearer ${RequestService.token}', 'accept': '*/*', 'Content-Type': 'application/json; charset=UTF-8', }, ).timeout(const Duration(seconds: 30)); if (response.statusCode == 200) { debugPrint('Like toggled successfully'); } else { debugPrint('Failed to toggle like: ${response.statusCode}'); if (index != -1) { monthlyItems[index].isLiked = !monthlyItems[index].isLiked; notifyListeners(); } } } catch (e) { debugPrint('Error toggling like: $e'); final index = monthlyItems.indexWhere((item) => item.id == id); if (index != -1) { monthlyItems[index].isLiked = !monthlyItems[index].isLiked; notifyListeners(); } } } Future toggleBookmark(int id) async { try { final url = '${RequestHelper.baseUrl}/monthly/$id/mark'; debugPrint('Toggling bookmark for monthly item: $url'); final index = monthlyItems.indexWhere((item) => item.id == id); if (index != -1) { monthlyItems[index].isBookmarked = !monthlyItems[index].isBookmarked; notifyListeners(); } final response = await http.post( Uri.parse(url), headers: { 'Authorization': 'Bearer ${RequestService.token}', 'accept': '*/*', 'Content-Type': 'application/json; charset=UTF-8', }, ).timeout(const Duration(seconds: 30)); if (response.statusCode == 200) { debugPrint('Bookmark toggled successfully'); } else { debugPrint('Failed to toggle bookmark: ${response.statusCode}'); if (index != -1) { monthlyItems[index].isBookmarked = !monthlyItems[index].isBookmarked; notifyListeners(); } } } catch (e) { debugPrint('Error toggling bookmark: $e'); final index = monthlyItems.indexWhere((item) => item.id == id); if (index != -1) { monthlyItems[index].isBookmarked = !monthlyItems[index].isBookmarked; notifyListeners(); } } } void resetFilters([bool notify = true]) { startDate = null; endDate = null; selectedCats.clear(); filtering = false; if (notify) { fetchMonthlyList(); } } List _applyFilters(List items) { var filtered = items; if (startDate != null || endDate != null) { filtered = filtered.where((item) { final itemDate = DateTime.parse(item.publishedAt); if (startDate != null) { final start = DateTime.parse(startDate!); if (itemDate.isBefore(start)) return false; } if (endDate != null) { final end = DateTime.parse(endDate!).add(const Duration(days: 1)); if (itemDate.isAfter(end)) return false; } return true; }).toList(); } if (selectedCats.isNotEmpty) { filtered = filtered.where((item) { return item.tags .any((tag) => selectedCats.any((cat) => cat.id == tag.id)); }).toList(); } return filtered; } }