import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/home/captin/map_driver_controller.dart';
import 'dart:async';

import '../../../constant/links.dart';
import '../../../constant/style.dart';
import '../../../constant/table_names.dart';
import '../../../main.dart';
import '../../../views/home/my_wallet/walet_captain.dart';
import '../../../views/widgets/elevated_btn.dart';
import '../../functions/crud.dart';
import '../../functions/location_background_controller.dart';
import '../../functions/location_controller.dart';
import '../payment/captain_wallet_controller.dart';

class HomeCaptainController extends GetxController {
  bool isActive = false;
  DateTime? activeStartTime;
  Duration activeDuration = Duration.zero;
  Timer? activeTimer;
  Map data = {};
  bool isLoading = true;
  late double kazan;
  double latePrice = 0;
  double heavyPrice = 0;
  double comfortPrice = 0,
      speedPrice = 0,
      deliveryPrice = 0,
      mashwariPrice = 0,
      fuelPrice = 0;
  double naturePrice = 0;
  bool isCallOn = false;
  String totalMoneyToday = '0';
  double? rating = 5;
  String rideId = '0';
  String countRideToday = '0';
  String totalMoneyInSEFER = '0';
  String totalDurationToday = '0';
  Timer? timer;
  late LatLng myLocation = const LatLng(32, 36);
  String totalPoints = '0';
  String countRefuse = '0';
  bool mapType = false;
  bool mapTrafficON = false;
  double widthMapTypeAndTraffic = 50;
// Inject the LocationController class
  final locationController = Get.put(LocationController());
  // final locationBackController = Get.put(LocationBackgroundController());
  String formatDuration(Duration duration) {
    String twoDigits(int n) => n.toString().padLeft(2, "0");
    String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
    String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
    return "${duration.inHours}:$twoDigitMinutes:$twoDigitSeconds";
  }

  void goToWalletFromConnect() {
    Get.back();
    Get.back();
    Get.to(() => WalletCaptain());
  }

  void changeRideId() {
    rideId = 'rideId';
    update();
  }

  String stringActiveDuration = '';
  void onButtonSelected() {
    // totalPoints = Get.find<CaptainWalletController>().totalPoints;

    isActive = !isActive;
    if (isActive) {
      if (double.parse(totalPoints) > -300) {
        locationController.startLocationUpdates();
        // locationBackController.startBackLocation();
        activeStartTime = DateTime.now();
        activeTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
          activeDuration = DateTime.now().difference(activeStartTime!);
          stringActiveDuration = formatDuration(activeDuration);
          update();
        });
      } else {
        locationController.stopLocationUpdates();

        activeStartTime = null;
        activeTimer?.cancel();
        savePeriod(activeDuration);
        activeDuration = Duration.zero;
        update();
      }
    } else {
      locationController.stopLocationUpdates();

      activeStartTime = null;
      activeTimer?.cancel();
      savePeriod(activeDuration);
      activeDuration = Duration.zero;
      update();
    }
    // }
  }

  void getRefusedOrderByCaptain() async {
    DateTime today = DateTime.now();
    int todayDay = today.day;

    String driverId = box.read(BoxName.driverID).toString();

    String customQuery = '''
    SELECT COUNT(*) AS count
    FROM ${TableName.driverOrdersRefuse}
    WHERE driver_id = '$driverId'
   AND created_at LIKE '%$todayDay%'
  ''';

    try {
      List<Map<String, dynamic>> results =
          await sql.getCustomQuery(customQuery);
      countRefuse = results[0]['count'].toString();
      update();
      if (int.parse(countRefuse) > 3 || double.parse(totalPoints) <= -300) {
        print('total point is $totalPoints');
        locationController.stopLocationUpdates();
        activeStartTime = null;
        activeTimer?.cancel();
        savePeriod(activeDuration);
        activeDuration = Duration.zero;
        update();

        Get.defaultDialog(
            // backgroundColor: CupertinoColors.destructiveRed,
            barrierDismissible: false,
            title: 'You Are Stopped For this Day !'.tr,
            content: Text(
              'You Refused 3 Rides this Day that is the reason \nSee you Tomorrow!'
                  .tr,
              style: AppStyle.title,
            ),
            confirm: MyElevatedButton(
                title: 'Ok , See you Tomorrow'.tr,
                onPressed: () {
                  Get.back();
                  Get.back();
                }));
      }
    } catch (e) {
      print('Error executing custom query: $e');
    }
  }

  void changeMapType() {
    mapType = !mapType;
    // heightButtomSheetShown = isButtomSheetShown == true ? 240 : 0;
    update();
  }

  void changeMapTraffic() {
    mapTrafficON = !mapTrafficON;
    update();
  }

  late GoogleMapController mapHomeCaptainController;
  void onMapCreated(GoogleMapController controller) {
    mapHomeCaptainController = controller;
    controller.getVisibleRegion();
    // Animate camera to user location (optional)
    controller.animateCamera(
      CameraUpdate.newLatLng(Get.find<LocationController>().myLocation),
    );
  }

  void savePeriod(Duration period) {
    final periods = box.read<List<dynamic>>(BoxName.periods) ?? [];
    periods.add(period.inSeconds);
    box.write(BoxName.periods, periods);
  }

  Duration calculateTotalDuration() {
    final periods = box.read<List<dynamic>>(BoxName.periods) ?? [];
    Duration totalDuration = Duration.zero;
    for (dynamic periodInSeconds in periods) {
      final periodDuration = Duration(seconds: periodInSeconds);
      totalDuration += periodDuration;
    }
    return totalDuration;
  }

  void startPeriodicExecution() {
    Timer.periodic(const Duration(seconds: 30), (timer) async {
      await getCaptainDurationOnToday();
    });
  }

  void stopTimer() {
    print('Stopping timer');
    timer?.cancel();
  }

  getlocation() async {
    isLoading = true;
    print('isLoading   $isLoading');
    update();
    await Get.find<LocationController>().getLocation();
    isLoading = false;
    update();
  }

  @override
  void onInit() async {
    await addToken();
    await getlocation();
    onButtonSelected();
    await getDriverRate();
    await getKazanPercent();
    await getPaymentToday();
    getCountRideToday();
    getAllPayment();
    startPeriodicExecution();
    onMapCreated(mapHomeCaptainController);
    totalPoints = Get.find<CaptainWalletController>().totalPoints;
    getRefusedOrderByCaptain();
    // LocationController().getLocation();
    super.onInit();
  }

  addToken() async {
    await CRUD().post(link: AppLink.addTokensDriver, payload: {
      'token': box.read(BoxName.tokenDriver),
      'captain_id': box.read(BoxName.driverID).toString()
    }).then((value) => print('Token Added'));
    MapDriverController().driverCallPassenger();
    // box.write(BoxName.statusDriverLocation, 'off');
  }

  getPaymentToday() async {
    var res = await CRUD().get(
        link: AppLink.getDriverpaymentToday,
        payload: {'driverID': box.read(BoxName.driverID).toString()});
    if (res != 'failure') {
      data = jsonDecode(res);
      totalMoneyToday = data['message'][0]['todayAmount'];

      update();
    } else {
      print(res);
    }
  }

  getKazanPercent() async {
    var res = await CRUD().get(
      link: AppLink.getKazanPercent,
      payload: {'country': box.read(BoxName.countryCode).toString()},
    );
    if (res != 'failure') {
      var json = jsonDecode(res);
      kazan = double.parse(json['message'][0]['kazan']);
      naturePrice = double.parse(json['message'][0]['naturePrice']);
      heavyPrice = double.parse(json['message'][0]['heavyPrice']);
      latePrice = double.parse(json['message'][0]['latePrice']);
      comfortPrice = double.parse(json['message'][0]['comfortPrice']);
      speedPrice = double.parse(json['message'][0]['speedPrice']);
      deliveryPrice = double.parse(json['message'][0]['deliveryPrice']);
      mashwariPrice = double.parse(json['message'][0]['freePrice']);
      fuelPrice = double.parse(json['message'][0]['fuelPrice']);
      print(json);
    }
  }

  double mpg = 0;
  calculateConsumptionFuel() {
    mpg = fuelPrice / 12; //todo in register car add mpg in box
  }

  getCountRideToday() async {
    var res = await CRUD().get(
        link: AppLink.getCountRide,
        payload: {'driver_id': box.read(BoxName.driverID).toString()});
    data = jsonDecode(res);

    countRideToday = data['message'][0]['count'].toString();
    // print(countRideToday);
    update();
  }

  getDriverRate() async {
    var res = await CRUD().get(
        link: AppLink.getDriverRate,
        payload: {'driver_id': box.read(BoxName.driverID).toString()});
    if (res != 'failure') {
      var decod = jsonDecode(res);
      if (decod['message'][0]['rating'] != null) {
        rating = double.parse(decod['message'][0]['rating'].toString());
      } else {
        rating = 5.0; // Set a default value (e.g., 5.0 for full rating)
      }
    } else {
      rating = 5;
    }
  }

  getAllPayment() async {
    var res = await CRUD().get(
        link: AppLink.getAllPaymentFromRide,
        payload: {'driverID': box.read(BoxName.driverID).toString()});
    data = jsonDecode(res);

    totalMoneyInSEFER = data['message'][0]['total_amount'];
    update();
  }

  Future<void> getCaptainDurationOnToday() async {
    var res = await CRUD().get(
        link: AppLink.getTotalDriverDurationToday,
        payload: {'driver_id': box.read(BoxName.driverID).toString()});

    data = jsonDecode(res);
    totalDurationToday = data['message'][0]['total_duration'];
    update();
  }

  @override
  void dispose() {
    activeTimer?.cancel();
    stopTimer();
    super.dispose();
  }
}
