import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sigap/src/features/daily-ops/data/models/models/officers_model.dart';
import 'package:sigap/src/features/personalization/data/repositories/officers_repository.dart';
import 'package:sigap/src/features/personalization/presentasion/controllers/profile/base_profile_controller.dart';
import 'package:sigap/src/features/personalization/presentasion/controllers/profile/profile_controller.dart';

class OfficerController extends BaseProfileController {
  // Use find to get previously registered repository
  final _officerRepository = Get.find<OfficerRepository>();

  // Observable state variables
  final Rx<OfficerModel?> officer = Rx<OfficerModel?>(null);
  final RxString unitName = ''.obs;
  final RxString patrolUnitName = ''.obs;
  final RxBool isValidOfficer = true.obs; // Track if officer profile is valid
  final RxBool isEditMode = false.obs;

  // Form controllers for edit mode
  late TextEditingController rankController;
  late TextEditingController positionController;
  late TextEditingController nrpController;
  late TextEditingController phoneController;

  // Original officer data for change tracking
  OfficerModel? originalOfficer;

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

    // Initialize text controllers
    rankController = TextEditingController();
    positionController = TextEditingController();
    nrpController = TextEditingController();
    phoneController = TextEditingController();

    loadData();
  }

  @override
  void onClose() {
    rankController.dispose();
    positionController.dispose();
    nrpController.dispose();
    phoneController.dispose();
    super.onClose();
  }

  // Load officer data
  @override
  Future<void> loadData() async {
    await loadOfficerData();
    if (isEditMode.value) {
      _loadOfficerDataToForm();
    }
  }

  // Load officer data
  Future<void> loadOfficerData() async {
    try {
      setLoading(true);

      // Get officer data from profile controller if available
      final profileController = Get.find<ProfileController>();
      if (profileController.officer.value != null) {
        officer.value = profileController.officer.value;
        originalOfficer = profileController.officer.value;
      } else {
        // Fetch officer data directly
        final officerData = await _officerRepository.getOfficerData();
        officer.value = officerData;
        originalOfficer = officerData;
      }

      // Additional metadata could be fetched here, like unit name
      // This would require additional repository methods

      if (officer.value != null) {
        // Example: You might fetch unit name from another repository
        // unitName.value = await _unitsRepository.getUnitName(officer.value!.unitId);
        unitName.value = officer.value?.unitId ?? 'Unknown Unit';
        patrolUnitName.value = officer.value?.patrolUnitId ?? 'No Patrol Unit';
      }

      isValidOfficer.value = _validateOfficerProfile();
    } catch (e) {
      setError('Failed to load officer data: ${e.toString()}');
      isValidOfficer.value = false;
    } finally {
      setLoading(false);
    }
  }

  // Toggle edit mode
  void toggleEditMode() {
    isEditMode.value = !isEditMode.value;
    if (isEditMode.value) {
      _loadOfficerDataToForm();
    } else {
      hasChanges.value = false;
    }
  }

  // Load officer data to form controllers
  void _loadOfficerDataToForm() {
    if (officer.value != null) {
      rankController.text = officer.value!.rank ?? '';
      positionController.text = officer.value!.position ?? '';
      nrpController.text = officer.value!.nrp?.toString() ?? '';
      phoneController.text = officer.value!.phone ?? '';
    }

    // Setup listeners
    _setupTextChangeListeners();
  }

  // Set up listeners to track changes
  void _setupTextChangeListeners() {
    void onTextChanged() {
      checkForChanges();
    }

    rankController.addListener(onTextChanged);
    positionController.addListener(onTextChanged);
    nrpController.addListener(onTextChanged);
    phoneController.addListener(onTextChanged);
  }

  // Check for changes in form fields
  void checkForChanges() {
    if (officer.value == null) {
      hasChanges.value = false;
      return;
    }

    hasChanges.value =
        rankController.text != (officer.value!.rank ?? '') ||
        positionController.text != (officer.value!.position ?? '') ||
        nrpController.text != (officer.value!.nrp?.toString() ?? '') ||
        phoneController.text != (officer.value!.phone ?? '');
  }

  // Validate officer profile has required fields
  bool _validateOfficerProfile() {
    if (officer.value == null) return false;

    // Check required fields
    return officer.value!.nrp != null &&
        officer.value!.name != null &&
        officer.value!.unitId != null;
  }

  // Refresh officer data
  Future<void> refreshOfficerData() async {
    await loadOfficerData();
  }

  // Get officer by ID
  Future<OfficerModel?> getOfficerById(String officerId) async {
    try {
      setLoading(true);
      return await _officerRepository.getOfficerById(officerId);
    } catch (e) {
      setError('Failed to get officer: ${e.toString()}');
      return null;
    } finally {
      setLoading(false);
    }
  }

  // Validate NRP for officers
  String? validateNRP(String? value) {
    if (value == null || value.isEmpty) {
      return 'NRP is required';
    }
    return null;
  }

  // Save officer changes
  @override
  Future<bool> saveChanges() async {
    if (!formKey.currentState!.validate()) {
      return false;
    }

    try {
      setLoading(true);

      if (officer.value != null) {
        dynamic nrpValue = nrpController.text.trim();
        // Try to convert to int if it's a number
        if (int.tryParse(nrpValue) != null) {
          nrpValue = int.parse(nrpValue);
        }

        // Create updated officer model
        final updatedOfficer = officer.value!.copyWith(
          rank: rankController.text.trim(),
          position: positionController.text.trim(),
          nrp: nrpValue,
          phone: phoneController.text.trim(),
        );

        // Save to repository
        final result = await _officerRepository.updateOfficer(updatedOfficer);
        if (result != null) {
          officer.value = result;
          originalOfficer = result;
        }

        await refreshOfficerData();
        showSuccess('Success', 'Officer profile updated successfully');
        hasChanges.value = false;
        isEditMode.value = false;
        return true;
      } else {
        showError('Error', 'No officer profile to update');
        return false;
      }
    } catch (e) {
      setError('Failed to save changes: ${e.toString()}');
      showError(
        'Error',
        'Could not save officer profile changes. ${e.toString()}',
      );
      return false;
    } finally {
      setLoading(false);
    }
  }

  // Discard changes
  @override
  void discardChanges() {
    _loadOfficerDataToForm();
    hasChanges.value = false;
    isEditMode.value = false;
  }
}
