import 'package:flutter/foundation.dart'; import 'package:injectable/injectable.dart'; import 'package:superport/data/datasources/remote/lookup_remote_datasource.dart'; import 'package:superport/data/models/lookups/lookup_data.dart'; @lazySingleton class LookupService extends ChangeNotifier { final LookupRemoteDataSource _dataSource; LookupData? _lookupData; bool _isLoading = false; String? _error; DateTime? _lastFetchTime; // 캐시 유효 시간 (30분) static const Duration _cacheValidDuration = Duration(minutes: 30); LookupService(this._dataSource); // Getters LookupData? get lookupData => _lookupData; bool get isLoading => _isLoading; String? get error => _error; bool get hasData => _lookupData != null; // 캐시가 유효한지 확인 bool get isCacheValid { if (_lastFetchTime == null) return false; return DateTime.now().difference(_lastFetchTime!) < _cacheValidDuration; } // 장비 타입 목록 List get equipmentTypes => _lookupData?.equipmentTypes ?? []; // 장비 상태 목록 List get equipmentStatuses => _lookupData?.equipmentStatuses ?? []; // 라이선스 타입 목록 List get licenseTypes => _lookupData?.licenseTypes ?? []; // 제조사 목록 List get manufacturers => _lookupData?.manufacturers ?? []; // 사용자 역할 목록 List get userRoles => _lookupData?.userRoles ?? []; // 회사 상태 목록 List get companyStatuses => _lookupData?.companyStatuses ?? []; // 창고 타입 목록 List get warehouseTypes => _lookupData?.warehouseTypes ?? []; // 전체 조회 데이터 로드 Future loadAllLookups({bool forceRefresh = false}) async { // 캐시가 유효하고 강제 새로고침이 아니면 캐시 사용 if (!forceRefresh && isCacheValid && hasData) { return; } _isLoading = true; _error = null; notifyListeners(); try { final result = await _dataSource.getAllLookups(); result.fold( (failure) { _error = failure.message; _isLoading = false; notifyListeners(); }, (data) { _lookupData = data; _lastFetchTime = DateTime.now(); _error = null; _isLoading = false; notifyListeners(); }, ); } catch (e) { _error = '조회 데이터 로드 중 오류가 발생했습니다: $e'; _isLoading = false; notifyListeners(); } } // 특정 타입의 조회 데이터만 로드 Future>?> loadLookupsByType(String type) async { try { final result = await _dataSource.getLookupsByType(type); return result.fold( (failure) { _error = failure.message; notifyListeners(); return null; }, (data) { // 부분 업데이트 (필요한 경우) _updatePartialData(type, data); return data; }, ); } catch (e) { _error = '타입별 조회 데이터 로드 중 오류가 발생했습니다: $e'; notifyListeners(); return null; } } // 부분 데이터 업데이트 void _updatePartialData(String type, Map> data) { if (_lookupData == null) { // 전체 데이터가 없으면 부분 데이터만으로 초기화 _lookupData = LookupData( equipmentTypes: data['equipment_types'] ?? [], equipmentStatuses: data['equipment_statuses'] ?? [], licenseTypes: data['license_types'] ?? [], manufacturers: data['manufacturers'] ?? [], userRoles: data['user_roles'] ?? [], companyStatuses: data['company_statuses'] ?? [], warehouseTypes: data['warehouse_types'] ?? [], ); } else { // 기존 데이터의 특정 부분만 업데이트 _lookupData = _lookupData!.copyWith( equipmentTypes: data['equipment_types'] ?? _lookupData!.equipmentTypes, equipmentStatuses: data['equipment_statuses'] ?? _lookupData!.equipmentStatuses, licenseTypes: data['license_types'] ?? _lookupData!.licenseTypes, manufacturers: data['manufacturers'] ?? _lookupData!.manufacturers, userRoles: data['user_roles'] ?? _lookupData!.userRoles, companyStatuses: data['company_statuses'] ?? _lookupData!.companyStatuses, warehouseTypes: data['warehouse_types'] ?? _lookupData!.warehouseTypes, ); } notifyListeners(); } // 코드로 아이템 찾기 LookupItem? findByCode(List items, String code) { try { return items.firstWhere((item) => item.code == code); } catch (_) { return null; } } // 이름으로 아이템 찾기 LookupItem? findByName(List items, String name) { try { return items.firstWhere((item) => item.name == name); } catch (_) { return null; } } // 캐시 클리어 void clearCache() { _lookupData = null; _lastFetchTime = null; _error = null; notifyListeners(); } }