import 'package:flutter/material.dart'; import 'package:prosapp_web_app/models/usuario.dart'; import 'package:prosapp_web_app/providers/professional_provider.dart'; import 'package:prosapp_web_app/providers/services_provider.dart'; import 'package:prosapp_web_app/router/router.dart'; import 'package:prosapp_web_app/services/api_service.dart'; import 'package:prosapp_web_app/services/navigation_service.dart'; import 'package:prosapp_web_app/services/notifications_service.dart'; import 'package:provider/provider.dart'; enum AuthStatus { checking, authenticated, notAuthenticated } class AuthProvider extends ChangeNotifier { Usuario? user; double userAverageScore = 0.0; AuthStatus authStatus = AuthStatus.checking; final _api = ApiService.instance; AuthProvider() { isAuthenticated(); } void _navigateAfterAuth() { if (user?.isPhoneVerified == false) { NavigationService.replaceTo(Flurorouter.phoneLoginRoute); } else { NavigationService.replaceTo(Flurorouter.dashboardRoute); } } Future login(String email, String password) async { try { final data = await _api.post('/auth/login', {'email': email, 'password': password}); await _api.saveToken(data['access_token'] as String); user = Usuario.fromDocument(data['user'] as Map); userAverageScore = await _loadAverageScore(user!.id); authStatus = AuthStatus.authenticated; notifyListeners(); _navigateAfterAuth(); } catch (e) { authStatus = AuthStatus.notAuthenticated; notifyListeners(); NotificationsService.showSnackBarError('Usuario o contraseña incorrectos'); } } Future register(String email, String password, String name) async { try { final data = await _api.post('/auth/register', { 'email': email, 'password': password, 'name': name.trim(), }); await _api.saveToken(data['access_token'] as String); user = Usuario.fromDocument(data['user'] as Map); authStatus = AuthStatus.authenticated; notifyListeners(); _navigateAfterAuth(); } catch (e) { authStatus = AuthStatus.notAuthenticated; notifyListeners(); NotificationsService.showSnackBarError('Email ya registrado'); } } Future verifyPhoneNumber(String phoneNumber) async { try { await _api.post('/auth/send-otp', {'phone': phoneNumber}); } catch (e) { NotificationsService.showSnackBarError('Error al enviar código SMS'); rethrow; } } Future signInWithOTP(String phoneNumber, String smsCode) async { try { final data = await _api.post('/auth/phone', {'phone': phoneNumber, 'code': smsCode}); await _api.saveToken(data['access_token'] as String); user = Usuario.fromDocument(data['user'] as Map); userAverageScore = await _loadAverageScore(user!.id); authStatus = AuthStatus.authenticated; notifyListeners(); NavigationService.replaceTo(Flurorouter.dashboardRoute); } catch (e) { authStatus = AuthStatus.notAuthenticated; notifyListeners(); NotificationsService.showSnackBarError('Código incorrecto o expirado'); } } Future verifyPhoneNumberForLink(String phoneNumber) async { try { await _api.post('/auth/send-otp', {'phone': phoneNumber}); } catch (e) { NotificationsService.showSnackBarError('Error al enviar código SMS'); rethrow; } } Future linkPhoneWithOTP(String phoneNumber, String smsCode) async { try { await _api.post('/auth/verify-phone', {'phone': phoneNumber, 'code': smsCode}); user = await _fetchMe(); NotificationsService.showSnackbar('Número vinculado exitosamente'); authStatus = AuthStatus.authenticated; notifyListeners(); NavigationService.replaceTo(Flurorouter.profileRoute); } catch (e) { NotificationsService.showSnackBarError('Código incorrecto o expirado'); } } Future addEmailAndPassword(String email, String password) async { try { await _api.post('/auth/link-email', {'email': email, 'password': password}); user = await _fetchMe(); notifyListeners(); NotificationsService.showSnackbar('Email y contraseña añadidos exitosamente'); NavigationService.replaceTo(Flurorouter.profileRoute); } catch (e) { NotificationsService.showSnackBarError('Error al añadir email'); } } Future isAuthenticated() async { final token = await _api.getToken(); if (token == null) { authStatus = AuthStatus.notAuthenticated; notifyListeners(); return false; } try { final data = await _api.get('/auth/me'); user = Usuario.fromDocument(data as Map); userAverageScore = await _loadAverageScore(user!.id); authStatus = AuthStatus.authenticated; notifyListeners(); return true; } catch (e) { await _api.deleteToken(); authStatus = AuthStatus.notAuthenticated; notifyListeners(); return false; } } Future logout() async { await _api.deleteToken(); authStatus = AuthStatus.notAuthenticated; user = null; notifyListeners(); final ctx = NavigationService.navigatorKey.currentContext!; Provider.of(ctx, listen: false).logout(); Provider.of(ctx, listen: false).logout(); NavigationService.replaceTo(Flurorouter.phoneLoginRoute); } void refreshUser() => isAuthenticated(); Future _fetchMe() async { final data = await _api.get('/auth/me'); return Usuario.fromDocument(data as Map); } Future _loadAverageScore(String userId) async { try { final data = await _api.get('/comments/reputation/$userId'); final rep = data as Map; return (rep['average'] as num?)?.toDouble() ?? 0.0; } catch (_) { return 0.0; } } }