import 'dart:async';

import 'package:flutter/material.dart';
import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_inspection/data/utils/marker_generator.dart';
import 'package:rasadyar_inspection/presentation/filter/view.dart';

class InspectorFilterLogic extends GetxController
    with GetTickerProviderStateMixin {
  Rx<LatLng> currentLocation = LatLng(35.824891, 50.948025).obs;
  RxList<LatLng> allMarkers = <LatLng>[].obs;
  RxList<LatLng> markers = <LatLng>[].obs;
  Timer? _debounceTimer;
  RxBool isLoading = false.obs;

  RxInt filterIndex = 0.obs;
  RxInt showIndex = 0.obs;
  bool showSlideHint = true;

  late Rx<SlidableController> slidController;

  Rx<MapController> mapController = MapController().obs;
  late final AnimatedMapController animatedMapController;

  late DraggableBottomSheetController filterBottomSheetController;
  late DraggableBottomSheetController selectedLocationBottomSheetController;
  late DraggableBottomSheetController detailsLocationBottomSheetController;
  late final BottomSheetManager bottomSheetManager;

  Future<void> determineCurrentPosition() async {
    final position = await Geolocator.getCurrentPosition(
      locationSettings: AndroidSettings(accuracy: LocationAccuracy.best),
    );
    final latLng = LatLng(position.latitude, position.longitude);

    currentLocation.value = latLng;
    markers.add(latLng);
    animatedMapController.animateTo(
      dest: latLng,
      zoom: 18,
      curve: Curves.easeInOut,
      duration: const Duration(seconds: 1),
    );
  }

  void debouncedUpdateVisibleMarkers({required LatLng center}) {
    _debounceTimer?.cancel();
    _debounceTimer = Timer(const Duration(milliseconds: 300), () {
      final filtered = filterNearbyMarkers({
        'markers': allMarkers,
        'centerLat': center.latitude,
        'centerLng': center.longitude,
        'radius': 2000.0,
      });

      markers.addAll(filtered);
    });
  }

  List<LatLng> filterNearbyMarkers(Map<String, dynamic> args) {
    final List<LatLng> rawMarkers = args['markers'];
    final double centerLat = args['centerLat'];
    final double centerLng = args['centerLng'];
    final double radiusInMeters = args['radius'];
    final center = LatLng(centerLat, centerLng);
    final distance = Distance();

    return rawMarkers
        .where((marker) => distance(center, marker) <= radiusInMeters)
        .toList();
  }

  Future<void> generatedMarkers() async {
    final generatedMarkers = await generateLocationsUsingCompute(100000);
    allMarkers.value = generatedMarkers;
  }

  @override
  void onInit() {
    super.onInit();
    animatedMapController = AnimatedMapController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
      curve: Curves.easeInOut,
      cancelPreviousAnimations: true,
    );

    filterBottomSheetController = DraggableBottomSheetController(
      initialHeight: 350,
      minHeight: 200,
      maxHeight: Get.height * 0.5,
    );

    selectedLocationBottomSheetController = DraggableBottomSheetController(
      initialHeight: 200,
      minHeight: 100,
      maxHeight: 200,
    );


    detailsLocationBottomSheetController = DraggableBottomSheetController(
      initialHeight: Get.height * 0.5,
      minHeight: Get.height * 0.37,
      maxHeight: Get.height * 0.5,
    );

    slidController = SlidableController(this).obs;
    bottomSheetManager = BottomSheetManager({
      filterBottomSheetController:
          () => filterWidget(filterIndex: filterIndex, showIndex: showIndex),
      selectedLocationBottomSheetController:
          () => selectedLocationWidget(
            showHint:
                selectedLocationBottomSheetController.isVisible.value &&
                showSlideHint,
            sliderController: slidController.value,
            trigger: triggerSlidableAnimation,
            toggle: selectedLocationBottomSheetController.toggle,
          ),
      detailsLocationBottomSheetController: () => markerDetailsWidget(),
    });
  }

  @override
  void onReady() {
    super.onReady();
    determineCurrentPosition();
    generatedMarkers();
  }

  Future<void> triggerSlidableAnimation() async {
    await Future.delayed(Duration(milliseconds: 200));
    await slidController.value.openEndActionPane();
    await Future.delayed(Duration(milliseconds: 200));
    await slidController.value.close();
    showSlideHint = false;
  }

  @override
  void onClose() {
    slidController.close();
    super.onClose();
  }
}
