import 'package:flutter/foundation.dart'; import 'package:injectable/injectable.dart'; import 'package:superport/data/models/zipcode_dto.dart'; import 'package:superport/domain/usecases/zipcode_usecase.dart'; import 'package:superport/core/constants/app_constants.dart'; @injectable class ZipcodeController extends ChangeNotifier { final ZipcodeUseCase _zipcodeUseCase; ZipcodeController(this._zipcodeUseCase); // 핵심 상태만 유지 List _zipcodes = []; ZipcodeDto? _selectedZipcode; bool _isLoading = false; String? _errorMessage; // 페이지네이션 int _currentPage = 1; int _totalPages = 1; int _totalCount = 0; final int _pageSize = AppConstants.defaultPageSize; // 단순한 필터 (2개 드롭다운 + 1개 텍스트) String? _selectedSido; String? _selectedGu; String _searchQuery = ''; // Hierarchy 데이터 (단 2개만) List _sidoList = []; List _guList = []; // Getters List get zipcodes => _zipcodes; ZipcodeDto? get selectedZipcode => _selectedZipcode; bool get isLoading => _isLoading; String? get errorMessage => _errorMessage; int get currentPage => _currentPage; int get totalPages => _totalPages; int get totalCount => _totalCount; String get searchQuery => _searchQuery; String? get selectedSido => _selectedSido; String? get selectedGu => _selectedGu; List get sidoList => _sidoList; List get guList => _guList; bool get hasNextPage => _currentPage < _totalPages; bool get hasPreviousPage => _currentPage > 1; // 초기화 (단순함) Future initialize() async { try { _setLoading(true); _zipcodes = []; _selectedZipcode = null; _errorMessage = null; notifyListeners(); // 시도 목록 로드 (Hierarchy API만 사용) await _loadSidoList(); // 초기 우편번호 목록 로드 (첫 페이지) await _executeSearch(); } catch (e) { _errorMessage = '초기화 중 오류가 발생했습니다.'; _isLoading = false; notifyListeners(); } } // 시도 선택 (단순함) Future setSido(String? sido) async { try { _selectedSido = sido; _selectedGu = null; // 구 초기화 _guList = []; notifyListeners(); // 선택된 시도의 구 목록 로드 if (sido != null && sido.isNotEmpty) { await _loadGuListBySido(sido); } // 실시간 검색 실행 await _executeSearch(); } catch (e) { debugPrint('시도 선택 오류: $e'); } } // 구 선택 (단순함) Future setGu(String? gu) async { try { _selectedGu = gu; notifyListeners(); // 실시간 검색 실행 await _executeSearch(); } catch (e) { debugPrint('구 선택 오류: $e'); } } // 검색어 설정 (실시간, 디바운스 없음) void setSearchQuery(String query) { _searchQuery = query; notifyListeners(); _executeSearch(); // 실시간 검색 } // 필터 초기화 (단순함) Future clearFilters() async { _searchQuery = ''; _selectedSido = null; _selectedGu = null; _guList = []; _currentPage = 1; notifyListeners(); await _executeSearch(); } // 페이지 이동 Future goToPage(int page) async { if (page < 1 || page > _totalPages) return; _currentPage = page; await _executeSearch(); } // 다음 페이지 Future nextPage() async { if (hasNextPage) { await goToPage(_currentPage + 1); } } // 이전 페이지 Future previousPage() async { if (hasPreviousPage) { await goToPage(_currentPage - 1); } } // 우편번호 선택 void selectZipcode(ZipcodeDto zipcode) { _selectedZipcode = zipcode; notifyListeners(); } // 선택 초기화 void clearSelection() { _selectedZipcode = null; notifyListeners(); } // 검색 실행 (핵심 로직) Future _executeSearch({bool refresh = false}) async { if (refresh) { _currentPage = 1; } _setLoading(true); _clearError(); try { final response = await _zipcodeUseCase.searchZipcodes( page: _currentPage, limit: _pageSize, search: _searchQuery.isNotEmpty ? _searchQuery : null, sido: _selectedSido, gu: _selectedGu, ); _zipcodes = response.items; _totalCount = response.totalCount; _totalPages = response.totalPages; _currentPage = response.currentPage; notifyListeners(); } catch (e) { _setError('우편번호 검색에 실패했습니다: ${e.toString()}'); } finally { _setLoading(false); } } // 시도 목록 로드 (Hierarchy API만 사용, fallback 없음) Future _loadSidoList() async { try { final response = await _zipcodeUseCase.getHierarchySidos(); _sidoList = response.data; debugPrint('=== Hierarchy 시도 목록 로드 완료 ==='); debugPrint('총 시도 개수: ${response.meta.total}'); debugPrint('시도 목록: ${response.data}'); } catch (e) { debugPrint('Hierarchy 시도 목록 로드 실패: $e'); _sidoList = []; } } // 구 목록 로드 (Hierarchy API만 사용, fallback 없음) Future _loadGuListBySido(String sido) async { try { final response = await _zipcodeUseCase.getHierarchyGusBySido(sido); _guList = response.data; debugPrint('=== Hierarchy 구 목록 로드 완료 ==='); debugPrint('시도: $sido, 구 개수: ${response.meta.total}'); notifyListeners(); } catch (e) { debugPrint('Hierarchy 구 목록 로드 실패: $e'); _guList = []; notifyListeners(); } } // 내부 헬퍼 메서드 void _setLoading(bool loading) { _isLoading = loading; notifyListeners(); } void _setError(String message) { _errorMessage = message; notifyListeners(); } void _clearError() { _errorMessage = null; } @override void dispose() { _zipcodes = []; _selectedZipcode = null; super.dispose(); } }