import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:sigap/src/features/auth/data/models/kta_model.dart';
import 'package:sigap/src/features/auth/data/repositories/authentication_repository.dart';
import 'package:sigap/src/features/daily-ops/data/models/index.dart';
import 'package:sigap/src/features/daily-ops/data/repositories/units_repository.dart';
import 'package:sigap/src/features/personalization/data/models/models/user_metadata_model.dart';
import 'package:sigap/src/features/personalization/data/repositories/officers_repository.dart';
import 'package:sigap/src/features/personalization/data/repositories/users_repository.dart';
import 'package:sigap/src/shared/widgets/state_screeen/state_screen.dart';
import 'package:sigap/src/utils/constants/image_strings.dart';
import 'package:sigap/src/utils/helpers/network_manager.dart';
import 'package:sigap/src/utils/popups/circular_full_screen_loader.dart';
import 'package:sigap/src/utils/popups/loaders.dart';

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

  final RxBool isFormValid = RxBool(true);

  // Data states
  final RxList<UnitModel> availableUnits = <UnitModel>[].obs;
  final RxBool isLoadingUnits = false.obs;
  final RxString selectedUnitName = ''.obs;

  // Controllers for officer info
  final nrpController = TextEditingController();
  final nameController = TextEditingController();
  final rankController = TextEditingController();
  final positionController = TextEditingController();
  final phoneController = TextEditingController();
  final unitIdController = TextEditingController();
  final validUntilController = TextEditingController();

  // New fields based on the model
  final placeOfBirthController = TextEditingController();
  final dateOfBirthController = TextEditingController();

  // Error states
  final RxString nrpError = ''.obs;
  final RxString nameError = ''.obs;
  final RxString rankError = ''.obs;
  final RxString unitIdError = ''.obs;
  final RxString positionError = ''.obs;
  final RxString phoneError = ''.obs;
  final RxString validUntilError = ''.obs;
  final RxString placeOfBirthError = ''.obs;
  final RxString dateOfBirthError = ''.obs;

  // Logger instance
  final Logger logger = Logger();

  // Unit repository
  late final UnitRepository unitRepository;

  // Dropdown open state
  RxBool isUnitDropdownOpen = false.obs;

  // Date selection related
  Rx<DateTime?> selectedValidUntil = Rx<DateTime?>(null);
  Rx<DateTime?> selectedDateOfBirth = Rx<DateTime?>(null);

  // Dark mode reactive state
  final Rx<bool> isDarkMode = false.obs;

  final isDark = Get.isDarkMode;

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

    // Initialize isDarkMode with current value
    _updateThemeMode();

    initRepositories();

    // Fetch units after ensuring repositories are set up
    getAvailableUnits();
  }

  // Update theme mode based on current Get.isDarkMode value
  void _updateThemeMode() {
    // Check the brightness of the current theme
    final brightness = Get.theme.brightness;
    isDarkMode.value = brightness == Brightness.dark;
  }

  // Method to check dark mode that can be called from UI
  bool checkIsDarkMode(BuildContext context) {
    final brightness = Theme.of(context).brightness;
    return brightness == Brightness.dark;
  }

  void initRepositories() {
    // Check if repositories are already registered with GetX
    unitRepository = Get.find<UnitRepository>();
    logger.i('UnitRepository initialized');
  }

  // Fetch available units with improved error handling
  void getAvailableUnits() async {
    logger.i('Starting to fetch available units');

    try {
      isLoadingUnits.value = true;
      availableUnits.clear();

      logger.i('Calling repository.getAllUnits()');
      final units = await unitRepository.getAllUnits();

      logger.i('Received ${units.length} units from repository');
      availableUnits.value = units;

      if (units.isEmpty) {
        logger.w('No units returned from repository');
      } else {
        logger.i('First unit: ${units.first.name}');
      }

      isLoadingUnits.value = false;
    } catch (error) {
      logger.e('Failed to fetch units: $error');
      isLoadingUnits.value = false;
      TLoaders.errorSnackBar(
        title: 'Error',
        message:
            'Something went wrong while fetching units. Please try again later.',
      );
    }
  }

  // Handle unit selection
  void onUnitSelected(UnitModel unit) {
    unitIdController.text = unit.codeUnit;
    selectedUnitName.value = unit.name;
  }

  // Set valid until date
  void setValidUntilDate(DateTime date) {
    selectedValidUntil.value = date;
    validUntilController.text = formatDate(date);
    validUntilError.value = '';
  }

  // Set date of birth
  void setDateOfBirth(DateTime date) {
    selectedDateOfBirth.value = date;
    dateOfBirthController.text = formatDate(date);
    dateOfBirthError.value = '';
  }

  // Format date as yyyy-MM-dd
  String formatDate(DateTime date) {
    return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
  }

  // Populate fields from KTA data
  void populateFromKta(KtaModel ktaData) {
    if (ktaData.nrp.isNotEmpty && nrpController.text.isEmpty) {
      nrpController.text = ktaData.nrp;
    }

    if (ktaData.name.isNotEmpty && nameController.text.isEmpty) {
      nameController.text = ktaData.name;
    }

    if (ktaData.rank?.isNotEmpty == true && rankController.text.isEmpty) {
      rankController.text = ktaData.rank!;
    }

    if (ktaData.position?.isNotEmpty == true &&
        positionController.text.isEmpty) {
      positionController.text = ktaData.position!;
    }
  }

  // Validate the form
  bool validate(GlobalKey<FormState>? formKey) {
    clearErrors();

    bool isValid = formKey?.currentState?.validate() ?? false;

    // Additional validation for required fields
    if (nrpController.text.isEmpty) {
      nrpError.value = 'NRP is required';
      isValid = false;
    }

    if (nameController.text.isEmpty) {
      nameError.value = 'Name is required';
      isValid = false;
    }

    if (rankController.text.isEmpty) {
      rankError.value = 'Rank is required';
      isValid = false;
    }

    if (positionController.text.isEmpty) {
      positionError.value = 'Position is required';
      isValid = false;
    }

    if (phoneController.text.isEmpty) {
      phoneError.value = 'Phone number is required';
      isValid = false;
    } else if (!RegExp(r'^\+?[0-9]{10,15}$').hasMatch(phoneController.text)) {
      phoneError.value = 'Invalid phone number format';
      isValid = false;
    }

    // Date of Birth validation
    if (dateOfBirthController.text.isEmpty) {
      dateOfBirthError.value = 'Date of birth is required';
      isValid = false;
    } else if (selectedDateOfBirth.value == null) {
      dateOfBirthError.value = 'Please select a valid birth date';
      isValid = false;
    }

    // Valid Until validation
    if (validUntilController.text.isEmpty) {
      validUntilError.value = 'Valid until date is required';
      isValid = false;
    } else if (selectedValidUntil.value == null) {
      validUntilError.value = 'Please select a valid date';
      isValid = false;
    }

    if (placeOfBirthController.text.isEmpty) {
      placeOfBirthError.value = 'Place of birth is required';
      isValid = false;
    }

    // Unit selection validation - fixed logic
    if (unitIdController.text.isEmpty) {
      unitIdError.value = 'Please select a unit';
      isValid = false;
    }

    isFormValid.value = isValid;
    return isValid;
  }

  void submitRegistration(
    OfficerInfoController controller,
    // FormRegistrationController mainController,
    GlobalKey<FormState> formKey,
  ) async {
    try {
      // First validate the form before showing the loading dialog
      if (!validate(formKey)) {
        TLoaders.errorSnackBar(
          title: 'Validation Error',
          message: 'Please fix the errors in the form before submitting.',
        );
        return;
      }

      TCircularFullScreenLoader.openLoadingDialog();

      final isConnected = await NetworkManager.instance.isConnected();
      if (!isConnected) {
        TLoaders.errorSnackBar(
          title: 'No Internet Connection',
          message: 'Please check your internet connection and try again.',
        );
        TCircularFullScreenLoader.stopLoading();
        return;
      }

      // No need to validate again, already done above
      final userId = AuthenticationRepository.instance.authUser!.id;

      final roleId =
          AuthenticationRepository.instance.authUser!.userMetadata!['role_id'];

      // Check if the user has a valid role
      if (roleId == null || roleId.isEmpty) {
        TLoaders.errorSnackBar(
          title: 'Role Error',
          message: 'User does not have a valid role assigned.',
        );
        TCircularFullScreenLoader.stopLoading();
        return;
      }

      OfficerModel officer = await OfficerRepository.instance.getOfficerById(
        userId,
      );

      // Convert Map<String, dynamic> to UserMetadataModel

      // Create a new OfficerModel instance with the provided data
      final updateOfficer = officer.copyWith(
        unitId: unitIdController.text.trim(),
        nrp: nrpController.text.trim(),
        name: nameController.text.trim(),
        rank: rankController.text.trim(),
        position: positionController.text.trim(),
        phone: phoneController.text.trim(),
        placeOfBirth: placeOfBirthController.text.trim(),
        dateOfBirth: selectedDateOfBirth.value,
        validUntil: selectedValidUntil.value,
      );

      // Logger().i('Updating officer with data: ${updateOfficer.toJson()}');

      final updatedOfficer = await OfficerRepository.instance.updateOfficer(
        updateOfficer,
      );

      if (updatedOfficer == null) {
        TLoaders.errorSnackBar(
          title: 'Update Failed',
          message: 'Failed to update officer information. Please try again.',
        );
        TCircularFullScreenLoader.stopLoading();
        return;
      }

      await UserRepository.instance.updateProfileStatus('completed');

      // TLoaders.successSnackBar(
      //   title: 'Update Successful',
      //   message: 'Officer information updated successfully.',
      // );

      // resetForm();
      TCircularFullScreenLoader.stopLoading();

      Get.off(
        () => StateScreen(
          title: 'Officer Information Created',
          subtitle: 'Officer information has been successfully created.',
          primaryButtonTitle: 'Back to signin',
          image:
              isDarkMode.value
                  ? TImages.womanHuggingEarthDark
                  : TImages.womanHuggingEarth,
          isSvg: true,
          showButton: true,
          onPressed: () => AuthenticationRepository.instance.screenRedirect(),
        ),
      );
    } catch (e) {
      logger.e('Error updating officer: $e');
      TCircularFullScreenLoader.stopLoading();
      TLoaders.errorSnackBar(
        title: 'Update Failed',
        message: 'An error occurred while updating officer information.',
      );
    }
  }

  void resetForm() {
    nrpController.clear();
    nameController.clear();
    rankController.clear();
    positionController.clear();
    phoneController.clear();
    unitIdController.clear();
    validUntilController.clear();
    placeOfBirthController.clear();
    dateOfBirthController.clear();

    clearErrors();

    selectedUnitName.value = '';
    selectedValidUntil.value = null;
    selectedDateOfBirth.value = null;
  }

  // Clear all error messages
  void clearErrors() {
    nrpError.value = '';
    nameError.value = '';
    rankError.value = '';
    unitIdError.value = '';
    positionError.value = '';
    phoneError.value = '';
    validUntilError.value = '';
    placeOfBirthError.value = '';
    dateOfBirthError.value = '';
  }

  // Clean up resources
  @override
  void onClose() {
    nrpController.dispose();
    nameController.dispose();
    rankController.dispose();
    positionController.dispose();
    phoneController.dispose();
    unitIdController.dispose();
    validUntilController.dispose();
    placeOfBirthController.dispose();
    dateOfBirthController.dispose();
    super.onClose();
  }
}
