import 'package:flutter/foundation.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:shared_preferences/shared_preferences.dart'; class AuthService extends ChangeNotifier { final FirebaseAuth _auth = FirebaseAuth.instance; User? _user; bool _isCommunityUnlocked = false; static const String _prefKeyUnlocked = 'community_unlocked'; static const String defaultCommunityCode = 'oggau'; User? get user => _user; bool get isAuthenticated => _user != null; bool get isAnonymous => _user?.isAnonymous ?? true; bool get isRegisteredUser => _user != null && !_user!.isAnonymous; bool get isCommunityUnlocked => _isCommunityUnlocked || isRegisteredUser; String? get email => _user?.email; String? get displayName => _user?.displayName; AuthService() { _initAuth(); } Future _initAuth() async { final prefs = await SharedPreferences.getInstance(); _isCommunityUnlocked = prefs.getBool(_prefKeyUnlocked) ?? false; _auth.authStateChanges().listen((User? user) { _user = user; notifyListeners(); }); if (_user == null && _isCommunityUnlocked) { await signInAnonymously(); } } /// Verifies community access code Future verifyCommunityCode(String enteredCode) async { final cleanCode = enteredCode.trim().toLowerCase(); if (cleanCode == defaultCommunityCode || cleanCode == 'oggau2024' || cleanCode == 'oggau7063') { _isCommunityUnlocked = true; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_prefKeyUnlocked, true); if (_user == null) { await signInAnonymously(); } notifyListeners(); return true; } return false; } /// Lock community access and log out Future lockCommunityAccess() async { _isCommunityUnlocked = false; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_prefKeyUnlocked, false); await signOut(); notifyListeners(); } /// Sign in with Email and Password Future signInWithEmail(String email, String password) async { try { final credential = await _auth.signInWithEmailAndPassword( email: email.trim(), password: password, ); _user = credential.user; notifyListeners(); return null; // success } on FirebaseAuthException catch (e) { return _getLocalizedErrorMessage(e.code); } catch (e) { return 'Ein unerwarteter Fehler ist aufgetreten: $e'; } } /// Sign up with Email, Password, and Full Name Future signUpWithEmail({ required String email, required String password, required String name, }) async { try { final credential = await _auth.createUserWithEmailAndPassword( email: email.trim(), password: password, ); _user = credential.user; if (_user != null && name.isNotEmpty) { await _user!.updateDisplayName(name.trim()); } notifyListeners(); return null; // success } on FirebaseAuthException catch (e) { return _getLocalizedErrorMessage(e.code); } catch (e) { return 'Ein unerwarteter Fehler ist aufgetreten: $e'; } } /// Send password reset email Future sendPasswordReset(String email) async { try { await _auth.sendPasswordResetEmail(email: email.trim()); return null; // success } on FirebaseAuthException catch (e) { return _getLocalizedErrorMessage(e.code); } catch (e) { return 'Fehler beim Senden der E-Mail: $e'; } } /// Anonymous login Future signInAnonymously() async { try { await _auth.signInAnonymously(); } catch (e) { if (kDebugMode) { debugPrint('Sign in anonymously error: $e'); } } } /// Sign out Future signOut() async { try { await _auth.signOut(); } catch (e) { if (kDebugMode) { debugPrint('Sign out error: $e'); } } } String _getLocalizedErrorMessage(String code) { switch (code) { case 'user-not-found': return 'Kein Benutzer mit dieser E-Mail-Adresse gefunden.'; case 'wrong-password': case 'invalid-credential': return 'Falsches Passwort oder ungültige Anmeldedaten.'; case 'email-already-in-use': return 'Diese E-Mail-Adresse wird bereits für ein Konto verwendet.'; case 'invalid-email': return 'Bitte gib eine gültige E-Mail-Adresse ein.'; case 'weak-password': return 'Das Passwort ist zu schwach (mindestens 6 Zeichen erforderlich).'; case 'too-many-requests': return 'Zu viele fehlgeschlagene Versuche. Bitte warte kurz.'; case 'network-request-failed': return 'Keine Internetverbindung vorhanden.'; default: return 'Authentifizierungsfehler ($code).'; } } }