import 'package:flutter/material.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'dart:convert'; import '/core/constants.dart'; import 'package:http/http.dart' as http; import 'package:chepuhagram/domain/services/api_service.dart'; import 'package:chepuhagram/data/datasources/ws_client.dart'; class AuthProvider extends ChangeNotifier { bool _isLoading = false; bool get isLoading => _isLoading; int? _currentUserId; int? get currentUserId => _currentUserId; final _storage = const FlutterSecureStorage(); final _client = http.Client(); final ApiService _apiService = ApiService(); final SocketService _socketService = SocketService(); Future initRealtime() async { final token = await _apiService.getAccessToken(); if (token != null) { _socketService.connect(token); } } void closeRealtime() { _socketService.disconnect(); } SocketService get socketService => _socketService; Future login(String username, String password) async { _isLoading = true; notifyListeners(); try { final response = await _client.post( Uri.http(AppConstants.baseUrl, 'auth/login'), body: {'username': username, 'password': password}, ); final decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map; if (response.statusCode == 200) { await _storage.write( key: 'access_token', value: decodedResponse['access_token'], ); await _storage.write( key: 'refresh_token', value: decodedResponse['refresh_token'], ); await _storage.write( key: 'user_id', value: decodedResponse['user_id'].toString(), ); _currentUserId = decodedResponse['user_id']; _isLoading = false; notifyListeners(); return true; } else { _isLoading = false; notifyListeners(); final error = decodedResponse['detail'] ?? 'Ошибка запроса'; throw Exception(error); } } catch (e) { _isLoading = false; notifyListeners(); rethrow; } } Future logout() async { final mode = await _storage.read(key: 'theme_mode'); final color = await _storage.read(key: 'accent_color'); await _storage.deleteAll(); if (mode != null) { await _storage.write(key: 'theme_mode', value: mode); } if (color != null) { await _storage.write(key: 'accent_color', value: color); } notifyListeners(); } Future tryAutoLogin() async { final token = await _apiService.getAccessToken(); if (token == null) return false; try { final response = await _client .get( Uri.http(AppConstants.baseUrl, 'users/me'), headers: {'Authorization': 'Bearer $token'}, ) .timeout(const Duration(seconds: 5)); if (response.statusCode == 200) { return true; } else if (response.statusCode == 401) { bool isUpdated = await _apiService.refreshToken(); return isUpdated; } else { // Если токен протух (401), чистим память //await logout(); return false; } } catch (e) { // Если сервер недоступен (ошибка сети), // в мессенджерах обычно всё равно пускают в приложение (offline mode), // но для простоты сейчас вернем true, если токен физически есть. return true; } } }