import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';

import 'dart:math';
import 'package:http/http.dart' as http;
import 'package:permission_handler/permission_handler.dart';
import 'package:sefer_driver/views/auth/captin/cards/sms_signup.dart';
import 'package:sefer_driver/views/auth/syria/registration_view.dart';
import 'package:sefer_driver/views/widgets/elevated_btn.dart';
import 'package:sefer_driver/views/widgets/error_snakbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:get/get.dart';
import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/constant/links.dart';
import 'package:sefer_driver/controller/functions/crud.dart';
import 'package:sefer_driver/main.dart';
import 'package:sefer_driver/views/home/Captin/home_captain/home_captin.dart';
import 'package:location/location.dart';

import '../../../constant/api_key.dart';
import '../../../constant/info.dart';
import '../../../print.dart';
import '../../../views/auth/captin/otp_page.dart';
import '../../../views/auth/captin/otp_token_page.dart';
import '../../../views/auth/syria/pending_driver_page.dart';
import '../../firebase/firbase_messge.dart';
import '../../firebase/local_notification.dart';
import '../../firebase/notification_service.dart';
import '../../functions/encrypt_decrypt.dart';
import '../../functions/package_info.dart';
import '../../functions/secure_storage.dart';
import '../../functions/security_checks.dart';

class LoginDriverController extends GetxController {
  final formKey = GlobalKey<FormState>();
  TextEditingController emailController = TextEditingController();
  TextEditingController phoneController = TextEditingController();
  TextEditingController passwordController = TextEditingController();
  TextEditingController passwordController2 = TextEditingController();
  bool isAgreeTerms = false;
  bool isGoogleDashOpen = false;
  bool isGoogleLogin = false;
  bool isloading = false;
  late int isTest = 1;
  final FlutterSecureStorage _storage = const FlutterSecureStorage();
  final location = Location();
  void changeAgreeTerm() {
    isAgreeTerms = !isAgreeTerms;
    update();
  }

  bool isPasswordHidden = true;

  void togglePasswordVisibility() {
    isPasswordHidden = !isPasswordHidden;
    update([
      'passwordVisibility'
    ]); // Use a unique ID to only update the password field
  }

  void changeGoogleDashOpen() {
    isGoogleDashOpen = !isGoogleDashOpen;
    update();
  }

  @override
  void onInit() async {
    box.write(BoxName.countryCode, 'Syria');
    // box.write(BoxName.driverID, '34feffd3fa72d6bee56b');
    // await getAppTester();
    getJWT();
    super.onInit();
  }

  getAppTester() async {
    var res = await CRUD().get(
        link: AppLink.getTesterApp,
        payload: {'appPlatform': AppInformation.appName});
    // Log.print('res: ${res}');
    if (res != 'failure') {
      var d = jsonDecode(res);
      isTest = d['message'][0]['isTest'];
      // Log.print('isTest: ${isTest}');
      box.write(BoxName.isTest, isTest);

      // Log.print('isTest: ${box.read(BoxName.isTest)}');
      update();
    } else {
      isTest = 0;
      box.write(BoxName.isTest, isTest);
      update();
      return false;
    }
  }

  updateAppTester(String appPlatform) async {
    await CRUD().post(
        link: AppLink.updateTesterApp, payload: {'appPlatform': appPlatform});
  }

  isPhoneVerified() async {
    var res = await CRUD().post(
        link: AppLink.isPhoneVerified,
        payload: {'phone_number': box.read(BoxName.phoneDriver)});

    if (res != 'failure') {
      // Get.offAll(() => SyrianCardAI());
      Get.offAll(() => RegistrationView());

      // isloading = false;
      // update();
    } else {
      Get.offAll(() => PhoneNumberScreen());
    }
  }

  void saveAgreementTerms() {
    box.write(BoxName.agreeTerms, 'agreed');
    update();
  }

  void saveCountryCode(String countryCode) {
    box.write(BoxName.countryCode, countryCode);
    update();
  }

  String shortHash(String password) {
    var bytes = utf8.encode(password);
    var digest = sha256.convert(bytes);
    return base64UrlEncode(digest.bytes);
  }

  var dev = '';
  getJwtWallet() async {
    if (box.read(BoxName.security_check).toString() != 'passed') {
      Log.print('Security check failed');
      return;
    }
    Log.print('Security check passed');
    String fingerPrint = await DeviceHelper.getDeviceFingerprint();
    dev = Platform.isAndroid ? 'android' : 'ios';
    var payload = {
      'id': box.read(BoxName.driverID),
      'password': AK.passnpassenger,
      'aud': '${AK.allowedWallet}$dev',
      'fingerPrint': fingerPrint
    };
    var response1 = await http.post(
      Uri.parse(AppLink.loginJwtWalletDriver),
      body: payload,
    );
    Log.print('response.request: ${response1.request}');
    Log.print('response.body: ${response1.body}');
    var decoded = jsonDecode(response1.body);
    var jwt = decoded['message'] is Map && decoded['message']['jwt'] != null ? decoded['message']['jwt'] : decoded['jwt'];
    var hmac = decoded['message'] is Map && decoded['message']['hmac'] != null ? decoded['message']['hmac'] : decoded['hmac'];
    Log.print('payment["jwt"]: $jwt');

    await box.write(BoxName.hmac, hmac);
    return jwt.toString();
  }

  getJWT() async {
    await EncryptionHelper.initialize();
    dev = Platform.isAndroid ? 'android' : 'ios';
    Log.print(
        'box.read(BoxName.firstTimeLoadKey): ${box.read(BoxName.firstTimeLoadKey)}');
    if (box.read(BoxName.firstTimeLoadKey).toString() != 'false') {
      var payload = {
        'id': box.read(BoxName.driverID) ?? AK.newId,
        'password': AK.passnpassenger,
        'aud': '${AK.allowed}$dev',
        'fingerPrint': box.read(BoxName.deviceFingerprint) ??
            await DeviceHelper.getDeviceFingerprint(),
      };
      // Log.print('payload: ${payload}');

      var response0 = await http.post(
        Uri.parse(AppLink.loginFirstTimeDriver),
        body: payload,
      );
      Log.print('response0: ${response0.body}');
      Log.print('request: ${response0.request}');
      if (response0.statusCode == 200) {
        final decodedResponse1 = jsonDecode(response0.body);
        Log.print('decodedResponse1: ${decodedResponse1}');

        String? jwt;
        if (decodedResponse1['message'] is Map && decodedResponse1['message']['jwt'] != null) {
          jwt = decodedResponse1['message']['jwt'];
        } else {
          jwt = decodedResponse1['jwt'];
        }
        
        if (jwt != null) {
          box.write(BoxName.jwt, c(jwt));
        }

        // ✅ بعد التأكد أن كل المفاتيح موجودة
        await EncryptionHelper.initialize();

        // await AppInitializer().getKey();
      } else {}
    } else {
      await EncryptionHelper.initialize();

      var payload = {
        'id': box.read(BoxName.driverID),
        'password': box.read(BoxName.emailDriver),
        'aud': '${AK.allowed}$dev',
        'fingerPrint': box.read(BoxName.deviceFingerprint) ??
            await DeviceHelper.getDeviceFingerprint(),
      };
      // print(payload);
      var response1 = await http.post(
        Uri.parse(AppLink.loginJwtDriver),
        body: payload,
      );
      Log.print('response1.request: ${response1.request}');
      Log.print('response1.body: ${response1.body}');

      if (response1.statusCode == 200) {
        final decodedResponse1 = jsonDecode(response1.body);
        // Log.print('decodedResponse1: ${decodedResponse1}');

        String? jwt;
        if (decodedResponse1['message'] is Map && decodedResponse1['message']['jwt'] != null) {
          jwt = decodedResponse1['message']['jwt'];
        } else {
          jwt = decodedResponse1['jwt'];
        }
        
        if (jwt != null) {
          await box.write(BoxName.jwt, c(jwt));
        }

        // await AppInitializer().getKey();
      }
    }
  }

  Future<void> getLocationPermission() async {
    var status = await Permission.locationAlways.status;
    if (!status.isGranted) {
      await Permission.locationAlways.request();
    }
    update();
  }

  String generateUniqueIdFromEmail(String email) {
    // Step 1: Extract the local part of the email
    String localPart = email.split('@')[0];

    // Step 2: Replace invalid characters (if any)
    String cleanLocalPart = localPart.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '');

    // Step 3: Ensure it does not exceed 24 characters
    if (cleanLocalPart.length > 24) {
      cleanLocalPart = cleanLocalPart.substring(0, 24);
    }

    // Step 4: Generate a random suffix if needed
    String suffix = generateRandomSuffix(24 - cleanLocalPart.length);

    return cleanLocalPart + suffix;
  }

  String generateRandomSuffix(int length) {
    const String chars =
        'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    Random random = Random();
    return List.generate(length, (index) => chars[random.nextInt(chars.length)])
        .join('');
  }

  bool isInviteDriverFound = false;

  Future updateInvitationCodeFromRegister() async {
    var res = await CRUD().post(
      link: AppLink.updateDriverInvitationDirectly,
      payload: {
        "inviterDriverPhone": box.read(BoxName.phoneDriver).toString(),
      },
    );
    Log.print('invite: ${res}');

    // حماية من النوع — res قد يكون String ('failure'/'token_expired') بدل Map
    if (res is! Map) return;

    if (res['status'] != 'failure') {
      isInviteDriverFound = true;
      update();
      box.write(BoxName.isInstall, '1');
      NotificationController().showNotification(
          "Code approved".tr, "Code approved".tr, 'tone2', '');

      try {
        NotificationService.sendNotification(
          target: (res)['message'][0]['token'].toString(),
          title: 'You have received a gift token!'.tr,
          body: 'for '.tr + box.read(BoxName.phoneDriver).toString(),
          isTopic: false,
          tone: 'tone2',
          driverList: [], category: 'You have received a gift token!',
        );
      } catch (e) {
        Log.print('invite notification error: $e');
      }
    }
  }

  loginWithGoogleCredential(String driverID, email) async {
    isloading = true;
    update();
    // await SecurityHelper.performSecurityChecks();
    // Log.print('(BoxName.emailDriver): ${box.read(BoxName.emailDriver)}');
    // await getJWT();
    var res = await CRUD().get(link: AppLink.loginFromGoogleCaptin, payload: {
      // 'email': email ?? 'yet',
      'id': driverID,
    });
    Log.print('loginWithGoogleCredential: ${res}');
    if (res == 'failure') {
      await isPhoneVerified();
      isloading = false; // <--- أضفت هذا أيضاً
      update();
      return false;
      // Get.snackbar('Failure', '', backgroundColor: Colors.red);
    } else {
      var jsonDecoeded = jsonDecode(res);
      var d = jsonDecoeded['data'][0];
      if (jsonDecoeded.isNotEmpty) {
        if (jsonDecoeded['status'] == 'success' &&
            d['is_verified'].toString() == '1') {
          box.write(BoxName.emailDriver, d['email']);
          box.write(BoxName.firstTimeLoadKey, 'false');
          box.write(BoxName.driverID, (d['id']));
          box.write(BoxName.isTest, '1');
          box.write(BoxName.gender, (d['gender']));
          box.write(BoxName.phoneVerified, d['is_verified'].toString());
          box.write(BoxName.phoneDriver, (d['phone']));
          box.write(BoxName.is_claimed, d['is_claimed']);
          box.write(BoxName.isInstall, d['isInstall']);
          // box.write(
          // BoxName.isGiftToken, d['isGiftToken']);
          box.write(BoxName.nameArabic, (d['name_arabic']));
          box.write(BoxName.carYear, d['year']);
          box.write(BoxName.bankCodeDriver, (d['bankCode']));
          box.write(BoxName.accountBankNumberDriver, (d['accountBank']));
          box.write(
              BoxName.nameDriver,
              '${(d['first_name'])}'
              ' ${(d['last_name'])}');
          if (((d['model']).toString().contains('دراجه') ||
              d['make'].toString().contains('دراجه '))) {
            if ((d['gender']).toString() == 'Male') {
              box.write(BoxName.carTypeOfDriver, 'Scooter');
            } else {
              box.write(BoxName.carTypeOfDriver, 'Pink Bike');
            }
          } else if (int.parse(d['year'].toString()) > 2016) {
            if (d['gender'].toString() != 'Male') {
              box.write(BoxName.carTypeOfDriver, 'Lady');
            } else {
              box.write(BoxName.carTypeOfDriver, 'Comfort');
            }
          } else if (int.parse(d['year'].toString()) > 2002 &&
              int.parse(d['year'].toString()) < 2016) {
            box.write(BoxName.carTypeOfDriver, 'Speed');
          } else if (int.parse(d['year'].toString()) < 2002) {
            box.write(BoxName.carTypeOfDriver, 'Awfar Car');
          }

          // ✅ الحصول على توكن access بدل registration قبل أي طلبات بعد تسجيل الدخول
          Log.print('🔑 Getting access token after login...');
          await getJWT();
          Log.print('🔑 Access token obtained.');

// add invitations
          if (box.read(BoxName.isInstall) == null ||
              box.read(BoxName.isInstall).toString() == '0') {
            updateInvitationCodeFromRegister();
          }

          // updateAppTester(AppInformation.appName);
          if (d['status'].toString() != 'yet') {
            var token = await CRUD().get(
                link: AppLink.getDriverToken,
                payload: {
                  'captain_id': (box.read(BoxName.driverID)).toString()
                });

            String fingerPrint = await DeviceHelper.getDeviceFingerprint();
            await storage.write(
                key: BoxName.fingerPrint, value: fingerPrint.toString());
            // print(jsonDecode(token)['data'][0]['token'].toString());
            // print(box.read(BoxName.tokenDriver).toString());
            // if (box.read(BoxName.emailDriver).toString() !=
            //     '963992952235@intaleqapp.com') {
            if (token != 'failure') {
              var serverData = jsonDecode(token);
              if ((serverData['data'][0]['token'].toString()) !=
                      box.read(BoxName.tokenDriver).toString() ||
                  serverData['data'][0]['fingerPrint'].toString() !=
                      fingerPrint.toString()) {
                Get.defaultDialog(
                  barrierDismissible: false,
                  title: 'Device Change Detected'.tr,
                  middleText: 'Please verify your identity'.tr,
                  textConfirm: 'Verify'.tr,
                  confirmTextColor: Colors.white,
                  onConfirm: () {
                    // نغلق الـ Dialog أولاً بشكل صريح
                    if (Get.isDialogOpen ?? false) {
                      Get.back();
                    }

                    // ثم ننتقل لصفحة OTP
                    Get.offAll(
                      () => OtpVerificationPage(
                        phone: d['phone'].toString(),
                        deviceToken: fingerPrint.toString(),
                        token: token.toString(),
                        ptoken:
                            jsonDecode(token)['data'][0]['token'].toString(),
                      ),
                    );
                  },
                );
                isloading = false;
                update();
                return true; // نخرج من الدالة هنا لنسمح لـ OTP بالتعامل مع الأمر
              }
              // }
            }

            Get.offAll(() => HomeCaptain()); // افترض أن هذا الكلاس موجود
            isloading = false; // <--- أضفت هذا
            update(); // <--- أضفت هذا
            return true;
          } else {
            Get.offAll(
                () => DriverVerificationScreen()); // افترض أن هذا الكلاس موجود
            isloading = false; // <--- أضفت هذا
            update(); // <--- أضفت هذا
            return false;
          }

          // Get.off(() => HomeCaptain());
        } else {
          Get.offAll(() => PhoneNumberScreen());
          isloading = false;
          update();
          return false; // <--- ✅ وهذا السطر موجود للحالات الأخرى
        }
      } else {
        mySnackbarSuccess('');

        isloading = false;
        update();
      }
    }
  }

  logintest(String driverID, email) async {
    isloading = true;
    update();
    // await SecurityHelper.performSecurityChecks();
    // Log.print('(BoxName.emailDriver): ${box.read(BoxName.emailDriver)}');

    var res = await CRUD().get(link: AppLink.loginFromGoogleCaptin, payload: {
      'email': email ?? 'yet',
      'id': driverID,
    });

    // print('res is $res');
    // if (res == 'failure') {
    //   await isPhoneVerified();
    //   // Get.snackbar('Failure', '', backgroundColor: Colors.red);
    // } else
    // {
    var jsonDecoeded = jsonDecode(res);
    var d = jsonDecoeded['data'][0];
    if (jsonDecoeded.isNotEmpty) {
      if (jsonDecoeded['status'] == 'success')
      //  &&
      // d['is_verified'].toString() == '1')
      {
        box.write(BoxName.emailDriver, d['email']);
        box.write(BoxName.firstTimeLoadKey, 'false');
        box.write(BoxName.driverID, (d['id']));
        box.write(BoxName.isTest, '1');
        box.write(BoxName.gender, (d['gender']));
        box.write(BoxName.phoneVerified, d['is_verified'].toString());
        box.write(BoxName.phoneDriver, (d['phone']));
        box.write(BoxName.is_claimed, d['is_claimed']);
        box.write(BoxName.isInstall, d['isInstall']);
        // box.write(
        // BoxName.isGiftToken, d['isGiftToken']);
        box.write(BoxName.nameArabic, (d['name_arabic']));
        box.write(BoxName.carYear, d['year']);
        box.write(BoxName.bankCodeDriver, (d['bankCode']));
        box.write(BoxName.accountBankNumberDriver, (d['accountBank']));
        box.write(
            BoxName.nameDriver,
            '${(d['first_name'])}'
            ' ${(d['last_name'])}');
        if (((d['model']).toString().contains('دراجه') ||
            d['make'].toString().contains('دراجه '))) {
          if ((d['gender']).toString() == 'Male') {
            box.write(BoxName.carTypeOfDriver, 'Scooter');
          } else {
            box.write(BoxName.carTypeOfDriver, 'Pink Bike');
          }
        } else if (int.parse(d['year'].toString()) > 2016) {
          if (d['gender'].toString() != 'Male') {
            box.write(BoxName.carTypeOfDriver, 'Lady');
          } else {
            box.write(BoxName.carTypeOfDriver, 'Comfort');
          }
        } else if (int.parse(d['year'].toString()) > 2002 &&
            int.parse(d['year'].toString()) < 2016) {
          box.write(BoxName.carTypeOfDriver, 'Speed');
        } else if (int.parse(d['year'].toString()) < 2002) {
          box.write(BoxName.carTypeOfDriver, 'Awfar Car');
        }
        // updateAppTester(AppInformation.appName);

        // var token = await CRUD().get(
        //     link: AppLink.getDriverToken,
        //     payload: {'captain_id': (box.read(BoxName.driverID)).toString()});

        // String fingerPrint = await DeviceHelper.getDeviceFingerprint();
        // await storage.write(
        //     key: BoxName.fingerPrint, value: fingerPrint.toString());

        Get.off(() => HomeCaptain());
        // } else {
        //   Get.offAll(() => PhoneNumberScreen());

        //   isloading = false;
        //   update();
        // }
        // }
        // else {
        //   mySnackbarSuccess('');

        //   isloading = false;
        //   update();
      }
    }
  }

  loginUsingCredentialsWithoutGoogle(String password, email) async {
    isloading = true;
    isGoogleLogin = true;
    update();
    var res = await CRUD()
        .get(link: AppLink.loginUsingCredentialsWithoutGoogle, payload: {
      'email': (email),
      'password': password,
    });
    box.write(BoxName.emailDriver, (email).toString());
    // print(res);
    if (res == 'failure') {
      //Failure
      if (box.read(BoxName.phoneVerified).toString() == '1') {
        // Get.offAll(() => SyrianCardAI());
        Get.offAll(() => RegistrationView());
      } else {
        Get.offAll(() => SmsSignupEgypt());
      }

      isloading = false;
      update();
    } else {
      var jsonDecoeded = jsonDecode(res);
      var d = jsonDecoeded['data'][0];
      if (jsonDecoeded.isNotEmpty) {
        if (jsonDecoeded['status'] == 'success' &&
            d['is_verified'].toString() == '1') {
          box.write(BoxName.emailDriver, (d['email']));
          box.write(BoxName.driverID, (d['id']));
          box.write(BoxName.isTest, '1');
          box.write(BoxName.gender, (d['gender']));
          box.write(BoxName.phoneVerified, d['is_verified'].toString());
          box.write(BoxName.phoneDriver, (d['phone']));
          box.write(BoxName.nameArabic, (d['name_arabic']));
          box.write(BoxName.bankCodeDriver, (d['bankCode']));
          box.write(BoxName.accountBankNumberDriver, d['accountBank']);
          box.write(
              BoxName.nameDriver,
              '${(d['first_name'])}'
              ' ${(d['last_name'])}');
          if ((d['model'].toString().contains('دراجه') ||
              d['make'].toString().contains('دراجه '))) {
            if ((d['gender']).toString() == 'Male') {
              box.write(BoxName.carTypeOfDriver, 'Scooter');
            } else {
              box.write(BoxName.carTypeOfDriver, 'Pink Bike');
            }
          } else if (int.parse(d['year'].toString()) > 2017) {
            if ((d['gender']).toString() != 'Male') {
              box.write(BoxName.carTypeOfDriver, 'Lady');
            } else {
              box.write(BoxName.carTypeOfDriver, 'Comfort');
            }
          } else if (int.parse(d['year'].toString()) > 2002 &&
              int.parse(d['year'].toString()) < 2017) {
            box.write(BoxName.carTypeOfDriver, 'Speed');
          } else if (int.parse(d['year'].toString()) < 2002) {
            box.write(BoxName.carTypeOfDriver, 'Awfar Car');
          }
          updateAppTester(AppInformation.appName);

          var fingerPrint = await DeviceHelper.getDeviceFingerprint();
          await storage.write(key: BoxName.fingerPrint, value: fingerPrint);

          var token = await CRUD().get(
              link: AppLink.getDriverToken,
              payload: {'captain_id': box.read(BoxName.driverID).toString()});

          if (token != 'failure') {
            if ((jsonDecode(token)['data'][0]['token']) !=
                (box.read(BoxName.tokenDriver))) {
              // Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP(
              //     'token change'.tr,
              //     'change device'.tr,
              //     (jsonDecode(token)['data'][0]['token']).toString(),
              //     [],
              //     'ding.wav');
              NotificationService.sendNotification(
                target: (jsonDecode(token)['data'][0]['token']).toString(),
                title: 'token change'.tr,
                body: 'token change'.tr,
                isTopic: false, // Important: this is a token
                tone: 'cancel',
                driverList: [], category: 'token change',
              );
              Get.defaultDialog(
                  title: 'you will use this device?'.tr,
                  middleText: '',
                  confirm: MyElevatedButton(
                      title: 'Ok'.tr,
                      onPressed: () async {
                        await CRUD()
                            .post(link: AppLink.addTokensDriver, payload: {
                          'token': box.read(BoxName.tokenDriver),
                          'captain_id': box.read(BoxName.driverID).toString(),
                          'fingerPrint': (fingerPrint).toString()
                        });

                        Get.back();
                      }));
            }
          }

          Get.off(() => HomeCaptain());
          // Get.off(() => LoginCaptin());
        } else {
          Get.offAll(() => SmsSignupEgypt());

          isloading = false;
          update();
        }
      } else {
        mySnackeBarError('');

        isloading = false;
        update();
      }
    }
  }

  void loginByBoxData() async {
    Get.to(() => HomeCaptain());
    await CRUD().post(link: AppLink.addTokensDriver, payload: {
      'token': box.read(BoxName.tokenDriver).toString(),
      'captain_id': box.read(BoxName.driverID).toString()
    });
    CRUD().post(
        link: "${AppLink.seferAlexandriaServer}/ride/firebase/addDriver.php",
        payload: {
          'token': box.read(BoxName.tokenDriver),
          'captain_id': box.read(BoxName.driverID).toString()
        });
    CRUD().post(
        link: "${AppLink.seferGizaServer}/ride/firebase/addDriver.php",
        payload: {
          'token': box.read(BoxName.tokenDriver),
          'captain_id': box.read(BoxName.driverID).toString()
        });
  }
}
