import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';

final _auth = FirebaseAuth.instance;

Future<UserCredential> signInWithGoogle() async {
  try {
    // Trigger the authentication flow
    final GoogleSignInAccount googleUser = await GoogleSignIn.instance.authenticate();

    // Obtain the auth details from the request
    final GoogleSignInAuthentication googleAuth = googleUser.authentication;

    // Create a new credential
    final credential = GoogleAuthProvider.credential(idToken: googleAuth.idToken);

    // Once signed in, return the UserCredential
    return await FirebaseAuth.instance.signInWithCredential(credential);
  } catch (e) {
    // Handle and map Google sign-in specific errors
    final msg = mapAuthErrorGoogle(e.toString());

    throw Exception(msg);
  }
}

// flutter: Google sign-in failed: PlatformException(google_sign_in, Your app is missing support for the following URL schemes: com.googleusercontent.apps.441447288850-m7pld8j4gv8k1guc5l0jpk1auqi93mna, NSInvalidArgumentException, null)

Future<UserCredential> signUpEmail({required String email, required String password}) async {
  try {
    return await _auth.createUserWithEmailAndPassword(email: email.trim(), password: password);
  } on FirebaseAuthException catch (e) {
    throw _mapAuthError(e);
  }
}

Future<UserCredential> signInEmail({required String email, required String password}) async {
  try {
    return await _auth.signInWithEmailAndPassword(email: email.trim(), password: password);
  } on FirebaseAuthException catch (e) {
    throw _mapAuthError(e);
  }
}

Future<void> signOut() => _auth.signOut();

Stream<User?> get authState => _auth.authStateChanges();

String _mapAuthError(FirebaseAuthException e) {
  switch (e.code) {
    case 'invalid-email':
      return 'The email address is badly formatted.';
    case 'user-disabled':
      return 'This account has been disabled.';
    case 'user-not-found':
      return 'No account found with this email.';
    case 'wrong-password':
      return 'Incorrect password.';
    case 'email-already-in-use':
      return 'An account already exists with this email.';
    case 'weak-password':
      return 'Please choose a stronger password.';
    case 'operation-not-allowed':
      return 'Email/Password is disabled in Firebase Console.';
    default:
      return 'Authentication failed. (${e.code})';
  }
}

String mapAuthErrorGoogle(Object e) {
  // Some errors come wrapped in PlatformException or GoogleSignInException.
  final msg = e.toString();

  if (msg.contains('GoogleSignInExceptionCode.canceled') ||
      msg.contains('The user canceled') ||
      msg.contains('sign-in flow.') ||
      msg.contains('sign-in sflow.') ||
      msg.contains('Exception: Sign-in was canceled')) {
    return 'Sign-in was canceled.';
  }

  if (msg.contains('no_network') || msg.contains('network error') || msg.contains('Network connection lost')) {
    return 'Check your internet connection and try again.';
  }

  if (msg.contains('No active configuration') || msg.contains('GIDClientID')) {
    return 'Google Sign-In is not configured correctly for this app.';
  }

  if (msg.contains('sign_in_failed') || msg.contains('invalid credentials') || msg.contains('Authentication error')) {
    return 'Could not sign in with Google. Please try again.';
  }

  if (msg.contains('popup_closed_by_user') || msg.contains('User closed the popup')) {
    return 'Google sign-in was closed before completion.';
  }

  return 'Google authentication failed.';
}
