import 'dart:convert';
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:get/get.dart';
import 'package:sefer_driver/constant/links.dart';
import 'package:sefer_driver/main.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'dart:math' as math;
import '../../../constant/box_name.dart';
import '../../../print.dart';
import '../../functions/audio_controller.dart';
import '../../functions/crud.dart';
import '../../functions/encrypt_decrypt.dart';
import '../../functions/location_controller.dart';
import 'home_captain_controller.dart';

class OrderRequestController extends GetxController {
  double progress = 0;
  double progressSpeed = 0;
  int duration = 15;
  int durationSpeed = 20;
  int remainingTime = 0;
  int remainingTimeSpeed = 0;
  String countRefuse = '0';
  bool applied = false;
  final locationController = Get.put(LocationController());
  BitmapDescriptor startIcon = BitmapDescriptor.defaultMarker;
  BitmapDescriptor endIcon = BitmapDescriptor.defaultMarker;
  final arguments = Get.arguments;
  var myList;
  late int hours;
  late int minutes;
  GoogleMapController? mapController; // Make it nullable

  @override
  Future<void> onInit() async {
    print('OrderRequestController onInit called');
    await initializeOrderPage();
    if (Platform.isAndroid) {
      bool isOverlayActive = await FlutterOverlayWindow.isActive();
      if (isOverlayActive) {
        await FlutterOverlayWindow.closeOverlay();
      }
    }

    addCustomStartIcon();
    addCustomEndIcon();
    startTimer(
      myList[6].toString(),
      myList[16].toString(),
    );
    update();
    super.onInit();
  }

  late LatLngBounds bounds;
  late List<LatLng> pointsDirection;
  late String body;
  late double latPassengerLocation;
  late double lngPassengerLocation;
  late double lngPassengerDestination;
  late double latPassengerDestination;

  Future<void> initializeOrderPage() async {
    final myListString = Get.arguments['myListString'];
    Log.print('myListString0000: ${myListString}');

    if (Get.arguments['DriverList'] == null ||
        Get.arguments['DriverList'].isEmpty) {
      myList = jsonDecode(myListString);
      Log.print('myList from myListString: ${myList}');
    } else {
      myList = Get.arguments['DriverList'];
      Log.print('myList from DriverList: ${myList}');
    }

    body = Get.arguments['body'];
    Duration durationToAdd =
        Duration(seconds: (double.tryParse(myList[4]) ?? 0).toInt());
    hours = durationToAdd.inHours;
    minutes = (durationToAdd.inMinutes % 60).round();
    startTimerSpeed(myList[6].toString(), body.toString());

    // --- Using the provided logic for initialization ---
    var cords = myList[0].toString().split(',');
    var cordDestination = myList[1].toString().split(',');

    double? parseDouble(String value) {
      try {
        return double.parse(value);
      } catch (e) {
        Log.print("Error parsing value: $value");
        return null; // or handle the error appropriately
      }
    }

    latPassengerLocation = parseDouble(cords[0]) ?? 0.0;
    lngPassengerLocation = parseDouble(cords[1]) ?? 0.0;
    latPassengerDestination = parseDouble(cordDestination[0]) ?? 0.0;
    lngPassengerDestination = parseDouble(cordDestination[1]) ?? 0.0;

    pointsDirection = [
      LatLng(latPassengerLocation, lngPassengerLocation),
      LatLng(latPassengerDestination, lngPassengerDestination)
    ];
    Log.print('pointsDirection: $pointsDirection');

    calculateBounds();
    update();
  }

  void onMapCreated(GoogleMapController controller) {
    mapController = controller;
    animateCameraToBounds();
  }

  void calculateBounds() {
    double minLat = math.min(latPassengerLocation, latPassengerDestination);
    double maxLat = math.max(latPassengerLocation, latPassengerDestination);
    double minLng = math.min(lngPassengerLocation, lngPassengerDestination);
    double maxLng = math.max(lngPassengerLocation, lngPassengerDestination);

    bounds = LatLngBounds(
      southwest: LatLng(minLat, minLng),
      northeast: LatLng(maxLat, maxLng),
    );
    Log.print('Calculated Bounds: $bounds');
  }

  void animateCameraToBounds() {
    if (mapController != null) {
      mapController!.animateCamera(CameraUpdate.newLatLngBounds(bounds, 80.0));
    } else {
      Log.print('mapController is null, cannot animate camera.');
    }
  }

  getRideDEtailsForBackgroundOrder(String rideId) async {
    await CRUD().get(link: AppLink.getRidesDetails, payload: {
      'id': rideId,
    });
  }

  void addCustomStartIcon() async {
    ImageConfiguration config = const ImageConfiguration(size: Size(30, 30));
    BitmapDescriptor.asset(
      config,
      'assets/images/A.png',
    ).then((value) {
      startIcon = value;
      update();
    });
  }

  void addCustomEndIcon() {
    ImageConfiguration config = const ImageConfiguration(size: Size(30, 30));
    BitmapDescriptor.asset(
      config,
      'assets/images/b.png',
    ).then((value) {
      endIcon = value;
      update();
    });
  }

  void changeApplied() {
    applied = true;
    update();
  }

  double mpg = 0;
  calculateConsumptionFuel() {
    mpg = Get.find<HomeCaptainController>().fuelPrice / 12;
  }

  bool _timerActive = false;

  Future<void> startTimer(String driverID, String orderID) async {
    _timerActive = true;
    for (int i = 0; i <= duration && _timerActive; i++) {
      await Future.delayed(const Duration(seconds: 1));
      progress = i / duration;
      remainingTime = duration - i;
      update();
    }
    if (remainingTime == 0 && _timerActive) {
      if (applied == false) {
        endTimer();
        //refuseOrder(orderID);
      }
    }
  }

  void endTimer() {
    _timerActive = false;
  }

  void startTimerSpeed(String driverID, orderID) async {
    for (int i = 0; i <= durationSpeed; i++) {
      await Future.delayed(const Duration(seconds: 1));
      progressSpeed = i / durationSpeed;
      remainingTimeSpeed = durationSpeed - i;
      update();
    }
    if (remainingTimeSpeed == 0) {
      if (applied == false) {
        Get.back();
      }
    }
  }

  addRideToNotificationDriverString(
    orderID,
    String startLocation,
    String endLocation,
    String date,
    String time,
    String price,
    String passengerId,
    String status,
    String carType,
    String passengerRate,
    String priceForPassenger,
    String distance,
    String duration,
  ) async {
    await CRUD().post(link: AppLink.addWaitingRide, payload: {
      'id': (orderID),
      'start_location': startLocation,
      'end_location': endLocation,
      'date': date,
      'time': time,
      'price': price,
      'passenger_id': (passengerId),
      'status': status,
      'carType': carType,
      'passengerRate': passengerRate,
      'price_for_passenger': priceForPassenger,
      'distance': distance,
      'duration': duration,
    });
  }
}
