import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:prosappco/src/authentication/exceptions/register_failed.dart';
import 'package:prosappco/src/screens/login.dart';
import 'package:prosappco/src/screens/welcome.dart';

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

  //Variables
  final _auth = FirebaseAuth.instance;
  late final Rx<User?> firebaseUser;
  final firebase = FirebaseFirestore.instance;
  final GoogleSignIn googleSignIn = GoogleSignIn();
  // final _userRef = firebase
  var verificationId = ''.obs;

  @override
  void onReady() {
    // Future.delayed(const Duration(seconds: 6));
    firebaseUser = Rx<User?>(_auth.currentUser);
    firebaseUser.bindStream(_auth.userChanges());
    ever(firebaseUser, _setInitialScreen);
  }

  _setInitialScreen(User? user) {
    user == null
        ? Get.offAll(const LoginScreen())
        : Get.offAll(const WelcomeScreen());
  }

  Future<void> phoneAuthentication(String phoneNo) async {
    await _auth.verifyPhoneNumber(
      phoneNumber: phoneNo,
      verificationCompleted: (credential) async {
        await _auth.signInWithCredential(credential);
      },
      codeSent: (verificationId, resendToken) {
        this.verificationId.value = verificationId;
      },
      codeAutoRetrievalTimeout: (verificationId) {
        this.verificationId.value = verificationId;
      },
      verificationFailed: (e) {
        if (e.code == 'invalid-phone-number') {
          Get.snackbar('Error', 'El numero no es valido.');
        } else {
          Get.snackbar('Error', 'Algo ha ido mal. Inténtalo de nuevo. $e');
        }
      },
    );
  }

  Future<void> updatePhoneNumber(String verificationId, String smsCode) async {
    try {
      PhoneAuthCredential credential = PhoneAuthProvider.credential(
          verificationId: verificationId, smsCode: smsCode);
      await FirebaseAuth.instance.currentUser!.updatePhoneNumber(credential);
      print("Phone number updated successfully");
    } catch (e) {
      print("Error updating phone number: $e");
    }
  }

  Future<bool> verifyOTP(String otp) async {
    var credentials = await _auth.signInWithCredential(
        PhoneAuthProvider.credential(
            verificationId: verificationId.value, smsCode: otp));
    return credentials.user != null ? true : false;
  }

  Future<void> createUserWithEmailAndPassword(
      String email, String password) async {
    try {
      // try {
      //   await firebase.collection('Users').doc().set({
      //     "Email": email,
      //     "Password": password,
      //   });
      // } catch (e) {
      //   print('Error $e');
      // }
      await _auth.createUserWithEmailAndPassword(
          email: email, password: password);

      firebaseUser.value != null
          ? Get.offAll(WelcomeScreen())
          : Get.to(LoginScreen());
    } on FirebaseAuthException catch (e) {
      final ex = SignUpWithEmailAndPasswordFailure.code(e.code);
      print('FIREBASE AUTH EXCEPTION - ${ex.message}');
    } catch (_) {
      const ex = SignUpWithEmailAndPasswordFailure();
      print('EXCEPTION - ${ex.message}');
      throw ex;
    }
  }

  Future<void> loginWithEmailAndPassword(String email, String password) async {
    try {
      await _auth.signInWithEmailAndPassword(email: email, password: password);
    } on FirebaseAuthException catch (e) {
    } catch (_) {}
  }

  Future<void> signInWithGoogle() async {
    try {
      final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
      final GoogleSignInAuthentication googleAuth =
          await googleUser!.authentication;
      final credential = GoogleAuthProvider.credential(
        accessToken: googleAuth.accessToken,
        idToken: googleAuth.idToken,
      );
      await FirebaseAuth.instance.signInWithCredential(credential);
    } catch (e) {
      print('Error - ${e}');
    }
  }

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

  String? getCurrentUserPhone() {
    final User? user = _auth.currentUser;
    return user?.phoneNumber;
  }

  String? getCurrentUserUid() {
    final User? user = _auth.currentUser;
    return user?.uid;
  }

  Future<String> getCity(String uid) async {
    String city = '';
    try {
      final snapshot =
          await FirebaseFirestore.instance.collection('users').doc(uid).get();
      final Map<String, dynamic>? data = snapshot.data();
      city = data?['city'] ?? '';
    } catch (e) {
      print('Error getting city: $e');
    }
    return city;
  }

  Future<String> getPhoto(String uid) async {
    String photo = '';
    try {
      final snapshot =
          await FirebaseFirestore.instance.collection('users').doc(uid).get();
      final Map<String, dynamic>? data = snapshot.data();
      photo = data?['photo'] ?? '';
    } catch (e) {
      print('Error getting photo: $e');
    }
    return photo;
  }

  Future<String> getProfession(String uid) async {
    String profession = '';
    try {
      final snapshot =
          await FirebaseFirestore.instance.collection('users').doc(uid).get();
      final Map<String, dynamic>? data = snapshot.data();
      profession = data?['profesion'] ?? '';
    } catch (e) {
      print('Error getting profesion: $e');
    }
    return profession;
  }

  Future<String> getState(String uid) async {
    String state = '';
    try {
      final snapshot =
          await FirebaseFirestore.instance.collection('users').doc(uid).get();
      final Map<String, dynamic>? data = snapshot.data();
      state = data?['estado'] ?? '';
    } catch (e) {
      print('Error getting estado: $e');
    }
    return state;
  }
}
