import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:sigap/src/features/auth/data/models/face_model.dart';
import 'package:sigap/src/features/auth/presentasion/controllers/signup/main/registration_form_controller.dart';
import 'package:sigap/src/features/auth/presentasion/controllers/signup/step/selfie-verification/facial_verification_controller.dart';

class IdentityVerificationController extends GetxController {
  // Singleton instance
  static IdentityVerificationController get instance => Get.find();

  // Main controller reference for accessing centralized data
  late FormRegistrationController mainController;

  // Dependencies
  final bool isOfficer;
  final FacialVerificationService _faceService =
      FacialVerificationService.instance;

  // Form controllers
  final TextEditingController nikController = TextEditingController();
  final TextEditingController nrpController = TextEditingController();
  final TextEditingController fullNameController = TextEditingController();
  final TextEditingController placeOfBirthController = TextEditingController();
  final TextEditingController birthDateController = TextEditingController();
  final TextEditingController addressController = TextEditingController();

  // Form validation errors
  final RxString nikError = RxString('');
  final RxString nrpError = RxString('');
  final RxString fullNameError = RxString('');
  final RxString placeOfBirthError = RxString('');
  final RxString birthDateError = RxString('');
  final RxString genderError = RxString('');
  final RxString addressError = RxString('');

  // ID verification states
  final RxBool isVerifying = RxBool(false);
  final RxBool isVerified = RxBool(false);
  final RxString verificationMessage = RxString('');

  // Face verification states
  final RxBool isVerifyingFace = RxBool(false);
  final RxBool isFaceVerified = RxBool(false);
  final RxString faceVerificationMessage = RxString('');
  final Rx<FaceComparisonResult?> faceComparisonResult =
      Rx<FaceComparisonResult?>(null);

  // UI state variables
  final Rx<String?> selectedGender = Rx<String?>('Male');
  final RxBool isNikReadOnly = RxBool(false);
  final RxBool isNrpReadOnly = RxBool(false);
  final RxBool isFormValid = RxBool(true);
  final RxBool isPreFilledNik = false.obs;

  // Data saving states
  final RxBool isSavingData = RxBool(false);
  final RxBool isDataSaved = RxBool(false);
  final RxString dataSaveMessage = RxString('');

  // Summary data for review page
  final RxMap<String, dynamic> summaryData = RxMap<String, dynamic>({});

  // Storage for extracted data
  final String? extractedIdCardNumber;
  final String? extractedName;

  // Verification status variables (computed from registration data)
  final RxBool isPersonalInfoVerified = RxBool(false);
  final RxBool isIdCardVerified = RxBool(false);
  final RxBool isSelfieVerified = RxBool(false);
  final RxBool isContactInfoVerified = RxBool(false);
  final RxBool isLoadingSummary = RxBool(false);

  IdentityVerificationController({
    this.extractedIdCardNumber = '',
    this.extractedName = '',
    required this.isOfficer,
  });

  @override
  void onInit() {
    super.onInit();

    // Set default gender value
    selectedGender.value = selectedGender.value ?? 'Male';

    // Defer any cross-controller dependencies until after initialization
    Future.microtask(() {
      _initializeAfterDependencies();
    });
  }

  void _initializeAfterDependencies() {
    try {
      // Get main controller for accessing centralized data
      if (Get.isRegistered<FormRegistrationController>()) {
        mainController = Get.find<FormRegistrationController>();

        // Initialize form with data from registration model
        _initializeFormFromRegistrationData();

        // Initialize data
        _initializeData();

        // Listen to registration data changes
        ever(mainController.registrationData, (_) {
          _updateFromRegistrationData();
        });
      }
    } catch (e) {
      Logger().e('Error in identity verification post-initialization: $e');
    }
  }

  // Initialize form with data from centralized registration model
  void _initializeFormFromRegistrationData() {
    final registrationData = mainController.registrationData.value;

    // Get ID card data
    final idCardData = registrationData.idCardVerification;

    if (!isOfficer && idCardData.ktpModel != null) {
      // For citizen - use KTP data
      final ktp = idCardData.ktpModel!;
      nikController.text = ktp.nik;
      fullNameController.text = ktp.name;
      placeOfBirthController.text = ktp.birthPlace;
      birthDateController.text = ktp.birthDate;
      addressController.text = ktp.address;

      // Set gender
      if (ktp.gender.toLowerCase().contains('laki') ||
          ktp.gender.toLowerCase() == 'male') {
        selectedGender.value = 'Male';
      } else if (ktp.gender.toLowerCase().contains('perempuan') ||
          ktp.gender.toLowerCase() == 'female') {
        selectedGender.value = 'Female';
      }

      isNikReadOnly.value = true;
    } else if (isOfficer && idCardData.ktaModel != null) {
      // For officer - use KTA data
      final kta = idCardData.ktaModel!;
      fullNameController.text = kta.name;

      // KTA often has less data, check for extra fields
      if (kta.extraData != null &&
          kta.extraData!.containsKey('tanggal_lahir')) {
        birthDateController.text = kta.extraData!['tanggal_lahir'] ?? '';
      }

      isNrpReadOnly.value = true;
    }

    // Pre-fill with personal info data
    final personalInfo = registrationData.personalInfo;
    if (fullNameController.text.isEmpty) {
      fullNameController.text =
          personalInfo.fullName.isNotEmpty
              ? personalInfo.fullName
              : '${personalInfo.firstName} ${personalInfo.lastName}'.trim();
    }

    if (addressController.text.isEmpty) {
      addressController.text = personalInfo.address;
    }

    // Pre-fill with identity verification data if exists
    final identityData = registrationData.identityVerification;
    if (identityData != null) {
      if (nikController.text.isEmpty) nikController.text = identityData.nik;
      if (fullNameController.text.isEmpty)
        fullNameController.text = identityData.fullName;
      if (placeOfBirthController.text.isEmpty)
        placeOfBirthController.text = identityData.placeOfBirth;
      if (birthDateController.text.isEmpty)
        birthDateController.text = identityData.birthDate;
      if (addressController.text.isEmpty)
        addressController.text = identityData.address;
      if (identityData.gender.isNotEmpty)
        selectedGender.value = identityData.gender;
    }
  }

  // Update form when registration data changes
  void _updateFromRegistrationData() {
    _updateVerificationStatus();
    _buildSummaryData();
  }

  // Initialize all data
  Future<void> _initializeData() async {
    try {
      // Check verification status from registration data
      _updateVerificationStatus();

      // Build summary data
      _buildSummaryData();
    } catch (e) {
      print('Error initializing data: $e');
    }
  }

  // Update verification status from registration data
  void _updateVerificationStatus() {
    final registrationData = mainController.registrationData.value;

    // Personal info verification - check if required fields are filled
    final personalInfo = registrationData.personalInfo;
    isPersonalInfoVerified.value =
        personalInfo.phone.isNotEmpty &&
        (personalInfo.fullName.isNotEmpty ||
            (personalInfo.firstName.isNotEmpty &&
                personalInfo.lastName.isNotEmpty));

    // ID card verification
    final idCardData = registrationData.idCardVerification;
    isIdCardVerified.value = idCardData.isValid && idCardData.isConfirmed;

    // Selfie verification
    final selfieData = registrationData.selfieVerification;
    isSelfieVerified.value =
        selfieData.isSelfieValid &&
        selfieData.isLivenessCheckPassed &&
        selfieData.isMatchWithIDCard &&
        selfieData.isConfirmed;
  }

  // Build summary data from registration model
  void _buildSummaryData() {
    summaryData.clear();

    final registrationData = mainController.registrationData.value;

    // Basic user info
    summaryData['userId'] = registrationData.userId;
    summaryData['email'] = registrationData.email;
    summaryData['roleId'] = registrationData.roleId;
    summaryData['isOfficer'] = registrationData.isOfficer;
    summaryData['profileStatus'] = registrationData.profileStatus;

    // Personal information
    final personalInfo = registrationData.personalInfo;
    summaryData['firstName'] = personalInfo.firstName;
    summaryData['lastName'] = personalInfo.lastName;
    summaryData['fullName'] = personalInfo.fullName;
    summaryData['phone'] = personalInfo.phone;
    summaryData['address'] = personalInfo.address;

    // ID card verification data
    final idCardData = registrationData.idCardVerification;
    summaryData['idCardType'] = isOfficer ? 'KTA' : 'KTP';
    summaryData['idCardValid'] = idCardData.isValid;
    summaryData['idCardConfirmed'] = idCardData.isConfirmed;
    summaryData['idCardImagePath'] = idCardData.imagePath;

    // Add KTP/KTA specific data
    if (!isOfficer && idCardData.ktpModel != null) {
      final ktp = idCardData.ktpModel!;
      summaryData['ktpNik'] = ktp.nik;
      summaryData['ktpName'] = ktp.name;
      summaryData['ktpBirthPlace'] = ktp.birthPlace;
      summaryData['ktpBirthDate'] = ktp.birthDate;
      summaryData['ktpGender'] = ktp.gender;
      summaryData['ktpAddress'] = ktp.address;
    } else if (isOfficer && idCardData.ktaModel != null) {
      final kta = idCardData.ktaModel!;
      summaryData['ktaNrp'] = kta.nrp;
      summaryData['ktaName'] = kta.name;
      summaryData['ktaExtraData'] = kta.extraData;
    }

    // Selfie verification data
    final selfieData = registrationData.selfieVerification;
    summaryData['hasSelfie'] = selfieData.isSelfieValid;
    summaryData['livenessCheckPassed'] = selfieData.isLivenessCheckPassed;
    summaryData['faceMatchResult'] = selfieData.isMatchWithIDCard;
    summaryData['faceMatchConfidence'] = selfieData.matchConfidence;
    summaryData['selfieConfirmed'] = selfieData.isConfirmed;
    summaryData['selfieImagePath'] = selfieData.imagePath;

    // Current form values (identity verification)
    _updateSummaryWithFormData();
  }

  // Validate form inputs
  bool validate(GlobalKey<FormState>? formKey) {
    isFormValid.value = true;
    clearErrors();

    // Validate required fields based on officer status
    if (!isOfficer) {
      // KTP validation
      if (nikController.text.isEmpty) {
        nikError.value = 'NIK is required';
        isFormValid.value = false;
      } else if (nikController.text.length != 16) {
        nikError.value = 'NIK must be 16 digits';
        isFormValid.value = false;
      }

      if (fullNameController.text.isEmpty) {
        fullNameError.value = 'Full name is required';
        isFormValid.value = false;
      }

      if (placeOfBirthController.text.isEmpty) {
        placeOfBirthError.value = 'Place of birth is required';
        isFormValid.value = false;
      }
    } else {
      // KTA validation
      if (fullNameController.text.isEmpty) {
        fullNameError.value = 'Full name is required';
        isFormValid.value = false;
      }
    }

    // Common validations
    if (birthDateController.text.isEmpty) {
      birthDateError.value = 'Birth date is required';
      isFormValid.value = false;
    }

    if (selectedGender.value == null) {
      genderError.value = 'Gender is required';
      isFormValid.value = false;
    }

    // Verify previous steps completion
    bool allPreviousStepsCompleted =
        isPersonalInfoVerified.value &&
        isIdCardVerified.value &&
        isSelfieVerified.value;

    if (!allPreviousStepsCompleted) {
      isFormValid.value = false;
      verificationMessage.value =
          'Please complete all previous steps before submitting';
    }

    // Update summary data with latest form values
    _updateSummaryWithFormData();

    return isFormValid.value;
  }

  // Update summary with current form data
  void _updateSummaryWithFormData() {
    summaryData['nik'] = nikController.text;
    summaryData['nrp'] = nrpController.text;
    summaryData['fullName'] = fullNameController.text;
    summaryData['placeOfBirth'] = placeOfBirthController.text;
    summaryData['birthDate'] = birthDateController.text;
    summaryData['gender'] = selectedGender.value;
    summaryData['address'] = addressController.text;
  }

  // Update extracted data method
  void updateExtractedData(String idNumber, String name) {
    if (idNumber.isNotEmpty && nikController.text.isEmpty) {
      nikController.text = idNumber;
    }
    if (name.isNotEmpty && fullNameController.text.isEmpty) {
      fullNameController.text = name;
    }
    isPreFilledNik.value = true;
  }

  // Clear all validation errors
  void clearErrors() {
    nikError.value = '';
    fullNameError.value = '';
    placeOfBirthError.value = '';
    birthDateError.value = '';
    genderError.value = '';
    addressError.value = '';
    isFormValid.value = true;
  }

  // Prefill form with extracted data
  void prefillExtractedData() {
    if (extractedIdCardNumber != null && extractedIdCardNumber!.isNotEmpty) {
      nikController.text = extractedIdCardNumber!;
    }

    if (extractedName != null && extractedName!.isNotEmpty) {
      fullNameController.text = extractedName!;
    }

    isPreFilledNik.value = true;
  }

  // Verify ID card with registration data
  void verifyIdCardWithOCR() {
    try {
      isVerifying.value = true;

      final registrationData = mainController.registrationData.value;
      final idCardData = registrationData.idCardVerification;

      if (!isOfficer && idCardData.ktpModel != null) {
        final ktpModel = idCardData.ktpModel!;

        bool nikMatches = nikController.text == ktpModel.nik;
        bool nameMatches = _compareNames(
          fullNameController.text,
          ktpModel.name,
        );

        if (nikMatches && nameMatches) {
          isVerified.value = true;
          verificationMessage.value = 'KTP information verified successfully!';
        } else {
          isVerified.value = false;
          verificationMessage.value =
              'Information doesn\'t match with KTP. Please check and try again.';
        }
      } else if (isOfficer && idCardData.ktaModel != null) {
        final ktaModel = idCardData.ktaModel!;

        bool nameMatches = _compareNames(
          fullNameController.text,
          ktaModel.name,
        );

        if (nameMatches) {
          isVerified.value = true;
          verificationMessage.value = 'KTA information verified successfully!';
        } else {
          isVerified.value = false;
          verificationMessage.value =
              'Information doesn\'t match with KTA. Please check and try again.';
        }
      } else {
        isVerified.value = false;
        verificationMessage.value =
            'No ID card data available from previous step.';
      }
    } catch (e) {
      isVerified.value = false;
      verificationMessage.value = 'Error during verification: ${e.toString()}';
      print('Error in ID card verification: $e');
    } finally {
      isVerifying.value = false;
    }
  }

  // Compare names accounting for formatting differences
  bool _compareNames(String name1, String name2) {
    String normalizedName1 = name1.toLowerCase().trim().replaceAll(
      RegExp(r'\s+'),
      ' ',
    );
    String normalizedName2 = name2.toLowerCase().trim().replaceAll(
      RegExp(r'\s+'),
      ' ',
    );

    if (normalizedName1 == normalizedName2) return true;

    if (normalizedName1.contains(normalizedName2) ||
        normalizedName2.contains(normalizedName1))
      return true;

    var parts1 = normalizedName1.split(' ');
    var parts2 = normalizedName2.split(' ');

    int matches = 0;
    for (var part1 in parts1) {
      for (var part2 in parts2) {
        if (part1.length > 2 &&
            part2.length > 2 &&
            (part1.contains(part2) || part2.contains(part1))) {
          matches++;
          break;
        }
      }
    }

    return matches >= (parts1.length / 2).floor();
  }

  // Verify face match using registration data
  void verifyFaceMatch() {
    if (_faceService.skipFaceVerification) {
      // Development mode - use dummy data
      isFaceVerified.value = true;
      faceVerificationMessage.value =
          'Face verification skipped (development mode)';

      final registrationData = mainController.registrationData.value;
      final idCardImagePath = registrationData.idCardVerification.imagePath;
      final selfieImagePath = registrationData.selfieVerification.imagePath;

      if (idCardImagePath != null && selfieImagePath != null) {
        faceComparisonResult.value = FaceComparisonResult(
          sourceFace: FaceModel(
            imagePath: idCardImagePath,
            faceId: 'dummy-id-card-id',
            confidence: 0.95,
            boundingBox: {'x': 0.1, 'y': 0.1, 'width': 0.8, 'height': 0.8},
          ),
          targetFace: FaceModel(
            imagePath: selfieImagePath,
            faceId: 'dummy-selfie-id',
            confidence: 0.95,
            boundingBox: {'x': 0.1, 'y': 0.1, 'width': 0.8, 'height': 0.8},
          ),
          isMatch: true,
          confidence: 0.92,
          similarity: 92.0,
          similarityThreshold: 70.0,
          message: 'Face verification passed (development mode)',
        );
      }
      return;
    }

    isVerifyingFace.value = true;

    final registrationData = mainController.registrationData.value;
    final idCardImagePath = registrationData.idCardVerification.imagePath;
    final selfieImagePath = registrationData.selfieVerification.imagePath;

    if (idCardImagePath == null || selfieImagePath == null) {
      isFaceVerified.value = false;
      faceVerificationMessage.value =
          'Both ID card and selfie are required for face verification.';
      isVerifyingFace.value = false;
      return;
    }

    // Use the face comparison result from selfie verification step
    final selfieData = registrationData.selfieVerification;
    isFaceVerified.value = selfieData.isMatchWithIDCard;
    faceVerificationMessage.value =
        selfieData.isMatchWithIDCard
            ? 'Face verification passed with ${(selfieData.matchConfidence * 100).toStringAsFixed(1)}% confidence'
            : 'Face verification failed. Please retake your selfie.';

    isVerifyingFace.value = false;
  }

  // Save registration data using the centralized model
  void saveRegistrationData() async {
    try {
      // For regular users, call the three required updates
      mainController.updateUserRegistrationData();
    } catch (e) {
      isDataSaved.value = false;
      dataSaveMessage.value = 'Error saving registration data: $e';
      Logger().e('Error saving registration data: $e');
    } finally {
      isSavingData.value = false;
    }
  }

  @override
  void onClose() {
    // Dispose form controllers
    nikController.dispose();
    nrpController.dispose();
    fullNameController.dispose();
    placeOfBirthController.dispose();
    birthDateController.dispose();
    addressController.dispose();
    super.onClose();
  }
}
