import 'package:flutter/material.dart'; import 'package:tm_app/core/utils/result.dart'; import 'package:tm_app/data/services/model/feedback_stats/feedback_stats.dart'; import 'package:tm_app/data/services/model/recommended_tenders_response/recommended_tenders_response.dart'; import 'package:tm_app/data/services/model/tender_approvals_response/tender_approvals_response.dart'; import 'package:tm_app/data/services/model/tender_approvals_stats_response/tender_approvals_stats_response.dart'; import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import '../data/repositories/home_repository.dart'; import '../data/services/model/feedback_stats_response/feedback_stat_response.dart'; import '../data/services/model/home/home_response/home_response_model.dart'; import '../data/services/model/request_models/get_tenders_request_model/get_tenders_request_model.dart'; class HomeViewModel with ChangeNotifier { final HomeRepository _homeRepository; HomeViewModel({required HomeRepository homeRepository}) : _homeRepository = homeRepository { init(); } bool _isLoading = false; String? _errorMessage; HomeResponseModel? _homeResponse; TenderApprovalsResponse? data; bool get isLoading => _isLoading; String? get errorMessage => _errorMessage; HomeResponseModel? get homeResponse => _homeResponse; RecommendedTendersResponse? _recommendedTendersResponse; TenderApprovalsStatsResponse? tenderApprovalsStateResponse; FeedbackStats? feedbackStats; final List _tenders = []; final int _pageSize = 10; int _currentPage = 0; bool _isLoadingMore = false; bool _hasMore = true; bool _isRecommendedMode = false; List get tenders => _tenders; bool get isLoadingMore => _isLoadingMore; bool get hasMore => _hasMore; bool get isRecommendedMode => _isRecommendedMode; bool _hasUnreadNotification = false; bool get hasUnreadNotification => _hasUnreadNotification; void init() async { _isLoading = true; notifyListeners(); await getApprovedStates(); await getYourTenders(reset: true); await getFeedbackStats(); await checkUnreadNotifications(); if (_errorMessage != null) { _isLoading = false; notifyListeners(); return; } _isLoading = false; notifyListeners(); } Future getHomeRecommendTenders({bool reset = false}) async { if (_isLoadingMore || (!_hasMore && !reset)) { return; } if (reset) { _currentPage = 0; _hasMore = true; _tenders.clear(); } _isLoadingMore = true; _errorMessage = null; _isRecommendedMode = true; notifyListeners(); final result = await _homeRepository.getHomeRecommendedTenders( limit: _pageSize, offset: _currentPage * _pageSize, ); switch (result) { case Ok(): _recommendedTendersResponse = result.value; if (_recommendedTendersResponse?.data?.tenders.isNotEmpty ?? false) { _tenders.addAll( _recommendedTendersResponse!.data!.tenders.whereType(), ); _currentPage++; } else { _hasMore = false; } break; case Error(): _errorMessage = result.error.toString(); break; } _isLoadingMore = false; notifyListeners(); } Future getYourTenders({bool reset = false}) async { if (_isLoadingMore || (!_hasMore && !reset)) { return; } if (reset) { _currentPage = 0; _hasMore = true; _tenders.clear(); } _isLoadingMore = true; _isRecommendedMode = false; notifyListeners(); final requestModel = GetTendersRequestModel( limit: _pageSize, offset: _currentPage * _pageSize, ); final result = await _homeRepository.getYourTenders( requestModel: requestModel, ); switch (result) { case Ok(): data = result.value; final tendersList = data?.data?.tenders ?? []; final metadata = data?.data?.metadata; if (tendersList.isNotEmpty) { _tenders.addAll( tendersList.map((e) => e.tender).whereType(), ); _currentPage++; if (metadata != null && (_currentPage >= metadata.pages!)) { _hasMore = false; } } else { _hasMore = false; _isLoadingMore = false; getHomeRecommendTenders(reset: true); } break; case Error(): _errorMessage = result.error.toString(); break; } _isLoadingMore = false; notifyListeners(); } Future getApprovedStates() async { final result = await _homeRepository.getTendersApprovalsStats(); switch (result) { case Ok(): tenderApprovalsStateResponse = result.value; break; case Error(): _errorMessage = result.error.toString(); break; } notifyListeners(); } Future getFeedbackStats() async { final result = await _homeRepository.getFeedbackStats(); switch (result) { case Ok(): feedbackStats = result.value.data; break; case Error(): _errorMessage = result.error.toString(); break; } notifyListeners(); } double get partnershipCount { return tenderApprovalsStateResponse?.data?.partnershipCount?.toDouble() ?? 0.0; } double get selfApplyCount { return tenderApprovalsStateResponse?.data?.selfApplyCount?.toDouble() ?? 0.0; } double get totalCount { return partnershipCount + selfApplyCount; } double get partnershipPercent { return totalCount > 0 ? (partnershipCount / totalCount) * 100 : 0; } double get selfApplyPercent { return totalCount > 0 ? (selfApplyCount / totalCount) * 100 : 0; } Future checkUnreadNotifications() async { final result = await _homeRepository.checkUnreadNotifications(); switch (result) { case Ok>(): final response = result.value; final data = response['data']; if (data is List && data.isNotEmpty) { _hasUnreadNotification = true; } else { _hasUnreadNotification = false; } break; case Error>(): _hasUnreadNotification = false; break; } notifyListeners(); } void setUnreadNotificationFalse() { _hasUnreadNotification = false; notifyListeners(); } }