import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_polyline_algorithm/google_polyline_algorithm.dart';
import 'package:sefer_driver/constant/api_key.dart';
import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/constant/links.dart';
import 'package:sefer_driver/controller/functions/crud.dart';
import 'package:sefer_driver/controller/functions/tts.dart';

import '../../../main.dart';

/// Handles map-related logic: fetching routes, drawing polylines, and managing markers.
class NavigationService extends GetxService {
  final CRUD _crud = CRUD();
  final TextToSpeechController _tts = Get.put(TextToSpeechController());

  final RxSet<Marker> markers = <Marker>{}.obs;
  final RxSet<Polyline> polylines = <Polyline>{}.obs;
  final RxString currentInstruction = "".obs;

  BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker;
  BitmapDescriptor passengerIcon = BitmapDescriptor.defaultMarker;
  BitmapDescriptor startIcon = BitmapDescriptor.defaultMarker;
  BitmapDescriptor endIcon = BitmapDescriptor.defaultMarker;

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

  void _loadCustomIcons() async {
    carIcon = await _createBitmapDescriptor('assets/images/car.png');
    passengerIcon = await _createBitmapDescriptor('assets/images/picker.png');
    startIcon = await _createBitmapDescriptor('assets/images/A.png');
    endIcon = await _createBitmapDescriptor('assets/images/b.png');
  }

  Future<BitmapDescriptor> _createBitmapDescriptor(String assetName) {
    return BitmapDescriptor.fromAssetImage(
      ImageConfiguration(
          size: const Size(30, 35), devicePixelRatio: Get.pixelRatio),
      assetName,
    );
  }

  Future<Map<String, dynamic>?> getRoute({
    required LatLng origin,
    required LatLng destination,
  }) async {
    final url =
        '${AppLink.googleMapsLink}directions/json?language=${box.read(BoxName.lang)}&destination=${destination.latitude},${destination.longitude}&origin=${origin.latitude},${origin.longitude}&key=${AK.mapAPIKEY}';

    final response = await _crud.getGoogleApi(link: url, payload: {});

    if (response != null && response['routes'].isNotEmpty) {
      return response['routes'][0];
    }
    return null;
  }

  void drawRoute(Map<String, dynamic> routeData, {Color color = Colors.blue}) {
    final pointsString = routeData["overview_polyline"]["points"];
    final points = decodePolyline(pointsString)
        .map((p) => LatLng(p[0].toDouble(), p[1].toDouble()))
        .toList();

    final polyline = Polyline(
      polylineId: PolylineId(routeData["summary"] ?? DateTime.now().toString()),
      points: points,
      width: 8,
      color: color,
    );

    polylines.add(polyline);
  }

  void updateCarMarker(LatLng position, double heading) {
    markers.removeWhere((m) => m.markerId.value == 'MyLocation');
    markers.add(
      Marker(
        markerId: MarkerId('MyLocation'.tr),
        position: position,
        icon: carIcon,
        rotation: heading,
        anchor: const Offset(0.5, 0.5),
        flat: true,
      ),
    );
  }

  void setInitialMarkers(
      LatLng passengerLocation, LatLng passengerDestination) {
    markers.clear();
    markers.add(Marker(
      markerId: const MarkerId('passengerLocation'),
      position: passengerLocation,
      icon: passengerIcon,
    ));
    markers.add(Marker(
      markerId: const MarkerId('passengerDestination'),
      position: passengerDestination,
      icon: endIcon,
    ));
  }

  void clearRoutes() {
    polylines.clear();
    currentInstruction.value = "";
  }
}
