import 'package:dio/dio.dart'; import '../../../../core/network/api_problem.dart'; import '../../../../data/network/api_client.dart'; import '../models/profile_settings.dart'; class ProfileApi { const ProfileApi({required ApiClient apiClient}) : _apiClient = apiClient; final ApiClient _apiClient; Future getProfile() async { final json = await _apiClient.getJson('/api/v1/users/me/profile'); return _toSettings(json); } Future updateProfile(ProfileSettingsV1 next) async { final payload = { 'display_name': next.displayName, 'bio': next.bio, if (next.avatarPath != null && next.avatarPath!.isNotEmpty) 'avatar_path': next.avatarPath, }; final json = await _apiClient.rawDio.patch>( '/api/v1/users/me/profile', data: payload, ); final data = json.data; if (data is! Map) { throw ApiProblem( status: 502, title: 'Invalid profile payload', detail: 'Expected profile response object', ); } return _toSettings(data); } Future uploadAvatar(String filePath) async { final formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(filePath), }); final response = await _apiClient.rawDio.post>( '/api/v1/users/me/avatar', data: formData, ); final data = response.data; if (data is! Map) { throw ApiProblem( status: 502, title: 'Invalid profile payload', detail: 'Expected profile response object', ); } return _toSettings(data); } ProfileSettingsV1 _toSettings(Map json) { final settingsRaw = json['settings']; final preferencesRaw = settingsRaw is Map ? settingsRaw['preferences'] : null; final preferences = preferencesRaw is Map ? PreferenceSettings( interfaceLanguage: (preferencesRaw['interface_language'] as String?) ?? 'zh-CN', aiLanguage: (preferencesRaw['ai_language'] as String?) ?? 'zh-CN', timezone: (preferencesRaw['timezone'] as String?) ?? 'Asia/Shanghai', country: (preferencesRaw['country'] as String?) ?? 'CN', ) : const PreferenceSettings(); return ProfileSettingsV1( displayName: (json['display_name'] as String?) ?? '', bio: (json['bio'] as String?) ?? '', avatarPath: json['avatar_path'] as String?, avatarUrl: json['avatar_url'] as String?, preferences: preferences, privacy: settingsRaw is Map ? (settingsRaw['privacy'] as Map? ?? const {}) : const {}, notification: settingsRaw is Map ? (settingsRaw['notification'] as Map? ?? const {}) : const {}, ); } }