import 'dart:typed_data'; import 'package:flutter/material.dart'; import '../core/network/api_response.dart'; import '../core/network/dio_client.dart'; import '../core/storage/local_storage.dart'; import '../data/models/user.dart'; import '../data/services/user_service.dart'; /// 認證狀態管理 class AuthProvider extends ChangeNotifier { final UserService _userService; User? _user; bool _isLoggedIn = false; bool _isLoading = false; String? _token; AuthProvider(this._userService) { _initAuth(); } // Getters User? get user => _user; bool get isLoggedIn => _isLoggedIn; bool get isLoading => _isLoading; String? get token => _token; /// 初始化認證狀態 Future _initAuth() async { _token = LocalStorage.getToken(); _isLoggedIn = _token?.isNotEmpty == true; if (_isLoggedIn) { _user = _loadUserFromStorage(); } notifyListeners(); } User? _loadUserFromStorage() { final userJson = LocalStorage.getUserInfo(); return userJson != null ? User.fromJson(userJson) : null; } /// 登錄 Future> login(String username, String password) { return _authenticate(() => _userService.login(username, password)); } /// 註冊(含身份證圖片和可選推廣碼) Future> register( String username, String password, { String? referralCode, required Uint8List frontBytes, required Uint8List backBytes, }) { return _authenticate(() => _userService.register( username, password, referralCode: referralCode, frontBytes: frontBytes, backBytes: backBytes, )); } /// 統一認證處理 Future> _authenticate( Future>> Function() action, ) async { _setLoading(true); try { final response = await action(); if (!response.success || response.data == null) { return ApiResponse.fail(response.message ?? '操作失敗'); } return _handleAuthSuccess(response.data!, response.message); } catch (e) { return ApiResponse.fail('操作失敗: $e'); } finally { _setLoading(false); } } /// 處理認證成功 ApiResponse _handleAuthSuccess( Map data, String? message, ) { _token = data['token'] as String?; final userJson = data['user'] as Map? ?? data['userInfo'] as Map?; if (_token != null) { LocalStorage.saveToken(_token!); } if (userJson != null) { LocalStorage.saveUserInfo(userJson); _user = User.fromJson(userJson); } _isLoggedIn = true; notifyListeners(); return _user != null ? ApiResponse.success(_user!, message) : ApiResponse.fail('用戶信息獲取失敗'); } /// 退出登錄 Future logout() async { _setLoading(true); try { await _userService.logout(); } catch (_) { // 忽略退出登錄的接口錯誤 } _clearAuthState(); _setLoading(false); } void _clearAuthState() { LocalStorage.clearUserData(); _user = null; _token = null; _isLoggedIn = false; } /// 強制登出(token 過期時由 DioClient 回調觸發) void forceLogout() { _clearAuthState(); notifyListeners(); } /// 刷新用戶信息 Future refreshUserInfo() async { if (!_isLoggedIn) return; try { final response = await _userService.getUserInfo(); if (response.success && response.data != null) { _user = response.data; await LocalStorage.saveUserInfo(_user!.toJson()); notifyListeners(); } } catch (_) { // 忽略錯誤 } } /// 提交KYC實名認證(真實圖片上傳) Future> submitKyc( Uint8List frontBytes, Uint8List backBytes) async { try { final response = await _userService.uploadKyc(frontBytes, backBytes); if (response.success) { await refreshUserInfo(); } return response; } catch (e) { return ApiResponse.fail('KYC提交失敗: $e'); } } void _setLoading(bool value) { _isLoading = value; notifyListeners(); } }