import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import '../config/api_config.dart'; import '../models/admin_model.dart'; /// 관리자 기능 관련 서비스 class AdminService extends ChangeNotifier { final String _baseUrl = ApiConfig.baseUrl; final String _token; final String _clubId; List _memberRoles = []; ClubSettings? _clubSettings; UserRole _currentUserRole = UserRole.member; AdminPermission _currentUserPermissions = AdminPermission(); bool _isLoading = false; String? _error; AdminService(this._token, this._clubId) { _initialize(); } // 게터 List get memberRoles => _memberRoles; ClubSettings? get clubSettings => _clubSettings; UserRole get currentUserRole => _currentUserRole; AdminPermission get currentUserPermissions => _currentUserPermissions; bool get isLoading => _isLoading; String? get error => _error; // 권한 확인 게터 bool get canManageMembers => _currentUserPermissions.canManageMembers; bool get canManageEvents => _currentUserPermissions.canManageEvents; bool get canManageScores => _currentUserPermissions.canManageScores; bool get canManageSettings => _currentUserPermissions.canManageSettings; bool get canManageSubscription => _currentUserPermissions.canManageSubscription; bool get canManageRoles => _currentUserPermissions.canManageRoles; bool get canViewFinancials => _currentUserPermissions.canViewFinancials; bool get canExportData => _currentUserPermissions.canExportData; /// 초기화 (현재 사용자 권한 및 클럽 설정 로드) Future _initialize() async { await Future.wait([ fetchCurrentUserRole(), fetchClubSettings(), ]); } /// 현재 사용자의 역할 및 권한 조회 Future fetchCurrentUserRole() async { _isLoading = true; _error = null; notifyListeners(); try { final response = await http.get( Uri.parse('$_baseUrl/api/clubs/$_clubId/my-role'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { final data = jsonDecode(response.body); final memberRole = MemberRole.fromJson(data); _currentUserRole = memberRole.role; _currentUserPermissions = memberRole.permissions; } else { // 기본값: 일반 회원 _currentUserRole = UserRole.member; _currentUserPermissions = AdminPermission.fromRole(UserRole.member); _error = '사용자 역할 정보를 불러오는데 실패했습니다. (${response.statusCode})'; } } catch (e) { _error = '사용자 역할 정보를 불러오는데 실패했습니다: $e'; // 기본값: 일반 회원 _currentUserRole = UserRole.member; _currentUserPermissions = AdminPermission.fromRole(UserRole.member); } finally { _isLoading = false; notifyListeners(); } } /// 클럽 내 모든 회원의 역할 정보 조회 Future fetchMemberRoles() async { if (!canManageRoles) { _error = '역할 관리 권한이 없습니다.'; notifyListeners(); return; } _isLoading = true; _error = null; notifyListeners(); try { final response = await http.get( Uri.parse('$_baseUrl/api/clubs/$_clubId/roles'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { final List data = jsonDecode(response.body); _memberRoles = data.map((role) => MemberRole.fromJson(role)).toList(); } else { _error = '회원 역할 정보를 불러오는데 실패했습니다. (${response.statusCode})'; } } catch (e) { _error = '회원 역할 정보를 불러오는데 실패했습니다: $e'; } finally { _isLoading = false; notifyListeners(); } } /// 회원 역할 변경 Future updateMemberRole(String memberId, UserRole newRole) async { if (!canManageRoles) { _error = '역할 관리 권한이 없습니다.'; notifyListeners(); return false; } _isLoading = true; _error = null; notifyListeners(); try { final response = await http.put( Uri.parse('$_baseUrl/api/clubs/$_clubId/members/$memberId/role'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $_token', }, body: jsonEncode({ 'role': newRole.toString().split('.').last, }), ); if (response.statusCode == 200) { // 역할 목록 갱신 await fetchMemberRoles(); return true; } else { _error = '회원 역할 변경에 실패했습니다. (${response.statusCode})'; return false; } } catch (e) { _error = '회원 역할 변경에 실패했습니다: $e'; return false; } finally { _isLoading = false; notifyListeners(); } } /// 클럽 설정 조회 Future fetchClubSettings() async { _isLoading = true; _error = null; notifyListeners(); try { final response = await http.get( Uri.parse('$_baseUrl/api/clubs/$_clubId/settings'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { final data = jsonDecode(response.body); _clubSettings = ClubSettings.fromJson(data); } else { _error = '클럽 설정을 불러오는데 실패했습니다. (${response.statusCode})'; } } catch (e) { _error = '클럽 설정을 불러오는데 실패했습니다: $e'; } finally { _isLoading = false; notifyListeners(); } } /// 클럽 설정 업데이트 Future updateClubSettings(ClubSettings updatedSettings) async { if (!canManageSettings) { _error = '설정 관리 권한이 없습니다.'; notifyListeners(); return false; } _isLoading = true; _error = null; notifyListeners(); try { final response = await http.put( Uri.parse('$_baseUrl/api/clubs/$_clubId/settings'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $_token', }, body: jsonEncode(updatedSettings.toJson()), ); if (response.statusCode == 200) { final data = jsonDecode(response.body); _clubSettings = ClubSettings.fromJson(data); notifyListeners(); return true; } else { _error = '클럽 설정 업데이트에 실패했습니다. (${response.statusCode})'; return false; } } catch (e) { _error = '클럽 설정 업데이트에 실패했습니다: $e'; return false; } finally { _isLoading = false; notifyListeners(); } } /// 클럽 로고 업로드 Future uploadClubLogo(String filePath) async { if (!canManageSettings) { _error = '설정 관리 권한이 없습니다.'; notifyListeners(); return false; } _isLoading = true; _error = null; notifyListeners(); try { // 파일 업로드 로직 구현 (multipart/form-data) // 실제 구현 시 http.MultipartRequest 사용 // 성공 시 설정 업데이트 await fetchClubSettings(); return true; } catch (e) { _error = '클럽 로고 업로드에 실패했습니다: $e'; return false; } finally { _isLoading = false; notifyListeners(); } } /// 클럽 데이터 내보내기 Future exportClubData(String dataType) async { if (!canExportData) { _error = '데이터 내보내기 권한이 없습니다.'; notifyListeners(); return null; } _isLoading = true; _error = null; notifyListeners(); try { final response = await http.get( Uri.parse('$_baseUrl/api/clubs/$_clubId/export/$dataType'), headers: { 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { // 다운로드 URL 또는 데이터 반환 final data = jsonDecode(response.body); return data['downloadUrl'] ?? data['data']; } else { _error = '데이터 내보내기에 실패했습니다. (${response.statusCode})'; return null; } } catch (e) { _error = '데이터 내보내기에 실패했습니다: $e'; return null; } finally { _isLoading = false; notifyListeners(); } } /// 클럽 통계 및 분석 데이터 조회 Future?> fetchClubAnalytics() async { if (!canViewFinancials) { _error = '통계 조회 권한이 없습니다.'; notifyListeners(); return null; } _isLoading = true; _error = null; notifyListeners(); try { final response = await http.get( Uri.parse('$_baseUrl/api/clubs/$_clubId/analytics'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { final data = jsonDecode(response.body); return data; } else { _error = '클럽 통계 데이터를 불러오는데 실패했습니다. (${response.statusCode})'; return null; } } catch (e) { _error = '클럽 통계 데이터를 불러오는데 실패했습니다: $e'; return null; } finally { _isLoading = false; notifyListeners(); } } /// 특정 권한이 있는지 확인 bool hasPermission(String permissionName) { switch (permissionName) { case 'manageMembers': return _currentUserPermissions.canManageMembers; case 'manageEvents': return _currentUserPermissions.canManageEvents; case 'manageScores': return _currentUserPermissions.canManageScores; case 'manageSettings': return _currentUserPermissions.canManageSettings; case 'manageSubscription': return _currentUserPermissions.canManageSubscription; case 'manageRoles': return _currentUserPermissions.canManageRoles; case 'viewFinancials': return _currentUserPermissions.canViewFinancials; case 'exportData': return _currentUserPermissions.canExportData; default: return false; } } }