import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:logger/logger.dart';
import 'package:sigap/src/cores/services/biometric_service.dart';
import 'package:sigap/src/cores/services/location_service.dart';
import 'package:sigap/src/cores/services/supabase_service.dart';
import 'package:sigap/src/features/auth/presentasion/pages/signin/signin_screen.dart';
import 'package:sigap/src/features/personalization/data/models/models/user_metadata_model.dart';
import 'package:sigap/src/utils/constants/app_routes.dart';
import 'package:sigap/src/utils/exceptions/exceptions.dart';
import 'package:sigap/src/utils/exceptions/format_exceptions.dart';
import 'package:sigap/src/utils/exceptions/platform_exceptions.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

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

  // ---------------------------------------------------------------------------
  // VARIABLES & GETTERS
  // ---------------------------------------------------------------------------
  // Variable
  final storage = GetStorage();
  final _supabase = SupabaseService.instance.client;
  final _locationService = LocationService.instance;
  final _biometricService = Get.find<BiometricService>();
  final _logger = Logger();

  // Getters that use the Supabase service
  User? get authUser => SupabaseService.instance.currentUser;
  String? get currentUserId => SupabaseService.instance.currentUserId;
  Session? get currentSession => _supabase.auth.currentSession;

  // ---------------------------------------------------------------------------
  // LIFECYCLE & REDIRECT
  // ---------------------------------------------------------------------------
  @override
  void onReady() {
    // FlutterNativeSplash.remove();
    screenRedirect();
  }

  // Check for biometric login on app start
  Future<bool> attemptBiometricLogin() async {
    try {
      if (!await _biometricService.isBiometricLoginEnabled()) {
        return false;
      }

      String? sessionToken = await _biometricService.attemptBiometricLogin();
      if (sessionToken == null || sessionToken.isEmpty) {
        return false;
      }

      try {
        // Use the session token to restore the session
        await _supabase.auth.setSession(sessionToken);

        // Verify if session was successfully restored
        final session = _supabase.auth.currentSession;
        if (session != null) {
          _logger.i('Biometric login successful');
          Get.offAllNamed(AppRoutes.navigationMenu);
          return true;
        } else {
          _logger.w('Session is null after biometric login');
          return false;
        }
      } catch (sessionError) {
        _logger.e('Session error: $sessionError');

        // Try alternate method with recoverSession if setSession fails
        try {
          final response = await _supabase.auth.recoverSession(sessionToken);
          if (response.session != null) {
            _logger.i('Biometric login successful using recoverSession');
            Get.offAllNamed(AppRoutes.navigationMenu);
            return true;
          }
          return false;
        } catch (recoverError) {
          _logger.e('Recover session error: $recoverError');
          return false;
        }
      }
    } catch (e) {
      // If token is invalid or expired, disable biometric login
      await _biometricService.disableBiometricLogin();
      _logger.e('Error during biometric login: $e');
      return false;
    }
  }


  static bool _isRedirecting = false;

  /// Updated screenRedirect method to handle onboarding preferences
  void screenRedirect({UserMetadataModel? arguments}) async {
    // Prevent recursive calls with a static guard
    if (_isRedirecting) {
      Logger().w('Screen redirect already in progress, ignoring this call');
      return;
    }

    try {
      _isRedirecting = true;
      Logger().d('Starting screen redirect');

      final session = _supabase.auth.currentSession;
      final bool isFirstTime = storage.read('isFirstTime') ?? true;
      final isEmailVerified = session?.user.emailConfirmedAt != null;
      final isProfileComplete =
          session?.user.userMetadata?['profile_status'] == 'completed';

      // Cek lokasi terlebih dahulu
      if (!isFirstTime) {
        bool isLocationValid =
            await _locationService.isLocationValidForFeature();
        if (!isLocationValid) {
          Logger().w('Location is invalid, redirecting to location warning');
          _navigateToRoute(AppRoutes.locationWarning);
          return;
        }
      }

      if (session != null) {
        if (!isEmailVerified) {
          _navigateToRoute(AppRoutes.emailVerification);
        } else if (!isProfileComplete && isEmailVerified) {
          // If already on registration form, don't redirect again
          if (Get.currentRoute == AppRoutes.registrationForm) {
            Logger().d('Already on registration form, not redirecting');
            return;
          }
          _navigateToRoute(AppRoutes.registrationForm);
        } else {
          _navigateToRoute(AppRoutes.navigationMenu);
        }
      } else {
        await _handleUnauthenticatedUser(isFirstTime);
      }
    } catch (e) {
      Logger().e('Error in screenRedirect: $e');
      _navigateToRoute(AppRoutes.signIn);
    } finally {
      _isRedirecting = false;
      Logger().d('Screen redirect completed');
    }
  }

  void _navigateToRoute(String routeName) {
    // Check if already on this route to avoid navigation loops
    if (Get.currentRoute == routeName) {
      Logger().d('Already on $routeName, skipping navigation');
      return;
    }
    Logger().d('Navigating to: $routeName');
    Get.offAllNamed(routeName);
  }

  // Pisahkan logic untuk user yang belum login
  Future<void> _handleUnauthenticatedUser(bool isFirstTime) async {
    if (Get.currentRoute != AppRoutes.onboarding) {
      bool biometricSuccess = await attemptBiometricLogin();
      if (!biometricSuccess) {
        if (isFirstTime) {
          _navigateToRoute(AppRoutes.onboarding);
        } else {
          _navigateToRoute(AppRoutes.signIn);
        }
      }
    }
  }

  // ---------------------------------------------------------------------------
  // EMAIL & PASSWORD AUTHENTICATION
  // ---------------------------------------------------------------------------
  // Sign in with email and password
  Future<AuthResponse> signInWithEmailPassword({
    required String email,
    required String password,
  }) async {
    try {
      // Check if the user is banned
      final bannedUser = await _supabase.rpc(
        'check_if_banned',
        params: {'user_email': email},
      );
      if (bannedUser != null && bannedUser == true) {
        throw TExceptions(
          'This account has been banned due to violation of terms.',
        );
      }

      final response = await _supabase.auth.signInWithPassword(
        email: email,
        password: password,
      );

      // Setup biometric login if available
      if (_biometricService.isBiometricAvailable.value) {
        // Ask user if they want to enable biometric login
        // This would typically be done in the UI, but setting up the flow here
        await _biometricService.enableBiometricLogin();
      }

      return response;
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Login with email and password
  Future<User?> loginWithEmailPassword({
    required String email,
    required String password,
  }) async {
    try {
      final response = await _supabase.auth.signInWithPassword(
        email: email,
        password: password,
      );

      // Store user in session
      final user = response.user;

      // Check for errors
      if (user == null) {
        Logger().e('User is null after sign in');
        throw 'User is null after sign in';
      }

      Logger().i('User signed in: ${user.email}');

      // Return user
      return user;
    } on AuthException catch (e) {
      throw TExceptions(e.message).message;
    } on FormatException catch (_) {
      throw const TFormatException().message;
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } catch (e) {
      throw e.toString();
    }
  }

  // Sign in with Google
  // Future<User?> signInWithGoogle() async {
  //   try {
  //     // Use Supabase auth to sign in with Google
  //     final response = await _supabase.auth.signInWithOAuth(
  //       Provider.google,
  //       redirectTo: kIsWeb ? null : 'io.supabase.sigap://login-callback/',
  //       queryParams: {'access_type': 'offline'},
  //     );

  //     // Check if sign in was successful
  //     if (!response.isSuccess()) {
  //       throw 'Google sign in failed';
  //     }

  //     // Get session
  //     final session = _supabase.auth.currentSession;
  //     if (session == null) {
  //       throw 'No session after Google sign in';
  //     }

  //     // Return user
  //     return session.user;
  //   } on AuthException catch (e) {
  //     throw TExceptions(e.message).message;
  //   } catch (e) {
  //     throw e.toString();
  //   }
  // }

  // ---------------------------------------------------------------------------
  // SESSION MANAGEMENT
  // ---------------------------------------------------------------------------
  // Get current session
  Future<Map<String, dynamic>?> getSession() async {
    try {
      final session = _supabase.auth.currentSession;
      if (session != null) {
        return {'user': session.user, 'session': session};
      }
      return null;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // ---------------------------------------------------------------------------
  // EMAIL VERIFICATION & PASSWORD RESET
  // ---------------------------------------------------------------------------
  // Send email verification
  Future<void> sendEmailVerification() async {
    try {
      await _supabase.auth.resend(
        type: OtpType.signup,
        email: _supabase.auth.currentUser!.email,
      );
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Send reset password email
  Future<void> sendResetPasswordForEmail(String email) async {
    try {
      await _supabase.auth.resetPasswordForEmail(email);
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Verify OTP
  Future<AuthResponse> verifyOtp(String otp) async {
    try {
      final AuthResponse res = await _supabase.auth.verifyOTP(
        type: OtpType.signup,
        token: otp,
      );

      final Session? session = res.session;
      final User? user = res.user;

      if (session == null && user == null) {
        throw TExceptions('Failed to verify OTP. Please try again.');
      }

      return res;
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Update password after reset
  Future<UserResponse> updatePasswordAfterReset(String newPassword) async {
    try {
      final response = await _supabase.auth.updateUser(
        UserAttributes(password: newPassword),
      );
      return response;
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Change password (requires reauthentication)
  Future<String> changePassword(
    String currentPassword,
    String newPassword,
    String email,
  ) async {
    try {
      // Reauthenticate user
      await _supabase.auth.reauthenticate();

      // Update password
      await _supabase.auth.updateUser(UserAttributes(password: newPassword));

      // Password changed successfully
      return 'Password changed successfully.';
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Resend email verification
  Future<void> resendEmailVerification(String email) async {
    try {
      await _supabase.auth.resend(type: OtpType.signup, email: email);
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // ---------------------------------------------------------------------------
  // SOCIAL AUTHENTICATION
  // ---------------------------------------------------------------------------
  // Google sign in
  Future<bool> signInWithGoogle() async {
    try {
      return await _supabase.auth.signInWithOAuth(
        OAuthProvider.google,
        authScreenLaunchMode: LaunchMode.inAppWebView,
      );
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Facebook sign in
  Future<bool> signInWithFacebook() async {
    try {
      return await _supabase.auth.signInWithOAuth(
        OAuthProvider.facebook,
        authScreenLaunchMode: LaunchMode.inAppWebView,
      );
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Apple sign in
  Future<bool> signInWithApple() async {
    try {
      return await _supabase.auth.signInWithOAuth(
        OAuthProvider.apple,
        authScreenLaunchMode: LaunchMode.inAppWebView,
      );
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Github sign in
  Future<bool> signInWithGithub() async {
    try {
      return await _supabase.auth.signInWithOAuth(
        OAuthProvider.github,
        authScreenLaunchMode: LaunchMode.inAppWebView,
      );
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Twitter sign in
  Future<bool> signInWithTwitter() async {
    try {
      return await _supabase.auth.signInWithOAuth(
        OAuthProvider.twitter,
        authScreenLaunchMode: LaunchMode.inAppWebView,
      );
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // ---------------------------------------------------------------------------
  // SIGN UP & ROLE MANAGEMENT
  // ---------------------------------------------------------------------------
  // Sign up with credential (email, password, NIK/NRP, etc)
  Future<AuthResponse> signUpWithCredential(
    String email,
    String password,
    String identifier, { // NIK for users or NRP for officers
    Map<String, dynamic>? userMetadata,
    bool isOfficer = false,
    Map<String, dynamic>? officerData,
  }) async {
    try {
      // Validate location for registration
      bool isLocationValid = await _locationService.isLocationValidForFeature();
      if (!isLocationValid) {
        throw TExceptions(
          'Registration is only available within Jember area. Please ensure your location services are enabled and you are not using a mock location app.',
        );
      }

      // Check if identifier (NIK/NRP) is already registered
      final identifierField = isOfficer ? 'nrp' : 'nik';
      final identifierType = isOfficer ? 'NRP' : 'NIK';

      if (isOfficer) {
        final existingOfficer =
            await _supabase
                .from('officers')
                .select('id, is_banned')
                .eq('nrp', identifier)
                .maybeSingle();

        if (existingOfficer != null) {
          bool isBanned = existingOfficer['is_banned'] as bool? ?? false;
          if (isBanned) {
            throw TExceptions(
              'This $identifierType is associated with a banned account.',
            );
          } else {
            throw TExceptions('This $identifierType is already registered.');
          }
        }
      } else {
        // For regular users, check NIK in profiles
        final existingUser =
            await _supabase
                .from('profiles')
                .select('id, user_id')
                .eq('nik', identifier)
                .maybeSingle();

        if (existingUser != null) {
          // Check if user is banned
          final userId = existingUser['user_id'];
          final userBanCheck =
              await _supabase
                  .from('users')
                  .select('is_banned')
                  .eq('id', userId)
                  .maybeSingle();

          if (userBanCheck != null &&
              (userBanCheck['is_banned'] as bool? ?? false)) {
            throw TExceptions(
              'This $identifierType is associated with a banned account.',
            );
          } else {
            throw TExceptions('This $identifierType is already registered.');
          }
        }
      }

      // Prepare the complete user metadata
      final metadata = userMetadata ?? {};

      // Add officer flag and data if needed
      metadata['is_officer'] = isOfficer;
      if (isOfficer && officerData != null) {
        metadata['officer_data'] = officerData;
      }

      // Add identifier to metadata
      if (isOfficer) {
        if (metadata['officer_data'] == null) {
          metadata['officer_data'] = {};
        }
        metadata['officer_data']['nrp'] = identifier;
      } else {
        metadata['nik'] = identifier;
      }

      final authResponse = await _supabase.auth.signUp(
        email: email,
        password: password,
        data: metadata,
      );

      final Session? session = authResponse.session;
      final User? user = authResponse.user;

      if (session == null && user == null) {
        throw TExceptions('Failed to sign up. Please try again.');
      }

      // Create profile with NIK if user is not an officer
      if (!isOfficer && user != null) {
        await _supabase.from('profiles').insert({
          'user_id': user.id,
          'nik': identifier,
        });
      }

      return authResponse;
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      if (e is TExceptions) {
        rethrow;
      }
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Add this method to the AuthenticationRepository class

  /// Creates a new user with initial data but doesn't complete the profile setup
  Future<AuthResponse> initialSignUp({
    required String email,
    required String password,
    required UserMetadataModel initialData,
  }) async {
    try {
      // Convert to UserModel for more functionality
      final userMetadataModel = UserMetadataModel.fromInitUserMetadata(
        initialData,
        email: email,
      );

      final AuthResponse res = await _supabase.auth.signUp(
        email: email,
        password: password,
        data: userMetadataModel.toInitialSignupJson(),
      );

      return res;
    } on AuthException catch (e) {
      throw e.message;
    } catch (e) {
      throw 'Something went wrong. Please try again.';
    }
  }

  /// Updates user profile after registration form completion
  Future<void> completeUserProfile(UserMetadataModel completeData) async {
    if (_isRedirecting) {
      // Don't attempt profile completion while already redirecting
      throw 'Cannot complete profile during redirection. Please try again.';
    }

    try {
      // Convert to UserModel
      final userMetadataModel = UserMetadataModel.fromInitUserMetadata(
        completeData,
        profileStatus: 'completed',
      );

      // First update auth metadata
      await _supabase.auth.updateUser(
        UserAttributes(data: userMetadataModel.toProfileCompletionJson()),
      );

      // Then update or insert relevant tables based on the role
      if (completeData.isOfficer && completeData.officerData != null) {
        await _supabase
            .from('officers')
            .insert(completeData.officerData!.toJson());
      } else if (!completeData.isOfficer && completeData.viewerData != null) {
        await _supabase
            .from('profiles')
            .insert(completeData.viewerData!.toJson());
      }

      // Set redirection flag to ensure we don't navigate before setup is complete
      _isRedirecting = true;
    } catch (e) {
      throw 'Failed to update profile: ${e.toString()}';
    }
  }

  /// Update user role after social authentication
  Future<void> updateUserRoleOAuth({
    required String userId,
    required UserMetadataModel metadata,
  }) async {
    try {
      // Convert to UserModel for more functionality
      final userMetadataModel = UserMetadataModel.fromInitUserMetadata(
        metadata,
      );

      // Update user metadata in auth
      await _supabase.auth.updateUser(
        UserAttributes(data: userMetadataModel.toAuthMetadataJson()),
      );

      // Store role information for later use
      final localStorage = GetStorage();
      localStorage.write('TEMP_USER_ID', userId);
      localStorage.write('TEMP_ROLE_ID', metadata.roleId);
      localStorage.write('IS_OFFICER', metadata.isOfficer);
    } catch (e) {
      throw 'Failed to update user role: ${e.toString()}';
    }
  }

  // Update user role (officer/user) and metadata
  Future<UserResponse> updateUserRole({
    required bool isOfficer,
    Map<String, dynamic>? officerData,
  }) async {
    try {
      // Prepare metadata with the officer flag
      final userMetadata = <String, dynamic>{'is_officer': isOfficer};

      // Add officer data if provided
      if (isOfficer && officerData != null) {
        userMetadata['officer_data'] = officerData;
      }

      // Update the user metadata which will trigger the role change function
      final response = await _supabase.auth.updateUser(
        UserAttributes(data: userMetadata),
      );
      return response;
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Add these methods to the AuthenticationRepository class

  // ---------------------------------------------------------------------------
  // BIOMETRIC AUTHENTICATION
  // ---------------------------------------------------------------------------
  // Enable or disable biometric login
  Future<void> toggleBiometricLogin(bool enable) async {
    if (enable) {
      await _biometricService.enableBiometricLogin();
    } else {
      await _biometricService.disableBiometricLogin();
    }
  }

  // Check if biometric login is enabled
  Future<bool> isBiometricLoginEnabled() async {
    return await _biometricService.isBiometricLoginEnabled();
  }

  // Check if biometrics are available on the device
  Future<bool> isBiometricAvailable() async {
    return _biometricService.isBiometricAvailable.value;
  }

  // ---------------------------------------------------------------------------
  // LOGOUT & ACCOUNT DELETION
  // ---------------------------------------------------------------------------
  // Sign out
  Future<void> signOut() async {
    try {
      await _supabase.auth.signOut();
      Get.offAll(() => const SignInScreen());
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }

  // Delete account
  Future<void> deleteAccount() async {
    try {
      final userId = _supabase.auth.currentUser!.id;
      await _supabase.rpc('delete_account', params: {'user_id': userId});
    } on AuthException catch (e) {
      throw TExceptions(e.message);
    } on FormatException catch (_) {
      throw const TFormatException();
    } on PlatformException catch (e) {
      throw TPlatformException(e.code).message;
    } on PostgrestException catch (error) {
      throw TExceptions.fromCode(error.code ?? 'unknown_error');
    } catch (e) {
      throw TExceptions('Something went wrong. Please try again later.');
    }
  }
}
