import 'dart:async';
import 'dart:convert';
import 'dart:math';

import 'package:Intaleq/constant/colors.dart';
import 'package:Intaleq/controller/auth/login_controller.dart';
import 'package:Intaleq/controller/functions/add_error.dart';
import 'package:Intaleq/controller/functions/encrypt_decrypt.dart';
import 'package:Intaleq/views/home/map_page_passenger.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/constant/style.dart';
import 'package:Intaleq/controller/functions/crud.dart';
import 'package:Intaleq/views/auth/login_page.dart';
import 'package:Intaleq/views/widgets/elevated_btn.dart';

import '../../constant/box_name.dart';
import '../../main.dart';
import '../../print.dart';
import '../../views/auth/verify_email_page.dart';
import '../../views/widgets/mydialoug.dart';
import '../functions/sms_controller.dart';

class RegisterController extends GetxController {
  final formKey = GlobalKey<FormState>();
  final formKey3 = GlobalKey<FormState>();

  TextEditingController firstNameController = TextEditingController();
  TextEditingController lastNameController = TextEditingController();
  TextEditingController emailController = TextEditingController();
  TextEditingController phoneController = TextEditingController();
  TextEditingController passwordController = TextEditingController();
  TextEditingController siteController = TextEditingController();
  // TextEditingController verfyCode = TextEditingController();
  TextEditingController verifyCode = TextEditingController();
  int remainingTime = 300; // 5 minutes in seconds
  bool isSent = false;
  bool isLoading = false;
  Timer? _timer;
  String birthDate = 'Birth Date'.tr;
  String gender = 'Male'.tr;
  @override
  void onInit() {
    super.onInit();
  }

  void startTimer() {
    _timer?.cancel(); // Cancel any existing timer
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (remainingTime > 0) {
        remainingTime--;
      } else {
        timer.cancel();
      }
    });
  }

  getBirthDate() {
    Get.defaultDialog(
        title: 'Select Date'.tr,
        titleStyle: AppStyle.title,
        content: SizedBox(
          width: 300,
          child: CalendarDatePicker(
            initialDate:
                DateTime.now().subtract(const Duration(days: 14 * 365)),
            firstDate: DateTime.parse('1940-06-01'),
            lastDate: DateTime.now().subtract(const Duration(days: 14 * 365)),
            onDateChanged: (date) {
              // Get the selected date and convert it to a DateTime object
              DateTime dateTime = date;
              // Call the getOrders() function from the controller
              birthDate = dateTime.toString().split(' ')[0];
              update();
            },

            // onDateChanged: (DateTime value) {},
          ),
        ),
        confirm: MyElevatedButton(title: 'Ok'.tr, onPressed: () => Get.back()));
  }

  void changeGender(String value) {
    gender = value;
    update();
  }

  bool isValidEgyptianPhoneNumber(String phoneNumber) {
    // Remove any whitespace from the phone number
    phoneNumber = phoneNumber.replaceAll(RegExp(r'\s+'), '');

    // Check if the phone number has exactly 11 digits
    if (phoneNumber.length != 11) {
      return false;
    }

    // Check if the phone number starts with 010, 011, 012, or 015
    RegExp validPrefixes = RegExp(r'^01[0125]\d{8}$');

    return validPrefixes.hasMatch(phoneNumber);
  }

  bool isValidPhoneNumber(String phoneNumber) {
    // Remove any whitespace from the phone number
    phoneNumber = phoneNumber.replaceAll(RegExp(r'\s+'), '');

    // Check if the phone number has at least 10 digits
    if (phoneNumber.length < 10) {
      return false;
    }

    // Check for valid prefixes (modify this to match your use case)
    RegExp validPrefixes = RegExp(r'^[0-9]+$');

    // Check if the phone number contains only digits
    return validPrefixes.hasMatch(phoneNumber);
  }

  sendOtpMessage() async {
    SmsEgyptController smsEgyptController;
    isLoading = true;
    update();
    try {
      // Initialize SmsEgyptController
      smsEgyptController = Get.put(SmsEgyptController());

      isLoading = true;
      update();

      // Get phone number from controller
      String phoneNumber = phoneController.text;

      // Check if the phone number is from Egypt (Assuming Egyptian numbers start with +20)

      if (phoneController.text.isNotEmpty) {
        bool isEgyptianNumber = phoneNumber.startsWith('+20');
        if (isEgyptianNumber && phoneNumber.length == 13) {
          // Check if the phone number is already verified
          var responseChecker = await CRUD().post(
            link: AppLink.checkPhoneNumberISVerfiedPassenger,
            payload: {
              'phone_number': (phoneNumber),
              'email': box.read(BoxName.email),
            },
          );

          if (responseChecker != 'failure') {
            var data = jsonDecode(responseChecker);

            // If the phone number is already verified
            if (data['message'][0]['verified'].toString() == '1') {
              Get.snackbar('Phone number is verified before'.tr, '',
                  backgroundColor: AppColor.greenColor);
              box.write(BoxName.isVerified, '1');
              box.write(BoxName.phone, (phoneNumber));
              Get.offAll(const MapPagePassenger());
            } else {
              await sendOtp(phoneNumber, isEgyptianNumber, smsEgyptController);
            }
          } else {
            await sendOtp(phoneNumber, isEgyptianNumber, smsEgyptController);
          }
        } else if (phoneNumber.length > 9) {
          sendOtp(phoneNumber, isEgyptianNumber, smsEgyptController);
        }
      } else {
        MyDialog().getDialog(
            'Error'.tr, 'Phone number must be exactly 11 digits long'.tr, () {
          Get.back();
        });
        // sendOtp(
        //     phoneNumber, randomNumber, isEgyptianNumber, smsEgyptController);
      }
    } catch (e) {
      // Handle error
    } finally {
      isLoading = false;
      update();
    }
  }

// Helper function to send OTP or WhatsApp message based on phone number location
  Future<void> sendOtp(String phoneNumber, bool isEgyptian,
      SmsEgyptController controller) async {
    // Trim any leading or trailing whitespace from the phone number
    phoneNumber = phoneNumber.trim();
    var dd = await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
      'phone_number': (phoneNumber),
    });
    Log.print('dd: ${dd}');

    // Common Registration Logic (extracted for reuse)
    Future<void> registerUser() async {
      await CRUD().post(link: AppLink.updatePhoneInvalidSMSPassenger, payload: {
        "phone_number": (Get.find<RegisterController>().phoneController.text)
      });

      box.write(BoxName.phone, (phoneController.text));

      var nameParts = (box.read(BoxName.name)).toString().split(' ');
      var firstName = nameParts.isNotEmpty ? nameParts[0] : 'unknown';
      var lastName = nameParts.length > 1 ? nameParts[1] : 'unknown';

      var payload = {
        'id': box.read(BoxName.passengerID),
        'phone': (phoneController.text),
        'email': box.read(BoxName.email),
        'password':
            ('unknown'), //Consider if you *really* want to store 'unknown' passwords
        'gender': ('unknown'),
        'birthdate': ('2002-01-01'),
        'site': box.read(BoxName.passengerPhotoUrl) ?? 'unknown',
        'first_name': (firstName),
        'last_name': (lastName),
      };

      var res1 = await CRUD().post(
        link: AppLink.signUp,
        payload: payload,
      );

      if (res1 != 'failure') {
        //Multi-server signup (moved inside the successful registration check)
        // if (AppLink.IntaleqAlexandriaServer != AppLink.IntaleqSyriaServer) {
        //   List<Future> signUp = [
        //     CRUD().post(
        //       link: '${AppLink.IntaleqAlexandriaServer}/auth/signup.php',
        //       payload: payload,
        //     ),
        //     CRUD().post(
        //       link: '${AppLink.IntaleqGizaServer}/auth/signup.php',
        //       payload: payload,
        //     )
        //   ];
        //   await Future.wait(signUp); // Wait for both sign-ups to complete.
        // }

        box.write(BoxName.isVerified, '1');
        box.write(
            BoxName.isFirstTime, '0'); //Double-check the logic for isFirstTime
        box.write(BoxName.phone, (phoneController.text));

        Get.put(LoginController()).loginUsingCredentials(
          box.read(BoxName.passengerID).toString(),
          box.read(BoxName.email).toString(),
        );
      }
    }

    if (isEgyptian) {
      // verifySMSCode();
      // await registerUser(); // Use the common registration logic
      // await controller.sendSmsEgypt(phoneNumber, otp.toString()); // Optional: Send SMS if Egyptian
    } else if (phoneController.text.toString().length >= 10) {
      await registerUser(); // Use the common registration logic for non-Egyptian users as well.
      // this for whatsapp messsage  // Optional: Send WhatsApp message
      // await CRUD().sendWhatsAppAuth(phoneNumber, otp.toString());
    }

    isLoading = false;
    isSent = true;
    remainingTime = 300;
    update(); // Reset to 5 minutes
    // startTimer(); // Consider whether you need a timer here, or if it's handled elsewhere.
  }

  verifySMSCode() async {
    try {
      if (formKey3.currentState!.validate()) {
        var res = await CRUD().post(link: AppLink.verifyOtpPassenger, payload: {
          'phone_number': phoneController.text,
          'token': verifyCode.text,
        });

        if (res != 'failure') {
          box.write(BoxName.phone, (phoneController.text));
          var nameParts = (box.read(BoxName.name)).toString().split(' ');
          var firstName = nameParts.isNotEmpty ? nameParts[0] : 'unknown';
          var lastName = nameParts.length > 1 ? nameParts[1] : 'unknown';

          var payload = {
            'id': box.read(BoxName.passengerID),
            'phone': (phoneController.text),
            'email': box.read(BoxName.email),
            'password': 'unknown',
            'gender': 'unknown',
            'birthdate': '2002-01-01',
            'site': box.read(BoxName.passengerPhotoUrl) ?? 'unknown',
            'first_name': firstName,
            'last_name': lastName,
          };

          var res1 = await CRUD().post(
            link: AppLink.signUp,
            payload: payload,
          );

          if (res1 != 'failure') {
            // if (AppLink.IntaleqAlexandriaServer != AppLink.IntaleqSyriaServer) {
            //   List<Future> signUp = [
            //     CRUD().post(
            //       link: '${AppLink.IntaleqAlexandriaServer}/auth/signup.php',
            //       payload: payload,
            //     ),
            //     CRUD().post(
            //       link: '${AppLink.IntaleqGizaServer}/auth/signup.php',
            //       payload: payload,
            //     )
            //   ];
            //   await Future.wait(signUp);
            // }

            box.write(BoxName.isVerified, '1');
            box.write(BoxName.isFirstTime, '0');
            box.write(BoxName.phone, (phoneController.text));

            Get.put(LoginController()).loginUsingCredentials(
              box.read(BoxName.passengerID).toString(),
              box.read(BoxName.email).toString(),
            );
          } else {
            Get.snackbar('Error'.tr,
                "The email or phone number is already registered.".tr,
                backgroundColor: Colors.redAccent);
          }
        } else {
          Get.snackbar('Error'.tr, "phone not verified".tr,
              backgroundColor: Colors.redAccent);
        }
      } else {
        Get.snackbar('Error'.tr, "you must insert token code".tr,
            backgroundColor: AppColor.redColor);
      }
    } catch (e) {
      addError(e.toString(), 'passenger sign up ');
      Get.snackbar('Error'.tr, "Something went wrong. Please try again.".tr,
          backgroundColor: Colors.redAccent);
    }
  }

  sendVerifications() async {
    var res = await CRUD().post(link: AppLink.verifyEmail, payload: {
      'email': emailController.text,
      'token': verifyCode.text,
    });
    var dec = jsonDecode(res);
    if (dec['status'] == 'success') {
      Get.offAll(() => LoginPage());
    }
  }

  void register() async {
    if (formKey.currentState!.validate()) {
      var res = await CRUD().post(link: AppLink.signUp, payload: {
        'first_name': firstNameController.text.toString(),
        'last_name': lastNameController.text.toString(),
        'email': emailController.text.toString(),
        'phone': phoneController.text.toString(),
        'password': passwordController.text.toString(),
        'gender': 'yet',
        'site': siteController.text,
        'birthdate': birthDate,
      });
      if (jsonDecode(res)['status'] == 'success') {
        int randomNumber = Random().nextInt(100000) + 1;
        await CRUD().post(link: AppLink.sendVerifyEmail, payload: {
          'email': emailController.text,
          'token': randomNumber.toString(),
        });
        Get.to(() => const VerifyEmailPage());
      }
    }
  }

  @override
  void onClose() {
    _timer?.cancel();
    super.onClose();
  }
}
