import 'dart:developer';

import 'package:easy_localization/easy_localization.dart';
import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';

class ValidationUtils {
  static final DialogService _dialogService = getIt.get<DialogService>();

  static bool isValidatePhoneAndId({String? nationalId, String? phoneNumber}) {
    log("phoneNumber: $phoneNumber");
    log("nationalId: $nationalId");
    if (nationalId == null || nationalId.isEmpty) {
      _dialogService.showErrorBottomSheet(message: LocaleKeys.enterValidNationalId.tr(), onOkPressed: () {});
      return false;
    }

    if (phoneNumber == null || phoneNumber.isEmpty) {
      _dialogService.showErrorBottomSheet(message: LocaleKeys.enterValidPhoneNumber.tr(), onOkPressed: () {});
      return false;
    }
    return true;
  }

  static bool isValidatedId({String? nationalId, required Function() onOkPress, CountryEnum? selectedCountry, bool? isTermsAccepted, String? dob}) {
    bool isCorrectID = true;
    if (nationalId == null || nationalId.isEmpty) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAnationalID.tr(), onOkPressed: onOkPress);
      isCorrectID = false;
    }

    if (nationalId!.length == 10) {
      if (Utils.isSAUDIIDValid(nationalId!) == false) {
        _dialogService.showExceptionBottomSheet(message: LocaleKeys.enterValidNationalId.tr(), onOkPressed: onOkPress);
        isCorrectID = false;
      }
    }

    if (nationalId != null && nationalId.isNotEmpty && selectedCountry != null) {
      if (selectedCountry == CountryEnum.saudiArabia) {
        if (!validateIqama(nationalId)) {
          _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAValidIqamaID.tr(), onOkPressed: onOkPress);
          return false;
        }
      }

      if (selectedCountry == CountryEnum.unitedArabEmirates) {
        if (!validateUaeNationalId(nationalId)) {
          _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAValidNationalID.tr(), onOkPressed: onOkPress);
          return false;
        }
      }

      if (dob == null || dob.isEmpty) {
        _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAValidDateOfBirth.tr(), onOkPressed: onOkPress);
        return false;
      }

      if (isTermsAccepted != null && !isTermsAccepted) {
        _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseAcceptTermsConditions.tr(), onOkPressed: onOkPress);
        return false;
      }
    }
    return isCorrectID;
  }

  static bool isValidatePhone({String? phoneNumber, required Function() onOkPress, CountryEnum? selectedCountry}) {
    if (phoneNumber == null || phoneNumber.isEmpty) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.enterValidPhoneNumber.tr(), onOkPressed: onOkPress);
      return false;
    }

    // Check if "Others" country is selected and phone number starts with restricted codes
    if (selectedCountry == CountryEnum.others) {
      if (phoneNumber.startsWith('00966') || phoneNumber.startsWith('00971')) {
        _dialogService.showExceptionBottomSheet(message: LocaleKeys.cannotEnterSaudiOrUAENumber.tr(), onOkPressed: onOkPress);
        return false;
      }
    }

    return true;
  }

  static bool isValidate({String? phoneNumber, required Function() onOkPress}) {
    if (phoneNumber == null || phoneNumber.isEmpty) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.enterValidPhoneNumber.tr(), onOkPressed: onOkPress);
      return false;
    }
    return true;
  }

  static bool validateIqama(String iqamaNumber) {
    String cleanedIqama = iqamaNumber.replaceAll(RegExp(r'[^0-9]'), '');
    if (cleanedIqama.length != 10) {
      return false;
    }
    int firstDigit = int.parse(cleanedIqama[0]);
    if (firstDigit != 2 && firstDigit != 1) {
      return false;
    }
    int sum = 0;
    for (int i = 0; i < 10; i++) {
      int digit = int.parse(cleanedIqama[i]);
      int weight = (i % 2 == 0) ? 2 : 1; // Alternate weights: 2, 1, 2, 1...
      int product = digit * weight;
      sum += (product > 9) ? product - 9 : product; // Sum digits if product > 9
    }
    return sum % 10 == 0;
  }

  static bool validateUaeNationalId(String id) {
    // Must be exactly 15 digits
    final regex = RegExp(r'^784\d{4}\d{7}\d{1}$');
    return regex.hasMatch(id);
  }

  static bool validateUaeRegistration(
      {String? name, GenderTypeEnum? gender, NationalityCountries? country, MaritalStatusTypeEnum? maritalStatus, required Function() onOkPress}) {
    if (name == null || name.isEmpty) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAValidName.tr(), onOkPressed: onOkPress);
      return false;
    }

    if (gender == null) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseSelectAGender.tr(), onOkPressed: onOkPress);
      return false;
    }

    if (maritalStatus == null) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseSelectAMaritalStatus.tr(), onOkPressed: onOkPress);
      return false;
    }

    if (country == null) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseSelectACountry.tr(), onOkPressed: onOkPress);
      return false;
    }

    return true;
  }

  static bool isValidateEmail({String? email, required Function() onOkPress}) {
    if (email == null || email.isEmpty) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterEmail.tr(), onOkPressed: onOkPress);
      return false;
    }
    final bool emailIsValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}$").hasMatch(email);

    if (!emailIsValid) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAValidEmailFormat.tr(), onOkPressed: onOkPress);
      return false;
    }

    return true;
  }

  static bool isValidatedIdAndPhoneWithCountryValidation(
      {String? nationalId, String? phoneNumber, required Function() onOkPress, CountryEnum? selectedCountry}) {
    bool isCorrectID = true;
    if (nationalId == null || nationalId.isEmpty) {
      _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAnationalID.tr(), onOkPressed: onOkPress);
      isCorrectID = false;
    }

    if (nationalId != null && nationalId.isNotEmpty && selectedCountry != null) {
      if (selectedCountry == CountryEnum.saudiArabia) {
        if (!validateIqama(nationalId)) {
          _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAValidIqamaID.tr(), onOkPressed: onOkPress);
          return false;
        }
      }

      if (selectedCountry == CountryEnum.unitedArabEmirates) {
        if (!validateUaeNationalId(nationalId)) {
          _dialogService.showExceptionBottomSheet(message: LocaleKeys.pleaseEnterAValidNationalID.tr(), onOkPressed: onOkPress);
          return false;
        }
      }

      if (phoneNumber == null || phoneNumber.isEmpty) {
        _dialogService.showExceptionBottomSheet(message: LocaleKeys.enterValidPhoneNumber.tr(), onOkPressed: onOkPress);
        return false;
      }
    }
    return isCorrectID;
  }

  static bool isNullOrEmpty(String? value) {
    return value == null || value.trim().isEmpty;
  }

  static bool validateIban(String iban) {
    final normalized = iban.replaceAll(RegExp(r'\s+'), '').toUpperCase();

    // General IBAN structure: country code + check digits + BBAN
    if (!RegExp(r'^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$').hasMatch(normalized)) {
      return false;
    }

    // IBAN total length must be between 15 and 34 characters
    if (normalized.length < 15 || normalized.length > 34) {
      return false;
    }

    // Move first 4 chars to the end
    final rearranged = normalized.substring(4) + normalized.substring(0, 4);

    // Convert letters to numbers: A=10, B=11, ..., Z=35
    final numeric = rearranged.split('').map((char) {
      final code = char.codeUnitAt(0);
      if (code >= 65 && code <= 90) {
        return (code - 55).toString();
      }
      return char;
    }).join();

    // MOD-97 check without parsing huge integer at once
    int remainder = 0;
    for (final ch in numeric.split('')) {
      remainder = (remainder * 10 + int.parse(ch)) % 97;
    }

    return remainder == 1;
  }
}
