import 'package:get/get.dart';
import 'package:on_field_work/helpers/services/app_logger.dart';
import 'package:on_field_work/helpers/services/api_service.dart';
import 'package:on_field_work/model/employees/employee_model.dart';
import 'package:on_field_work/model/employees/employee_details_model.dart';

class EmployeesScreenController extends GetxController {
  /// ✅ Data lists
  RxList<EmployeeModel> employees = <EmployeeModel>[].obs;
  Rxn<EmployeeDetailsModel> selectedEmployeeDetails =
      Rxn<EmployeeDetailsModel>();

  /// ✅ Loading states
  RxBool isLoading = false.obs;
  RxBool isLoadingEmployeeDetails = false.obs;

  /// ✅ Selection state
  RxBool isAllEmployeeSelected = false.obs;
  RxSet<String> selectedEmployeeIds = <String>{}.obs;

  /// ✅ Upload state tracking (if needed later)
  RxMap<String, RxBool> uploadingStates = <String, RxBool>{}.obs;

  RxList<EmployeeModel> selectedEmployeePrimaryManagers = <EmployeeModel>[].obs;
  RxList<EmployeeModel> selectedEmployeeSecondaryManagers =
      <EmployeeModel>[].obs;

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

  /// 🔹 Fetch all employees (no project filter)
  Future<void> fetchAllEmployees({String? organizationId}) async {
    isLoading.value = true;
    update(['employee_screen_controller']);

    await _handleApiCall(
      () => ApiService.getAllEmployees(organizationId: organizationId),
      onSuccess: (data) {
        employees.assignAll(data.map((json) => EmployeeModel.fromJson(json)));
        logSafe(
          "All Employees fetched: ${employees.length} employees loaded.",
          level: LogLevel.info,
        );

        // Reset selection states when new data arrives
        selectedEmployeeIds.clear();
        isAllEmployeeSelected.value = false;
      },
      onEmpty: () {
        employees.clear();
        selectedEmployeeIds.clear();
        isAllEmployeeSelected.value = false;
        logSafe("No Employee data found or API call failed",
            level: LogLevel.warning);
      },
    );

    isLoading.value = false;
    update(['employee_screen_controller']);
  }

  /// 🔹 Fetch details for a specific employee
  Future<void> fetchEmployeeDetails(String? employeeId) async {
    if (employeeId == null || employeeId.isEmpty) return;

    isLoadingEmployeeDetails.value = true;

    await _handleSingleApiCall(
      () => ApiService.getEmployeeDetails(employeeId),
      onSuccess: (data) {
        selectedEmployeeDetails.value = EmployeeDetailsModel.fromJson(data);
        logSafe("Employee details loaded for $employeeId",
            level: LogLevel.info);
      },
      onEmpty: () {
        selectedEmployeeDetails.value = null;
        logSafe("No employee details found for $employeeId",
            level: LogLevel.warning);
      },
      onError: (e) {
        selectedEmployeeDetails.value = null;
        logSafe("Error fetching employee details for $employeeId",
            level: LogLevel.error, error: e);
      },
    );

    isLoadingEmployeeDetails.value = false;
  }

  /// Fetch reporting managers for a specific employee from /organization/hierarchy/list/:employeeId
  Future<void> fetchReportingManagers(String? employeeId) async {
    if (employeeId == null || employeeId.isEmpty) return;

    try {
      // ✅ Always clear before new fetch (to avoid mixing old data)
      selectedEmployeePrimaryManagers.clear();
      selectedEmployeeSecondaryManagers.clear();

      // Fetch from existing API helper
      final data = await ApiService.getOrganizationHierarchyList(employeeId);

      if (data == null || data.isEmpty) {
        update(['employee_screen_controller']);
        return;
      }

      for (final item in data) {
        try {
          final reportTo = item['reportTo'];
          if (reportTo == null) continue;

          final emp = EmployeeModel.fromJson(reportTo);
          final isPrimary = item['isPrimary'] == true;

          if (isPrimary) {
            if (!selectedEmployeePrimaryManagers.any((e) => e.id == emp.id)) {
              selectedEmployeePrimaryManagers.add(emp);
            }
          } else {
            if (!selectedEmployeeSecondaryManagers.any((e) => e.id == emp.id)) {
              selectedEmployeeSecondaryManagers.add(emp);
            }
          }
        } catch (_) {
          // ignore malformed items
        }
      }

      update(['employee_screen_controller']);
    } catch (e) {
      logSafe("Error fetching reporting managers for $employeeId",
          level: LogLevel.error, error: e);
    }
  }

  /// 🔹 Clear all employee data
  void clearEmployees() {
    employees.clear();
    selectedEmployeeIds.clear();
    isAllEmployeeSelected.value = false;
    logSafe("Employees cleared", level: LogLevel.info);
    update(['employee_screen_controller']);
  }

  /// 🔹 Generic handler for list API responses
  Future<void> _handleApiCall(
    Future<List<dynamic>?> Function() apiCall, {
    required Function(List<dynamic>) onSuccess,
    required Function() onEmpty,
    Function(dynamic error)? onError,
  }) async {
    try {
      final response = await apiCall();
      if (response != null && response.isNotEmpty) {
        onSuccess(response);
      } else {
        onEmpty();
      }
    } catch (e) {
      if (onError != null) {
        onError(e);
      } else {
        logSafe("API call error", level: LogLevel.error, error: e);
      }
    }
  }

  /// 🔹 Generic handler for single-object API responses
  Future<void> _handleSingleApiCall(
    Future<Map<String, dynamic>?> Function() apiCall, {
    required Function(Map<String, dynamic>) onSuccess,
    required Function() onEmpty,
    Function(dynamic error)? onError,
  }) async {
    try {
      final response = await apiCall();
      if (response != null && response.isNotEmpty) {
        onSuccess(response);
      } else {
        onEmpty();
      }
    } catch (e) {
      if (onError != null) {
        onError(e);
      } else {
        logSafe("API call error", level: LogLevel.error, error: e);
      }
    }
  }
}
