import 'package:flutter/material.dart'; import 'package:tm_app/core/utils/result.dart'; import 'package:tm_app/data/repositories/liked_tenders_repository.dart'; import 'package:tm_app/data/repositories/tenders_repository.dart'; import 'package:tm_app/data/services/model/liked_tender_feedback/liked_tender_feedback.dart'; import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart'; import '../data/services/model/feedback_response/feedback_response.dart'; import '../data/services/model/tender_approvals_by_id_response/tender_approvals_by_id_response.dart'; import '../data/services/model/tender_approvals_data/tender_approvals_data.dart'; class LikedTendersViewModel with ChangeNotifier { final LikedTendersRepository _likedTendersRepository; final TendersRepository _tendersRepository; LikedTendersViewModel({ required LikedTendersRepository likedTendersRepository, required TendersRepository tendersRepository, }) : _likedTendersRepository = likedTendersRepository, _tendersRepository = tendersRepository; bool isLoading = false; bool isLoadingMore = false; bool hasMore = true; String? errorMessage; LikedTendersResponse? data; TenderApprovalsData? _tenderApprovalData; TenderApprovalsData? get tenderApprovalData => _tenderApprovalData; List tenderApprovals = []; int _offset = 0; final int _limit = 7; int currentPage = 1; Future getLikedTenders({bool reset = false}) async { if (!reset && (isLoadingMore || !hasMore)) { return; } if (reset) { _offset = (currentPage - 1) * _limit; hasMore = true; data = null; isLoading = true; notifyListeners(); } else { if (_offset == 0) { isLoading = true; } else { isLoadingMore = true; } notifyListeners(); } errorMessage = null; final result = await _likedTendersRepository.getLikedTenders( offset: _offset, limit: _limit, ); switch (result) { case Ok(): final incoming = result.value; final incomingList = incoming.data?.feedback ?? []; for (var element in incomingList) { await getTenderApproval(element.tenderId!); } if (reset) { data = incoming; } else { final existingList = data?.data?.feedback ?? []; final combined = List.of(existingList) ..addAll(incomingList); data = data?.copyWith( data: data?.data?.copyWith( feedback: combined, meta: incoming.data?.meta ?? data!.data!.meta, ), ); } hasMore = incomingList.length == _limit; _offset += _limit; errorMessage = null; break; case Error(): errorMessage = result.error.toString(); break; } isLoading = false; isLoadingMore = false; notifyListeners(); } Future loadMoreIfNeeded() async { if (isLoadingMore || !hasMore) { return; } await getLikedTenders(reset: false); } Future jumpToPage(int page) async { currentPage = page; _offset = (page - 1) * _limit; hasMore = true; await getLikedTenders(reset: true); } void removeTenderById(String id) async { final current = data; final list = current?.data?.feedback; if (current == null || list == null) { return; } // Store original list to restore if error occurs final originalList = List.of(list); final updatedList = List.of(list) ..removeWhere((e) => e.tenderId == id); // Temporarily update UI data = current.copyWith( data: current.data?.copyWith(feedback: updatedList), ); notifyListeners(); final result = await _tendersRepository.toggleFeedback( tenderId: id, feedbackType: 'like', ); switch (result) { case Ok(): final updatedMeta = current.data?.meta?.copyWith( total: updatedList.length, ); data = current.copyWith( data: current.data?.copyWith( feedback: updatedList, meta: updatedMeta, ), ); break; case Error(): // Restore original list if error occurs data = current.copyWith( data: current.data?.copyWith(feedback: originalList), ); errorMessage = result.error.toString(); break; } notifyListeners(); } Future getTenderApproval(String tenderId) async { errorMessage = null; notifyListeners(); final result = await _tendersRepository.getTenderApprovals( tenderId: tenderId, ); switch (result) { case Ok(): _tenderApprovalData = result.value.data; tenderApprovals.add(_tenderApprovalData!); break; case Error(): errorMessage = result.error.toString(); break; } notifyListeners(); errorMessage = null; notifyListeners(); } TenderApprovalsData? getApprovalStatusForTender(String tenderId) { try { return tenderApprovals.firstWhere((a) => a.tenderId == tenderId); } catch (e) { return null; } } /// Check if tender approval exists for a specific tender bool hasTenderApprovalForTender(String tenderId) { return tenderApprovals.any((a) => a.tenderId == tenderId); } // Future submitTenderApproval({ // required String tenderId, // required String submissionMode, // }) async { // errorMessage = null; // notifyListeners(); // final result = await _tendersRepository.toggleApprovals( // tenderId: tenderId, // status: 'submitted', // submissionMode: submissionMode, // ); // switch (result) { // case Ok(): // approvalStatus = true; // _status = result.value.data?.status ?? ''; // break; // case Error(): // _errorMessage = result.error.toString(); // approvalStatus = false; // break; // } // _isSubmitApprovalLoading = false; // notifyListeners(); // _errorMessage = null; // approvalStatus = false; // notifyListeners(); // } // Future rejectTenderApproval({ // required String tenderId, // required String submissionMode, // }) async { // _isRejectApprovalLoading = true; // _errorMessage = null; // notifyListeners(); // final result = await _tendersRepository.toggleApprovals( // tenderId: tenderId, // status: 'rejected', // submissionMode: submissionMode, // ); // switch (result) { // case Ok(): // approvalStatus = true; // _status = result.value.data?.status ?? ''; // break; // case Error(): // _errorMessage = result.error.toString(); // approvalStatus = false; // break; // } // _isRejectApprovalLoading = false; // notifyListeners(); // _errorMessage = null; // approvalStatus = false; // notifyListeners(); // } }