import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:tm_app/data/repositories/tenders_repository.dart'; import 'package:tm_app/data/services/model/feedback_data/feedback_data.dart'; import 'package:tm_app/data/services/model/feedback_response/feedback_response.dart'; import 'package:tm_app/data/services/model/tenders/tenders_response/tenders_response.dart'; import '../core/utils/result.dart'; class TendersViewModel with ChangeNotifier { final TendersRepository _tendersRepository; TendersViewModel({required TendersRepository tendersRepository}) : _tendersRepository = tendersRepository { WidgetsBinding.instance.addPostFrameCallback((_) { getTenders(); }); } bool _isLoading = false; bool _isLoadingMore = false; String? _errorMessage; TendersResponse? _tendersResponse; FeedbackData? _feedbackData; bool get isLoading => _isLoading; bool get isLoadingMore => _isLoadingMore; String? get errorMessage => _errorMessage; TendersResponse? get tendersResponse => _tendersResponse; FeedbackData? get feedbackData => _feedbackData; List feedbacks = []; int currentPage = 1; int _currentOffset = 0; static const int _pageSize = 10; bool _hasMoreData = true; bool get hasMoreData => _hasMoreData; /// Get feedback for a specific tender FeedbackData? getFeedbackForTender(String tenderId) { try { return feedbacks.firstWhere((f) => f.tender == tenderId); } catch (e) { return null; } } /// Check if feedback exists for a specific tender bool hasFeedbackForTender(String tenderId) { return feedbacks.any((f) => f.tender == tenderId); } Future getTenders() async { _isLoading = true; _errorMessage = null; _currentOffset = 0; _hasMoreData = true; notifyListeners(); final result = await _tendersRepository.getTenders( limit: _pageSize, offset: _currentOffset, ); switch (result) { case Ok(): _tendersResponse = result.value; // Check if we have more data if (_tendersResponse?.data?.tenders != null) { _hasMoreData = _tendersResponse!.data!.tenders!.length >= _pageSize; } if (_tendersResponse?.data?.tenders?.isNotEmpty == true) { getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!); } break; case Error(): _errorMessage = result.error.toString(); break; } _isLoading = false; notifyListeners(); _errorMessage = null; notifyListeners(); } Future loadMoreTenders() async { if (_isLoadingMore || !_hasMoreData) return; _isLoadingMore = true; _errorMessage = null; notifyListeners(); _currentOffset += _pageSize; final result = await _tendersRepository.getTenders( limit: _pageSize, offset: _currentOffset, ); switch (result) { case Ok(): if (result.value.data?.tenders != null && result.value.data!.tenders!.isNotEmpty) { // Create a new modifiable list by combining existing and new tenders if (_tendersResponse?.data?.tenders != null) { final existingTenders = _tendersResponse!.data!.tenders!; final newTenders = result.value.data!.tenders!; final combinedTenders = [...existingTenders, ...newTenders]; // Create a new TendersData with the combined list _tendersResponse = _tendersResponse!.copyWith( data: _tendersResponse!.data!.copyWith(tenders: combinedTenders), ); } else { _tendersResponse = result.value; } // Check if we have more data _hasMoreData = result.value.data!.tenders!.length >= _pageSize; } else { _hasMoreData = false; } break; case Error(): _errorMessage = result.error.toString(); _currentOffset -= _pageSize; // Revert offset on error break; } _isLoadingMore = false; notifyListeners(); _errorMessage = null; notifyListeners(); } Future getTenderFeedback(String tenderId) async { // _isLoading = true; _errorMessage = null; notifyListeners(); final result = await _tendersRepository.getTenderFeedback( tenderId: tenderId, ); switch (result) { case Ok(): _feedbackData = result.value.data; // Add or update _feedbackData in feedbacks list by tender id if (_feedbackData != null) { final index = feedbacks.indexWhere( (f) => f.tender == _feedbackData!.tender, ); if (index != -1) { feedbacks[index] = _feedbackData!; log('Updated feedback for tender: ${_feedbackData!.tender}'); } else { feedbacks.add(_feedbackData!); log('Added new feedback for tender: ${_feedbackData!.tender}'); } log('Total feedbacks: ${feedbacks.length}'); } break; case Error(): _errorMessage = result.error.toString(); break; } // _isLoading = false; notifyListeners(); _errorMessage = null; notifyListeners(); } Future feedback({ required String tenderId, required String feedbackType, }) async { _errorMessage = null; notifyListeners(); final result = await _tendersRepository.feedback( tenderId: tenderId, feedbackType: feedbackType, ); switch (result) { case Ok(): _feedbackData = result.value.data; if (_feedbackData != null) { final index = feedbacks.indexWhere( (f) => f.tender == _feedbackData!.tender, ); if (index != -1) { feedbacks[index] = _feedbackData!; } else { feedbacks.add(_feedbackData!); } } break; case Error(): _errorMessage = result.error.toString(); break; } notifyListeners(); _errorMessage = null; notifyListeners(); } }