import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../config/api_config.dart'; import '../models/club_model.dart'; import './api_service.dart'; import './event_bus.dart'; class ClubService with ChangeNotifier { List _clubs = []; Club? _currentClub; bool _isLoading = false; String? _token; ApiService _apiService; bool _disposed = false; // 기본 생성자 ClubService() : _apiService = ApiService(); // 테스트용 생성자 ClubService.forTest(this._apiService); List get clubs => [..._clubs]; Club? get currentClub => _currentClub; bool get isLoading => _isLoading; // 초기화 함수 Future initialize(String token) async { if (_disposed) return; _token = token; _apiService.setToken(token); // 저장된 현재 클럽 ID 가져오기 final prefs = await SharedPreferences.getInstance(); final clubId = prefs.getString(ApiConfig.clubIdKey); if (clubId != null) { if (_disposed) return; await fetchClubById(clubId); } } // 사용자의 모든 클럽 가져오기 Future fetchUserClubs() async { if (_disposed || _token == null) return; _isLoading = true; if (!_disposed) notifyListeners(); try { final data = await _apiService.post('${ApiConfig.clubs}/user'); final List clubsData = data; _clubs = clubsData.map((clubData) => Club.fromJson(clubData)).toList(); _isLoading = false; if (!_disposed) notifyListeners(); } catch (e) { _isLoading = false; if (!_disposed) notifyListeners(); throw Exception('클럽 목록을 불러오는데 실패했습니다: $e'); } } // ID로 클럽 정보 가져오기 Future fetchClubById(String clubId) async { if (_disposed || _token == null) return; _isLoading = true; if (!_disposed) notifyListeners(); try { final data = await _apiService.post( ApiConfig.clubs, data: {'clubId': clubId}, ); // 백엔드에서는 club 키로 감싸지 않고 직접 클럽 객체를 반환합니다 _currentClub = Club.fromJson(data); // 현재 클럽 ID 저장 final prefs = await SharedPreferences.getInstance(); await prefs.setString(ApiConfig.clubIdKey, clubId); _isLoading = false; if (!_disposed) notifyListeners(); } catch (e) { _isLoading = false; if (!_disposed) notifyListeners(); throw Exception('클럽 정보를 불러오는데 실패했습니다: $e'); } } // 현재 클럽 설정 Future setCurrentClub(String clubId) async { await fetchClubById(clubId); } // 백엔드에 클럽 선택 요청 (세션에 clubId 저장) Future selectClub(String clubId) async { if (_disposed || _token == null) return; _isLoading = true; if (!_disposed) notifyListeners(); try { await _apiService.post( '${ApiConfig.clubs}/select-club', data: {'clubId': clubId}, ); // 클럽 선택 성공 후 클럽 정보 가져오기 if (_disposed) return; await fetchClubById(clubId); // 클럽 ID를 로컬에 저장 final prefs = await SharedPreferences.getInstance(); await prefs.setString(ApiConfig.clubIdKey, clubId); // 클럽 데이터도 함께 저장 if (_currentClub != null) { await prefs.setString('${ApiConfig.clubIdKey}_data', jsonEncode(_currentClub!.toJson())); } // 클럽 변경 이벤트 발생 - 다른 서비스들에게 알림 if (!_disposed) { EventBus().fire(ClubChangedEvent(clubId)); } _isLoading = false; if (!_disposed) notifyListeners(); } catch (e) { _isLoading = false; if (!_disposed) notifyListeners(); throw Exception('클럽 선택에 실패했습니다: $e'); } } // 클럽 생성 Future createClub(Club club) async { if (_token == null) { throw Exception('인증이 필요합니다'); } _isLoading = true; if (!_disposed) notifyListeners(); try { final data = await _apiService.post( ApiConfig.clubs, data: club.toJson(), ); final newClub = Club.fromJson(data['club']); _clubs.add(newClub); _currentClub = newClub; // 현재 클럽 ID 저장 final prefs = await SharedPreferences.getInstance(); await prefs.setString(ApiConfig.clubIdKey, newClub.id); _isLoading = false; if (!_disposed) notifyListeners(); return newClub; } catch (e) { _isLoading = false; if (!_disposed) notifyListeners(); throw Exception('클럽 생성에 실패했습니다: $e'); } } // 클럽 정보 업데이트 Future updateClub(String clubId, Map updates) async { if (_disposed || _token == null) { throw Exception('인증이 필요합니다'); } _isLoading = true; if (!_disposed) notifyListeners(); try { final data = await _apiService.put( ApiConfig.clubs, data: { 'clubId': clubId, ...updates, }, ); // 백엔드 응답 처리: 직접 클럽 객체가 반환되거나 {club: {...}} 형태로 반환될 수 있음 final updatedClub = data is Map && data.containsKey('club') ? Club.fromJson(data['club']) : Club.fromJson(data); // 클럽 목록 업데이트 final index = _clubs.indexWhere((club) => club.id == clubId); if (index >= 0) { _clubs[index] = updatedClub; } // 현재 클럽이 업데이트된 클럽인 경우 업데이트 if (_currentClub?.id == clubId) { _currentClub = updatedClub; } _isLoading = false; if (!_disposed) notifyListeners(); return updatedClub; } catch (e) { _isLoading = false; if (!_disposed) notifyListeners(); throw Exception('클럽 정보 업데이트에 실패했습니다: $e'); } } // 클럽 정보 가져오기 (ID로) Future fetchClub(String clubId) async { if (_disposed || _token == null) { throw Exception('인증이 필요합니다'); } try { // 현재 클럽이 요청한 클럽과 동일한 경우 캐시된 데이터 반환 if (_currentClub != null && _currentClub!.id == clubId) { return _currentClub!; } final data = await _apiService.post( ApiConfig.clubs, data: {'clubId': clubId}, ); final club = Club.fromJson(data); return club; } catch (e) { throw Exception('클럽 정보를 불러오는데 실패했습니다: $e'); } } @override void dispose() { _disposed = true; super.dispose(); } }