import 'package:flutter/material.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/modules/site_request_module/models/dropdown_models.dart'; import 'package:test_sa/modules/site_request_module/models/request_type_model.dart'; import 'package:test_sa/modules/site_request_module/models/site_request_model.dart'; import 'package:test_sa/models/lookup.dart'; import 'dart:convert'; import 'package:http/http.dart'; class SiteRequestProvider extends ChangeNotifier { bool _loading = false; bool get loading => _loading; set loading(bool value) { _loading = value; notifyListeners(); } String? _errorMessage; String? get errorMessage => _errorMessage; int? stateCode; // Get current user from UserProvider String getCurrentUserEmployeeId(UserProvider userProvider) { return userProvider.user?.employeeId ?? ''; } String getCurrentUserFullName(UserProvider userProvider) { return userProvider.user?.username ?? ''; } String getCurrentUserEmail(UserProvider userProvider) { return userProvider.user?.email ?? ''; } String getCurrentUserMobile(UserProvider userProvider) { return userProvider.user?.phoneNumber ?? ''; } String getCurrentUserExtension(UserProvider userProvider) { return userProvider.user?.extensionNo ?? ''; } String getCurrentUserRole(UserProvider userProvider) { // Get the first role if available if (userProvider.user?.userRoles != null && userProvider.user!.userRoles!.isNotEmpty) { return userProvider.user!.userRoles!.first.name ?? ''; } return ''; } List getCurrentUserAssignedSites(UserProvider userProvider) { // You can modify this based on how assigned sites are stored in your User model // For now, returning empty list as it's not clear from the User model // You may need to fetch this from another source or API return []; } // Request types from API List _requestTypes = []; List get requestTypes => _requestTypes; // Fetch request types from API (Step 1) Future fetchRequestTypes() async { if (_loading) return -2; _loading = true; _errorMessage = null; notifyListeners(); late Response response; try { response = await ApiManager.instance.get( URLs.getSiteRequestTypes, enableToastMessage: false, ); } catch (error) { _loading = false; stateCode = -1; _errorMessage = 'Failed to fetch request types'; notifyListeners(); return -1; } stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { try { var responseData = json.decode(response.body); List listJson = responseData['data'] ?? responseData; _requestTypes = listJson .map((item) => Lookup.fromJson(item)) .map((lookup) => RequestTypeModel( id: lookup.id?.toString() ?? lookup.value?.toString() ?? '', name: lookup.name ?? '', value: lookup.value, )) .toList(); } catch (e) { _errorMessage = 'Failed to parse request types: $e'; _loading = false; notifyListeners(); return -1; } } else { _errorMessage = 'Failed to fetch request types'; } _loading = false; notifyListeners(); return response.statusCode; } // Mock sites as Base models List _allSites = []; List get allSites => _allSites; // Fetch sites from API (Step 2) Future fetchSites() async { if (_loading) return -2; _loading = true; _errorMessage = null; notifyListeners(); late Response response; try { response = await ApiManager.instance.get( URLs.signUpGetSiteList, enableToastMessage: false, ); } catch (error) { _loading = false; stateCode = -1; _errorMessage = 'Failed to fetch sites'; notifyListeners(); return -1; } stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { try { var responseData = json.decode(response.body); List listJson = responseData is List ? responseData : responseData['data'] ?? []; _allSites = listJson .map((item) => SiteRequestSiteModel( id: item['id']?.toString() ?? '', name: item['name']?.toString() ?? '', )) .toList(); } catch (e) { _errorMessage = 'Failed to parse sites'; _loading = false; notifyListeners(); return -1; } } else { _errorMessage = 'Failed to fetch sites'; } _loading = false; notifyListeners(); return response.statusCode; } // Mock departments as Base models List _allDepartments = []; List get allDepartments => _allDepartments; // Fetch departments from API (Step 3) Future fetchDepartments() async { if (_loading) return -2; _loading = true; _errorMessage = null; notifyListeners(); late Response response; try { response = await ApiManager.instance.get( URLs.signUpGetDepartmentAutoComplete, enableToastMessage: false, ); } catch (error) { _loading = false; stateCode = -1; _errorMessage = 'Failed to fetch departments'; notifyListeners(); return -1; } stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { try { var responseData = json.decode(response.body); List listJson = responseData is List ? responseData : responseData['data'] ?? []; _allDepartments = listJson .map((item) => SiteRequestDepartmentModel( id: item['id']?.toString() ?? '', name: item['name']?.toString() ?? '', )) .toList(); } catch (e) { _errorMessage = 'Failed to parse departments'; _loading = false; notifyListeners(); return -1; } } else { _errorMessage = 'Failed to fetch departments'; } _loading = false; notifyListeners(); return response.statusCode; } // History of submitted requests final List _requestHistory = []; List get requestHistory => _requestHistory; // Get available sites based on request type List getAvailableSites(String requestType, List assignedSites) { if (requestType == 'Remove Site') { // Only return currently assigned sites return _allSites.where((site) { return assignedSites.contains(site.name ?? ''); }).toList(); } // For Add Site and Change Site, return all sites return _allSites; } // Check if user has assigned sites for removal bool hasAssignedSites(List assignedSites) { return assignedSites.isNotEmpty; } // Submit site request (local only, no API) Future submitSiteRequest(SiteRequestModel request, UserProvider userProvider) async { loading = true; _errorMessage = null; notifyListeners(); late Response response; try { // Prepare site IDs array with correct structure final siteIdsArray = request.siteIds.asMap().entries.map((entry) { return { "id": 0, "siteId": int.tryParse(request.siteIds[entry.key]) ?? 0, "siteName": request.siteNames[entry.key], "oldSiteId": 0, "oldSitName": "" }; }).toList(); // Prepare department IDs array with correct structure final departmentIdsArray = (request.departmentIds != null && request.departmentIds!.isNotEmpty) ? request.departmentIds!.asMap().entries.map((entry) { return { "id": 0, "departmentId": int.tryParse(request.departmentIds![entry.key]) ?? 0, "departmentName": request.departmentNames![entry.key], "oldDepartmentId": 0, "oldDepartmentName": "" }; }).toList() : []; // Prepare the request body matching the API specification final requestBody = { "id": 0, "userId": getCurrentUserEmployeeId(userProvider), "requestTypeId": int.tryParse(request.requestType) ?? 0, "siteIds": siteIdsArray, "departmentIds": departmentIdsArray, }; response = await ApiManager.instance.post( URLs.submitSiteRequest, body: requestBody, ); } catch (error) { _errorMessage = 'Failed to submit request: $error'; loading = false; notifyListeners(); return false; } stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { try { var responseData = json.decode(response.body); // Add request to history with server response final requestWithId = request.copyWith( id: responseData['id']?.toString() ?? 'REQ_${DateTime.now().millisecondsSinceEpoch}', status: responseData['status']?.toString() ?? 'Pending', requestDate: DateTime.now(), ); _requestHistory.insert(0, requestWithId); loading = false; notifyListeners(); return true; } catch (e) { _errorMessage = 'Request submitted but failed to parse response'; loading = false; notifyListeners(); return true; // Still return true as request was submitted } } else { try { var errorData = json.decode(response.body); _errorMessage = errorData['message'] ?? 'Failed to submit request'; } catch (e) { _errorMessage = 'Failed to submit request'; } loading = false; notifyListeners(); return false; } } // Fetch request history from API (Step 5) Future fetchRequestHistory() async { if (_loading) return -2; _loading = true; _errorMessage = null; notifyListeners(); late Response response; try { response = await ApiManager.instance.get( URLs.getSiteRequestHistory, enableToastMessage: false, ); } catch (error) { _loading = false; stateCode = -1; _errorMessage = 'Failed to fetch request history'; notifyListeners(); return -1; } stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { try { var responseData = json.decode(response.body); List listJson = responseData is List ? responseData : responseData['data'] ?? []; _requestHistory.clear(); _requestHistory.addAll( listJson.map((item) => SiteRequestModel.fromJson(item)).toList() ); } catch (e) { _errorMessage = 'Failed to parse request history'; _loading = false; notifyListeners(); return -1; } } else { _errorMessage = 'Failed to fetch request history'; } _loading = false; notifyListeners(); return response.statusCode; } // Reset provider state void reset() { _loading = false; _errorMessage = null; _requestHistory.clear(); notifyListeners(); } // Add mock history data for testing void addMockHistoryData(UserProvider userProvider) { final mockRequests = [ SiteRequestModel( id: 'REQ_001', requestType: 'Add Site', employeeId: getCurrentUserEmployeeId(userProvider), fullName: getCurrentUserFullName(userProvider), emailAddress: getCurrentUserEmail(userProvider), mobileNumber: getCurrentUserMobile(userProvider), extensionNumber: getCurrentUserExtension(userProvider), siteIds: ['site_3', 'site_4'], siteNames: ['Site C', 'Site D'], departmentIds: ['dept_2'], departmentNames: ['IT'], role: getCurrentUserRole(userProvider), status: 'Approved', requestDate: DateTime.now().subtract(const Duration(days: 5)), ), SiteRequestModel( id: 'REQ_002', requestType: 'Change Site', employeeId: getCurrentUserEmployeeId(userProvider), fullName: getCurrentUserFullName(userProvider), emailAddress: getCurrentUserEmail(userProvider), mobileNumber: getCurrentUserMobile(userProvider), extensionNumber: getCurrentUserExtension(userProvider), siteIds: ['site_1'], siteNames: ['Site A'], departmentIds: ['dept_1', 'dept_3'], departmentNames: ['HR', 'Finance'], role: getCurrentUserRole(userProvider), status: 'Pending', requestDate: DateTime.now().subtract(const Duration(days: 2)), ), SiteRequestModel( id: 'REQ_003', requestType: 'Remove Site', employeeId: getCurrentUserEmployeeId(userProvider), fullName: getCurrentUserFullName(userProvider), emailAddress: getCurrentUserEmail(userProvider), mobileNumber: getCurrentUserMobile(userProvider), extensionNumber: getCurrentUserExtension(userProvider), siteIds: ['site_2'], siteNames: ['Site B'], role: getCurrentUserRole(userProvider), status: 'Rejected', requestDate: DateTime.now().subtract(const Duration(days: 10)), ), ]; _requestHistory.addAll(mockRequests); notifyListeners(); } }