import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:sigap/src/cores/services/biometric_service.dart';
import 'package:sigap/src/features/auth/data/repositories/authentication_repository.dart';
import 'package:sigap/src/utils/constants/app_routes.dart';
import 'package:sigap/src/utils/popups/loaders.dart';

class SignInController extends GetxController {
  static SignInController get instance => Get.find();

  final _logger = Logger();
  final _authRepo = Get.find<AuthenticationRepository>();
  final _biometricService = Get.find<BiometricService>();

  // Form controllers
  final email = TextEditingController();
  final password = TextEditingController();

  // Form error messages
  final RxString emailError = RxString('');
  final RxString passwordError = RxString('');

  // States
  final RxBool isLoading = RxBool(false);
  final RxBool isPasswordVisible = RxBool(false);
  final RxBool isBiometricAvailable = RxBool(false);

  @override
  void onInit() {
    super.onInit();
    _checkBiometricAvailability();
  }

  @override
  void onClose() {
    email.dispose();
    password.dispose();
    super.onClose();
  }

  // Check if biometrics is available and enabled for the user
  Future<void> _checkBiometricAvailability() async {
    try {
      final isAvailable = _biometricService.isBiometricAvailable.value;
      final isEnabled = await _biometricService.isBiometricLoginEnabled();
      isBiometricAvailable.value = isAvailable && isEnabled;
    } catch (e) {
      _logger.e('Error checking biometric availability: $e');
      isBiometricAvailable.value = false;
    }
  }

  // Attempt to sign in with biometrics
  Future<void> signInWithBiometrics() async {
    try {
      isLoading.value = true;

      // Reuse the existing method from AuthRepository
      bool success = await _authRepo.attemptBiometricLogin();

      if (success) {
        // Redirect is handled automatically by restoreSession
        _authRepo.screenRedirect();
      } else {
        // Show error if biometric authentication failed
        TLoaders.errorSnackBar(
          title: 'Authentication Failed',
          message:
              'Biometric authentication unsuccessful. Please try again or use email and password.',
        );
      }
    } catch (e) {
      _logger.e('Biometric sign-in error: $e');
      TLoaders.errorSnackBar(
        title: 'Biometric Sign In Failed',
        message: e.toString(),
      );
    } finally {
      isLoading.value = false;
    }
  }

  // Toggle password visibility
  void togglePasswordVisibility() {
    isPasswordVisible.value = !isPasswordVisible.value;
  }

  // Navigate to forgot password screen
  void goToForgotPassword() {
    Get.toNamed(AppRoutes.forgotPassword);
  }

  // Navigate to sign up screen
  void goToSignUp() {
    Get.toNamed(AppRoutes.roleSelection);
  }

  // Clear error messages
  void clearErrors() {
    emailError.value = '';
    passwordError.value = '';
  }

  // Sign in with email and password
  Future<void> signIn(GlobalKey<FormState> formKey) async {
    // Clear previous errors
    clearErrors();

    // Validate form
    final isValid = formKey.currentState?.validate() ?? false;
    if (!isValid) return;

    try {
      isLoading.value = true;

      // Attempt to sign in
      await _authRepo.loginWithEmailPassword(
        email: email.text.trim(),
        password: password.text.trim(),
      );

      // Handle result
      // _logger.i('Sign in successful: $signInResult');

      // Redirect based on user's profile status
      _authRepo.screenRedirect();
    } catch (e) {
      isLoading.value = false;

      // Handle specific errors
      if (e.toString().contains('user-not-found')) {
        emailError.value = 'No user found with this email';
      } else if (e.toString().contains('wrong-password')) {
        passwordError.value = 'Incorrect password';
      } else if (e.toString().contains('invalid-email')) {
        emailError.value = 'Invalid email format';
      } else {
        // Show general error
        TLoaders.errorSnackBar(title: 'Sign In Failed', message: e.toString());
      }

      _logger.e('Sign in error: $e');
    } finally {
      isLoading.value = false;
    }
  }

  // Sign in with Google
  Future<void> googleSignIn() async {
    try {
      isLoading.value = true;

      // Attempt to sign in with Google
      await _authRepo.signInWithGoogle();

      // Redirect based on user's profile status
      _authRepo.screenRedirect();
    } catch (e) {
      isLoading.value = false;

      // Show error
      TLoaders.errorSnackBar(
        title: 'Google Sign In Failed',
        message: e.toString(),
      );

      _logger.e('Google sign in error: $e');
    } finally {
      isLoading.value = false;
    }
  }

  // Sign in with github
  Future<void> githubSignIn() async {
    try {
      isLoading.value = true;

      // Attempt to sign in with GitHub
      await _authRepo.signInWithGithub();

      // Redirect based on user's profile status
      _authRepo.screenRedirect();
    } catch (e) {
      isLoading.value = false;

      // Show error
      TLoaders.errorSnackBar(
        title: 'GitHub Sign In Failed',
        message: e.toString(),
      );

      _logger.e('GitHub sign in error: $e');
    } finally {
      isLoading.value = false;
    }
  }

  // Sign in with Facebook
  Future<void> facebookSignIn() async {
    try {
      isLoading.value = true;

      // Attempt to sign in with Facebook
      await _authRepo.signInWithFacebook();

      // Redirect based on user's profile status
      _authRepo.screenRedirect();
    } catch (e) {
      isLoading.value = false;

      // Show error
      TLoaders.errorSnackBar(
        title: 'Facebook Sign In Failed',
        message: e.toString(),
      );

      _logger.e('Facebook sign in error: $e');
    } finally {
      isLoading.value = false;
    }
  }

  // Sign in with Apple
  Future<void> appleSignIn() async {
    try {
      isLoading.value = true;

      // Attempt to sign in with Apple
      await _authRepo.signInWithApple();

      // Redirect based on user's profile status
      _authRepo.screenRedirect();
    } catch (e) {
      isLoading.value = false;

      // Show error
      TLoaders.errorSnackBar(
        title: 'Apple Sign In Failed',
        message: e.toString(),
      );

      _logger.e('Apple sign in error: $e');
    } finally {
      isLoading.value = false;
    }
  }
}
