import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:generp/Models/crmModels/GetSegmentOnTeamResponse.dart'; import 'package:generp/Models/crmModels/GetSourceOnReferenceResponse.dart'; import 'package:generp/Models/crmModels/LeadListViewResponse.dart'; import 'package:generp/Models/crmModels/SubmitLeadListFilterResponse.dart'; import 'package:provider/provider.dart'; import '../../Models/crmModels/GetDistrictOnStateResponse.dart'; import '../../Models/crmModels/GetSubLocOnDistrictResponse.dart'; import '../../Models/crmModels/LeadListContactPopUpResponse.dart' show Contacts; import '../../services/api_calling.dart'; import '../HomeScreenNotifier.dart'; class Leadlistprovider extends ChangeNotifier { TextEditingController sLeadIDController = TextEditingController(); TextEditingController mobileNumberController = TextEditingController(); TextEditingController companyNameController = TextEditingController(); bool _isLoading = true; List _sourcesList = []; List _teamsList = []; List _statesList = []; List _employeesList = []; List _referencesList = []; List _segmentsList = []; List _districtsList = []; List _subLocationsList = []; List _contactsList = []; List _crmLeadList = []; List _leadStatusList = []; List _openStatusList = []; List _alphabetList = []; Sources? _selectedSources; Teams? _selectedTeams; States? _selectedStates; Employees? _selectedEmployees; References? _selectedReferences; Segments? _selectedSegments; Districts? _selectedDistricts; SubLocations? _selectedSubLocations; Contacts? _selectedContacts; String? _selectedLeadStatus; String? _selectedOpenStatus; String? _selectedAlphabet; String? _selectedSourceId; String? _selectedSourceValue; String? _selectedTeamId; String? _selectedTeamValue; String? _selectedStateId; String? _selectedStateValue; String? _selectedEmployeeId; String? _selectedEmployeeValue; String? _selectedReferenceId; String? _selectedReferenceValue; String? _selectedSegmentId; String? _selectedSegmentValue; String? _selectedDistrictId; String? _selectedDistrictValue; String? _selectedSubLocationId; String? _selectedSubLocationValue; String? _selectedContactId; String? _selectedContactValue; bool get isLoading => _isLoading; List get sourcesList => _sourcesList; List get teamsList => _teamsList; List get statesList => _statesList; List get employeesList => _employeesList; List get referencesList => _referencesList; List get segmentsList => _segmentsList; List get districtsList => _districtsList; List get subLocationsList => _subLocationsList; List get contactsList => _contactsList; List get crmLeadList => _crmLeadList; List get leadStatusList => _leadStatusList; List get alphabetList => _alphabetList; List get openStatusList => _openStatusList; Sources? get selectedSource => _selectedSources; Teams? get selectedTeam => _selectedTeams; States? get selectedStates => _selectedStates; Employees? get selectedEmployee => _selectedEmployees; References? get selectedReference => _selectedReferences; Segments? get selectedSegment => _selectedSegments; Districts? get selectedDistricts => _selectedDistricts; SubLocations? get selectedSubLocations => _selectedSubLocations; Contacts? get selectedContacts => _selectedContacts; String? get selectedLeadStatus => _selectedLeadStatus; String? get selectedOpenStatus => _selectedOpenStatus; String? get selectedSourceId => _selectedSourceId; String? get selectedSourceValue => _selectedSourceValue; String? get selectedTeamId => _selectedTeamId; String? get selectedTeamValue => _selectedTeamValue; String? get selectedStateId => _selectedStateId; String? get selectedStateValue => _selectedStateValue; String? get selectedEmployeeId => _selectedEmployeeId; String? get selectedEmployeeValue => _selectedEmployeeValue; String? get selectedReferenceId => _selectedReferenceId; String? get selectedReferenceValue => _selectedReferenceValue; String? get selectedSegmentId => _selectedSegmentId; String? get selectedSegmentValue => _selectedSegmentValue; String? get selectedDistrictId => _selectedDistrictId; String? get selectedDistrictValue => _selectedDistrictValue; String? get selectedSubLocationId => _selectedSubLocationId; String? get selectedSubLocationValue => _selectedSubLocationValue; String? get selectedContactId => _selectedContactId; String? get selectedContactValue => _selectedContactValue; String? get selectedAlphabet => _selectedAlphabet; set isLoading(bool value) { _isLoading = value; notifyListeners(); } set selectedAlphabet(String? value) { _selectedAlphabet = value; notifyListeners(); } set selectedSource(Sources? value) { _selectedSources = value; _selectedSourceId = value?.id; _selectedSourceValue = value?.name; // debug - helpful when debugging filter problems debugPrint( 'Setting selectedSource: id=$_selectedSourceId, name=$_selectedSourceValue', ); notifyListeners(); } set selectedTeam(Teams? value) { _selectedTeams = value; _selectedTeamId = value?.id; _selectedTeamValue = value?.name; notifyListeners(); } set selectedStates(States? value) { _selectedStates = value; _selectedStateId = value?.id; _selectedStateValue = value?.name; notifyListeners(); } set selectedEmployee(Employees? value) { _selectedEmployees = value; _selectedEmployeeId = value?.id; _selectedEmployeeValue = value?.name; notifyListeners(); } set selectedReference(References? value) { _selectedReferences = value; _selectedReferenceId = value?.id; _selectedReferenceValue = value?.name; notifyListeners(); } set selectedSegment(Segments? value) { _selectedSegments = value; _selectedSegmentId = value?.id; _selectedSegmentValue = value?.name; notifyListeners(); } set selectedDistricts(Districts? value) { _selectedDistricts = value; _selectedDistrictId = value?.id; _selectedDistrictValue = value?.district; notifyListeners(); } set selectedSubLocations(SubLocations? value) { _selectedSubLocations = value; _selectedSubLocationId = value?.id; _selectedSubLocationValue = value?.subLocality; notifyListeners(); } set selectedContacts(Contacts? value) { _selectedContacts = value; _selectedContactId = value?.id; _selectedContactValue = value?.name; notifyListeners(); } set selectedLeadStatus(String? value) { _selectedLeadStatus = value; notifyListeners(); } set selectedOpenStatus(String? value) { _selectedOpenStatus = value; notifyListeners(); } set selectedSourceId(String? value) { _selectedSourceId = value; notifyListeners(); } set selectedSourceValue(String? value) { _selectedSourceValue = value; notifyListeners(); } set selectedTeamId(String? value) { _selectedTeamId = value; notifyListeners(); } set selectedTeamValue(String? value) { _selectedTeamValue = value; notifyListeners(); } set selectedStateId(String? value) { _selectedStateId = value; notifyListeners(); } set selectedStateValue(String? value) { _selectedStateValue = value; notifyListeners(); } set selectedEmployeeId(String? value) { _selectedEmployeeId = value; notifyListeners(); } set selectedEmployeeValue(String? value) { _selectedEmployeeValue = value; notifyListeners(); } set selectedReferenceId(String? value) { _selectedReferenceId = value; notifyListeners(); } set selectedReferenceValue(String? value) { _selectedReferenceValue = value; notifyListeners(); } set selectedSegmentId(String? value) { _selectedSegmentId = value; notifyListeners(); } set selectedSegmentValue(String? value) { _selectedSegmentValue = value; notifyListeners(); } set selectedDistrictId(String? value) { _selectedDistrictId = value; notifyListeners(); } set selectedDistrictValue(String? value) { _selectedDistrictValue = value; notifyListeners(); } set selectedSubLocationId(String? value) { _selectedSubLocationId = value; notifyListeners(); } set selectedSubLocationValue(String? value) { _selectedSubLocationValue = value; notifyListeners(); } set selectedContactId(String? value) { _selectedContactId = value; notifyListeners(); } set selectedContactValue(String? value) { _selectedContactValue = value; notifyListeners(); } // ---------- fetches & rehydrate selection logic ---------- // view API that returns many filter lists Future crmLeadListViewAPIFunction(context, mode) async { try { var HomeProv = Provider.of(context, listen: false); final data = await ApiCalling.crmLeadListViewAPI( HomeProv.empId, HomeProv.session, mode, ); if (data != null) { debugPrint( 'crmLeadListViewAPI error: ${data.error}, sources length: ${data.sources?.length ?? 0}', ); if (data.error == "0") { _leadStatusList = [ "all", "Hot", "Warm", "Cold", "Order Gain", "Order Lost", ]; _alphabetList = List.generate( 26, (index) => String.fromCharCode(index + 65), ); _openStatusList = ["open", "Closed", "All"]; _sourcesList = data.sources ?.where((source) => source.id != null && source.name != null) .toList() ?? []; _teamsList = data.teams ?.where((team) => team.id != null && team.name != null) .toList() ?? []; _statesList = data.states ?.where((state) => state.id != null && state.name != null) .toList() ?? []; _employeesList = data.employees ?.where( (employee) => employee.id != null && employee.name != null, ) .toList() ?? []; // --- rehydrate previously selected items by matching IDs --- _rehydrateSelectionsAfterViewLoad(); checkDropDownValues(); // ensure loading flag set off _isLoading = false; notifyListeners(); } else { // clear lists on non-zero error to avoid stale options _sourcesList.clear(); _teamsList.clear(); _statesList.clear(); _employeesList.clear(); _isLoading = false; notifyListeners(); } } else { // null response -> clear lists _sourcesList.clear(); _teamsList.clear(); _statesList.clear(); _employeesList.clear(); _isLoading = false; notifyListeners(); } } catch (e, s) { debugPrint('crmLeadListViewAPI error: $e, stack: $s'); _sourcesList.clear(); _teamsList.clear(); _statesList.clear(); _employeesList.clear(); _isLoading = false; notifyListeners(); } } Future crmLeadListSourceOnReferenceAPIFunction( context, mode, String? sourceID, ) async { try { var prov = Provider.of(context, listen: false); final data = await ApiCalling.crmLeadListSourceOnReferenceAPI( prov.empId, prov.session, sourceID, ); if (data != null) { if (data.error == "0") { _referencesList = data.references ?.where((ref) => ref.id != null && ref.name != null) .toList() ?? []; // rehydrate selectedReference if id exists if (_selectedReferenceId != null) { final found = _referencesList.firstWhere( (r) => r.id == _selectedReferenceId, orElse: () => References(id: _selectedReferenceId, name: _selectedReferenceValue), ); // if found in list use that instance else leave existing selectedReference null/unchanged if (_referencesList.any((r) => r.id == _selectedReferenceId)) { _selectedReferences = found; } else { // if API returned different list, keep selectedReference null to avoid mismatch _selectedReferences = null; _selectedReferenceId = null; _selectedReferenceValue = null; } } notifyListeners(); } else { _referencesList.clear(); _selectedReferences = null; _selectedReferenceId = null; _selectedReferenceValue = null; notifyListeners(); } } else { _referencesList.clear(); _selectedReferences = null; _selectedReferenceId = null; _selectedReferenceValue = null; notifyListeners(); } } catch (e, s) { debugPrint('crmLeadListSourceOnReferenceAPI error: $e, stack: $s'); } } Future crmLeadListSegmentOnTeamAPIFunction( context, mode, String? teamID, ) async { try { var prov = Provider.of(context, listen: false); final data = await ApiCalling.crmLeadListSegmentOnTeamAPI( prov.empId, prov.session, teamID, ); if (data != null) { if (data.error == "0") { _segmentsList = data.segments ?.where( (segment) => segment.id != null && segment.name != null, ) .toList() ?? []; // rehydrate selectedSegment if id exists if (_selectedSegmentId != null) { final found = _segmentsList.firstWhere( (s) => s.id == _selectedSegmentId, orElse: () => Segments(id: _selectedSegmentId, name: _selectedSegmentValue), ); if (_segmentsList.any((s) => s.id == _selectedSegmentId)) { _selectedSegments = found; } else { _selectedSegments = null; _selectedSegmentId = null; _selectedSegmentValue = null; } } notifyListeners(); } else { _segmentsList.clear(); _selectedSegments = null; _selectedSegmentId = null; _selectedSegmentValue = null; notifyListeners(); } } else { _segmentsList.clear(); _selectedSegments = null; _selectedSegmentId = null; _selectedSegmentValue = null; notifyListeners(); } } catch (e, s) { debugPrint('crmLeadListSegmentOnTeamAPI error: $e, stack: $s'); } } Future crmLeadListDistrictsOnStateAPIFunction( context, mode, String? stateID, ) async { try { var prov = Provider.of(context, listen: false); final data = await ApiCalling.crmDistrictsOnStateAPI( prov.empId, prov.session, stateID, ); if (data != null) { if (data.error == "0") { _districtsList = data.districts ?.where( (district) => district.id != null && district.district != null, ) .toList() ?? []; // rehydrate selection if (_selectedDistrictId != null) { final found = _districtsList.firstWhere( (d) => d.id == _selectedDistrictId, orElse: () => Districts(id: _selectedDistrictId, district: _selectedDistrictValue), ); if (_districtsList.any((d) => d.id == _selectedDistrictId)) { _selectedDistricts = found; } else { _selectedDistricts = null; _selectedDistrictId = null; _selectedDistrictValue = null; } } notifyListeners(); } else { _districtsList.clear(); _selectedDistricts = null; _selectedDistrictId = null; _selectedDistrictValue = null; notifyListeners(); } } else { _districtsList.clear(); _selectedDistricts = null; _selectedDistrictId = null; _selectedDistrictValue = null; notifyListeners(); } } catch (e, s) { debugPrint('crmLeadListDistrictsOnStateAPI error: $e, stack: $s'); } } Future crmLeadListSubLocOnDistrictAPIFunction( context, mode, String? districtID, ) async { try { var prov = Provider.of(context, listen: false); final data = await ApiCalling.crmSubLocOnDistrictAPI( prov.empId, prov.session, districtID, ); if (data != null) { if (data.error == "0") { _subLocationsList = data.subLocations ?.where( (subLoc) => subLoc.id != null && subLoc.subLocality != null, ) .toList() ?? []; // rehydrate selection if (_selectedSubLocationId != null) { final found = _subLocationsList.firstWhere( (s) => s.id == _selectedSubLocationId, orElse: () => SubLocations(id: _selectedSubLocationId, subLocality: _selectedSubLocationValue), ); if (_subLocationsList.any((s) => s.id == _selectedSubLocationId)) { _selectedSubLocations = found; } else { _selectedSubLocations = null; _selectedSubLocationId = null; _selectedSubLocationValue = null; } } notifyListeners(); } else { _subLocationsList.clear(); _selectedSubLocations = null; _selectedSubLocationId = null; _selectedSubLocationValue = null; notifyListeners(); } } else { _subLocationsList.clear(); _selectedSubLocations = null; _selectedSubLocationId = null; _selectedSubLocationValue = null; notifyListeners(); } } catch (e, s) { debugPrint('crmLeadListSubLocOnDistrictAPI error: $e, stack: $s'); } } Future crmLeadListContactPopUpAPIFunction( context, mode, String? accountID, ) async { try { var prov = Provider.of(context, listen: false); final data = await ApiCalling.crmLeadListContactPopUpAPI( prov.empId, prov.session, accountID, ); if (data != null) { if (data.error == "0") { _contactsList = data.contacts ?.where( (contact) => contact.id != null && contact.name != null, ) .toList() ?? []; notifyListeners(); } else { _contactsList.clear(); notifyListeners(); } } else { _contactsList.clear(); notifyListeners(); } } catch (e, s) { debugPrint('crmLeadListContactPopUpAPI error: $e, stack: $s'); } } bool _isLoadingMore = false; bool get isLoadingMore => _isLoadingMore; bool _hasMoreData = true; bool get hasMoreData => _hasMoreData; int _currentPage = 1; String? _errorMessage; String? get errorMessage => _errorMessage; /// Reset pagination void resetPagination() { _currentPage = 1; _hasMoreData = true; _crmLeadList.clear(); notifyListeners(); } Future crmLeadListAPIFunction( BuildContext context, String? mode, String? leadStatus, String? openStatus, String? sourceID, String? referenceID, String? teamID, String? segmentID, String? alphabet, { bool append = false, }) async { try { var HomeProv = Provider.of(context, listen: false); if (!append) { _isLoading = true; _errorMessage = null; notifyListeners(); } else { _isLoadingMore = true; notifyListeners(); } final data = await ApiCalling.crmLeadListFilterSubmitAPI( HomeProv.empId, HomeProv.session, mode, leadStatus, openStatus, mobileNumberController.text, companyNameController.text, sourceID, referenceID, teamID, segmentID, alphabet, _currentPage.toString(), // ); debugPrint( 'empId: ${HomeProv.empId}, session: ${HomeProv.session}, pageNumber: $_currentPage', ); if (data != null) { if (data.error == "0") { debugPrint("Lead List Length ${data.leadList?.length ?? 0}"); if (append) { _crmLeadList.addAll(data.leadList ?? []); } else { _crmLeadList = data.leadList ?? []; } if ((data.leadList?.length ?? 0) < 15) { _hasMoreData = false; // no more pages } } else if (data.error == "1") { if (!append) _errorMessage = "No leads found!"; _hasMoreData = false; } } else { _hasMoreData = false; } } catch (e) { _errorMessage = "Error: $e"; } _isLoading = false; _isLoadingMore = false; notifyListeners(); } /// Load next page Future loadMore( BuildContext context, String? mode, String? leadStatus, String? openStatus, String? sourceID, String? referenceID, String? teamID, String? segmentID, String? alphabet, ) async { if (_isLoadingMore || !_hasMoreData) return; _currentPage++; await crmLeadListAPIFunction( context, mode, leadStatus, openStatus, sourceID, referenceID, teamID, segmentID, alphabet, append: true, ); } onChangedLeadId(String? value) { notifyListeners(); } onChangedMobileNum(String? value) { notifyListeners(); } onChangedCompanyName(String? value) { notifyListeners(); } void resetForm() { _isLoading = false; sLeadIDController.clear(); mobileNumberController.clear(); companyNameController.clear(); _selectedEmployees = null; _selectedSources = null; _selectedReferences = null; _selectedSegments = null; _selectedTeams = null; _selectedDistricts = null; _selectedStates = null; _selectedSubLocations = null; _selectedLeadStatus = null; _selectedOpenStatus = null; _selectedAlphabet = null; _selectedEmployeeId = null; _selectedSourceId = null; _selectedReferenceId = null; _selectedTeamId = null; _selectedSegmentId = null; _selectedStateId = null; _selectedDistrictId = null; _selectedSubLocationId = null; _selectedEmployeeValue = null; _selectedSourceValue = null; _selectedReferenceValue = null; _selectedTeamValue = null; _selectedSegmentValue = null; _selectedDistrictValue = null; _selectedStateValue = null; _selectedSubLocationValue = null; checkDropDownValues(); notifyListeners(); } void checkDropDownValues() { if (_selectedEmployees != null && !_employeesList.contains(_selectedEmployees)) { _selectedEmployees = null; _selectedEmployeeId = null; _selectedEmployeeValue = null; } if (_selectedSources != null && !_sourcesList.contains(_selectedSources)) { _selectedSources = null; _selectedSourceId = null; _selectedSourceValue = null; } if (_selectedReferences != null && !_referencesList.contains(_selectedReferences)) { _selectedReferences = null; _selectedReferenceId = null; _selectedReferenceValue = null; } if (_selectedSegments != null && !_segmentsList.contains(_selectedSegments)) { _selectedSegments = null; _selectedSegmentId = null; _selectedSegmentValue = null; } if (_selectedTeams != null && !_teamsList.contains(_selectedTeams)) { _selectedTeams = null; _selectedTeamId = null; _selectedTeamValue = null; } if (_selectedDistricts != null && !_districtsList.contains(_selectedDistricts)) { _selectedDistricts = null; _selectedDistrictId = null; _selectedDistrictValue = null; } if (_selectedStates != null && !_statesList.contains(_selectedStates)) { _selectedStates = null; _selectedStateId = null; _selectedStateValue = null; } if (_selectedSubLocations != null && !_subLocationsList.contains(_selectedSubLocations)) { _selectedSubLocations = null; _selectedSubLocationId = null; _selectedSubLocationValue = null; } notifyListeners(); } // --- helper to rehydrate selected instances by their IDs after lists are loaded --- // --- helper to rehydrate selected instances by their IDs after lists are loaded --- void _rehydrateSelectionsAfterViewLoad() { // sources if (_selectedSourceId != null) { final idx = _sourcesList.indexWhere((s) => s.id == _selectedSourceId); if (idx != -1) { _selectedSources = _sourcesList[idx]; } else { _selectedSources = null; _selectedSourceId = null; _selectedSourceValue = null; } } // teams if (_selectedTeamId != null) { final idx = _teamsList.indexWhere((t) => t.id == _selectedTeamId); if (idx != -1) { _selectedTeams = _teamsList[idx]; } else { _selectedTeams = null; _selectedTeamId = null; _selectedTeamValue = null; } } // employees if (_selectedEmployeeId != null) { final idx = _employeesList.indexWhere((e) => e.id == _selectedEmployeeId); if (idx != -1) { _selectedEmployees = _employeesList[idx]; } else { _selectedEmployees = null; _selectedEmployeeId = null; _selectedEmployeeValue = null; } } // states if (_selectedStateId != null) { final idx = _statesList.indexWhere((st) => st.id == _selectedStateId); if (idx != -1) { _selectedStates = _statesList[idx]; } else { _selectedStates = null; _selectedStateId = null; _selectedStateValue = null; } } // note: I only handled the lists you used earlier; if you need to rehydrate // other selections (district/segment/subLocation/reference etc.) add same pattern. } }