import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:country_currency_pickers/country.dart';
import 'package:country_currency_pickers/utils/utils.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart';
import 'package:http/http.dart' as dio1;
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'package:otp_timer_button/otp_timer_button.dart';
import 'package:rounded_loading_button_plus/rounded_loading_button.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sms_autofill/sms_autofill.dart';
import '../../Data/Repository/Authentication/loginrepository.dart';
import '../../Helper/Constants/Colorconstants.dart';
import '../../Helper/Logger.dart';
import '../../Helper/toast.dart';
import '../../Model/Request/Authentication/Loginrequest.dart';
import '../../Model/Response/Authentication/Loginresponse.dart';
import '../../View/Authentication/Otpverification.dart';
import '../../View/Authentication/Usercreate/Usercreateview.dart';


class AuthController extends GetxController with CodeAutoFill{

  String? formatter;
  String? currencyCode;
  String? fcmEntryToken;

  String? resendOtp;


  String? userFcmToken;
  String? contactNo;


  //Otp
  String? smsOtp;
  String verifyId = "";

  int authmode = 0;

  bool termsChecking =false;

  //Otp
  bool codeSent = false;

  var loginStatus;

  String? contactLength;


  // FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
  FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;


  Country selectedDialogCountry = CountryPickerUtils.getCountryByIsoCode('IN');


  // final RoundedLoadingButtonController btnController = RoundedLoadingButtonController();

  final RoundedLoadingButtonController loginController = RoundedLoadingButtonController();

  //Otp
  OtpTimerButtonController otpTimerController = OtpTimerButtonController();


  TextEditingController loginPhoneNumberController = TextEditingController();
  TextEditingController otpController = TextEditingController();
  TextEditingController textEditingController = TextEditingController();

  LoginRepository loginRepository = LoginRepository();


  @override
  void onInit() {
    getId();
    fcmToken();
    listenForCode();
    super.onInit();
  }

  @override
  void onClose() {
    cancel(); /// Stop listening for the OTP code
    super.onClose();
  }

  @override
  void codeUpdated() {
    otpController.text = code ?? '';
    logger.i("OTP Code Received: ${otpController.text}");
  }

  @override
  void dispose() {
    // TODO: implement dispose
    SmsAutoFill().unregisterListener();
    loginPhoneNumberController.dispose();
    otpController.dispose();
    super.dispose();
  }



  fcmToken() async {

    SharedPreferences prefs = await SharedPreferences.getInstance();
    var token = await firebaseMessaging.getToken();
    logger.i("firebase token======$token");
    fcmEntryToken = token;
    prefs.setString('fcmToken', token!);
    logger.i("tenanttokensetstring  ${prefs.getString('fcmToken')}");

  }




  void currency() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    currencyCode = prefs.getString('Code_Currency')!;
    final formats = NumberFormat();
    formatter = formats.simpleCurrencySymbol("$currencyCode");
    prefs.setString('Currency_Symbol', formatter!);
  }

  void loginTenant(context) async {
    Timer(const Duration(seconds: 1), () {
      // btnController.success();
      profileValidation(context);
    });
  }

  profileValidation(context)async{
    if (loginPhoneNumberController.text.isEmpty) {
      loginController.reset();
      Toast.showToast("Please Enter Mobile Number");
    } else if (!RegExp(
        r'^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$')
        .hasMatch(loginPhoneNumberController.text)) {
      loginController.reset();
      Toast.showToast("Please Enter a Valid Phone Number");
    } else if(termsChecking==false){
      loginController.reset();
      Toast.showToast("Please Select Terms of Service");

    }
    else {
      signIn(context);
    }
  }

  String? uniqueDeviceId;
  String? deviceId;
  var iosDeviceInfo;
  var androidDeviceInfo;
  Future<String?> getId() async {
    // var deviceInfo = DeviceInfoPlugin();
    SharedPreferences prefs = await SharedPreferences.getInstance();
    if (Platform.isIOS) { // import 'dart:io'
      // iosDeviceInfo = await deviceInfo.iosInfo;
      deviceId = iosDeviceInfo.toMap().toString();
      uniqueDeviceId = iosDeviceInfo.id;
      prefs.setString('deviceId',uniqueDeviceId!);
      print('iosDeviceInfodeviceId$deviceId');
      print('uniqueDeviceId${prefs.getString('deviceId')}');
      return iosDeviceInfo.identifierForVendor; // Unique ID on iOS
    } else {
      // androidDeviceInfo = await deviceInfo.androidInfo;
      deviceId = androidDeviceInfo.toMap().toString();
      uniqueDeviceId = androidDeviceInfo.id;
      prefs.setString('deviceId',uniqueDeviceId!);
      print('androidDeviceInfodeviceId$deviceId');
      print('uniqueDeviceId${prefs.getString('deviceId')}');
      return androidDeviceInfo.androidId; // Unique ID on Android
    }
    print('${deviceId =androidDeviceInfo.androidId}');
  }



  //Authentication

  signIn(context) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    // ✅ Ensure FCM token is ready before calling API
    if (fcmEntryToken == null) {
      await fcmToken();
    }

    // Prepare data
    final contactNo = loginPhoneNumberController.text;
    final configId = 1;
    final deviceType = Platform.operatingSystem;
    final fcmTokenValue = fcmEntryToken ?? '';
    final deviceId1 = deviceId ?? '';

    // ✅ Print all values before sending
    print("========= LOGIN REQUEST DATA =========");
    print("📱 Contact No     : $contactNo");
    print("⚙️ Config ID      : $configId");
    print("💻 Device Type    : $deviceType");
    print("🔑 FCM Token      : $fcmTokenValue");
    print("🆔 Device ID      : $deviceId1");
    print("======================================");

    // Call login API
    loginApi(
      LoginRequest(
        contactno: contactNo,
        configid: configId,
        devicetype: deviceType,
        userfcmtoken: fcmTokenValue,
        deviceid: deviceId1,
      ),
      context,
    );
  }


  loginApi(LoginRequest data,context) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    LoginResponse? result = await loginRepository.signIn(data);
    if (result?.status == true) {

      loginStatus = result?.status;
      authmode = result?.details?.authmode??0;
      userFcmToken = result?.details?.userfcmtoken;
      contactNo = result?.details?.contactno;


      logger.i('loginApilocationname ${result?.details?.locationname}');


      prefs.setInt('userId', result?.details?.userid ?? 0);
      prefs.setString('authName', result?.details?.authname ?? '');
      prefs.setInt('configId', result?.details?.configid ?? 0);
      prefs.setInt('authMode', result?.details?.authmode ?? 0);
      prefs.setInt('roleId', result?.details?.roleid ?? 0);
      prefs.setString('userFirstName', result?.details?.firstname ?? '');
      prefs.setString('userLastName', result?.details?.lastname ?? '');
      prefs.setString('userPassword', result?.details?.password ?? '');
      prefs.setString('userEmail', result?.details?.email ?? '');
      // prefs.setString('tenantContactNo', result?.details?.contactno ?? '');
      prefs.setString('address', result?.details?.address ?? '');
      prefs.setString('userSuburb', result?.details?.suburb ?? '');
      prefs.setString('userCity', result?.details?.city ?? '');
      prefs.setString('userState', result?.details?.state ?? '');
      prefs.setString('userPostcode', result?.details?.postcode ?? '');
      // prefs.setString('tenantFcmToken', result?.details?.userfcmtoken ?? '');
      prefs.setInt('userPin', result?.details?.pin ?? 0);
      prefs.setInt('partnerId', result?.details?.partnerid ?? 0);
      prefs.setInt('tenantId', result?.details?.tenantid ?? 0);
      prefs.setString('userName', result?.details?.fullname ?? '');
      prefs.setString('tenantName', result?.details?.tenantname ?? '');
      prefs.setString('tenantAddress', result?.details?.tenantaddress ?? '');
      prefs.setString('tenantCity', result?.details?.tenantcity ?? '');
      prefs.setString('tenantPostcode', result?.details?.tenantpostcode ?? '');
      prefs.setString('tenantLatitude', result?.details?.tenantlat ?? '');
      prefs.setString('tenantLongitude', result?.details?.tenantlong ?? '');
      prefs.setInt('locationId', result?.details?.locationid ?? 0);
      prefs.setString('locationName', result?.details?.locationname ?? '');
      prefs.setString('appLocation', result?.details?.applocation ?? '');
      prefs.setString('appLatitude', result?.details?.applatitude ?? '');
      prefs.setString('appLongitude', result?.details?.applongitude ?? '');
      prefs.setInt('appRadius', result?.details?.appradius ?? 0);
      prefs.setInt('appLocationId', result?.details?.applocationid ?? 0);
      prefs.setInt('moduleId', result?.details?.moduleid ?? 0);
      logger.i('App location Id from login : ${prefs.getInt('appLocationId')}');
      logger.i('location Id from login : ${prefs.getInt('locationId')}');
      update();
    }

    if(authmode !=1) {
      sendSmsOtp('${loginPhoneNumberController.text.trim()}',
          authmode: result?.details?.authmode ?? 0);
    }
    else{
      otpController.clear();
      resendOtp = '123456';
      if(authmode==1){
        var snackBar =  SnackBar(
            backgroundColor: ColorConstants.primaryColor,
            duration: const Duration(seconds: 5),
            content: Text('Please enter your 6 digit verification code provided  by Nearlexpress Business',style: TextStyle(color: ColorConstants.secondaryColor),)
        );
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      }
      Get.to(()=>OTPVerification(otp: '$resendOtp' ,authmode: authmode,logInStatus:loginStatus ,));
    }
    loginController.reset();
  }

  //Otp

  sendSmsOtp(String mobile, {authmode=0}) async {
    int otpInput = await otpGenerator();
    smsOtp = otpInput.toString();
    if(authmode==1)
    {
      onNavigateToProfileNumberVerification(otp: "123456",authmode: authmode);
    }

    else {
      receiveSmsOtp(mobile,smsOtp.toString(), Get.context);
    }
  }

  Future<void> receiveSmsOtp(String phoneNumber, String otp, context) async {
    final appSignature = await SmsAutoFill().getAppSignature;

    final message = "<#> Dear customer, use OTP $otp to sign in to Nearle App.\n$appSignature";
    final encodedMessage = Uri.encodeComponent(message);

    final url = Uri.parse(
      'https://msg.lionsms.com/api/smsapi?'
          'key=e57f5c9679af26077be1a7eadabb1b2a'
          '&route=7'
          '&sender=NEARLE'
          '&number=$phoneNumber'
          '&sms=$encodedMessage'
          '&templateid=1107174712357438611',
    );

    logger.i('urlsendOtp $url');
    logger.i('appSignaturereceiveSmsOtp $appSignature');

    try {
      final response = await http.get(url);
      if (response.statusCode == 200) {
        logger.i("SMS sent successfully");
        receiveOtp(response, otp);
      } else {
        logger.i("Failed to send SMS: ${response.body}");
      }
    } catch (e) {
      logger.i("Error sending SMS: $e");
    }
  }

  receiveOtp(model,otp) async{
    onNavigateToProfileNumberVerification(otp: otp);
  }

  onNavigateToProfileNumberVerification({String? otp,authmode=0}){
    otpController.clear();
    print('onNavigateToProfileNumberVerification $otp');
    resendOtp = otp;
    Get.to(()=>OTPVerification(otp: resendOtp??'' ,authmode: authmode,logInStatus: loginStatus,));
  }


  otpGenerator(){
    var rng = Random();
    var next = rng.nextDouble() * 1000000;
    while (next < 100000) {
      next *= 10;
    }
    print(next.toInt());
    print("random${next.toInt()}");
    return next.toInt();
  }


  Future<void> getHintPhoneNumber(context) async {
    try {
      final phoneNumber = await SmsAutoFill().hint;
      if (phoneNumber != null) {
        // Remove +91 from the phone number
        String cleanedPhoneNumber = phoneNumber.startsWith('+91')
            ? phoneNumber.substring(3)
            : phoneNumber;

        loginPhoneNumberController.text = cleanedPhoneNumber;
        contactLength = cleanedPhoneNumber;
        // doSomething(context);
        update();

        logger.i("Phone number retrieved: ${loginPhoneNumberController.text}");
      }
    } catch (e) {
      logger.i("Failed to retrieve phone number hint: $e");
    }
  }

}