import 'dart:convert';
import 'dart:math';

import 'package:get/get.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 '../../../constant/table_names.dart';
import '../../../main.dart';
import '../../../print.dart';

class DriverBehaviorController extends GetxController {
  Future<List<Map<String, dynamic>>> getAllData() async {
    return await sql.getAllData(TableName.behavior);
  }

  var isLoading = false.obs;
  var overallScore = 100.0.obs;
  var lastTrips = [].obs;

  Future<void> fetchDriverBehavior() async {
    isLoading.value = true;
    try {
      final response = await CRUD().get(
        link: AppLink.get_driver_behavior,
        payload: {"driver_id": box.read(BoxName.driverID).toString()},
      );

      if (response != 'failure') {
        final json = jsonDecode(response);

        overallScore.value =
            double.parse(json['message']['overall_behavior_score'].toString());
        lastTrips.value = json['message']['last_10_trips'];
      } else {
        // Get.snackbar("Error", json['message'] ?? "Unknown error");
      }
    } catch (e) {
      // Get.snackbar("Error", "Exception: $e");
      Log.print('e: ${e}');
    } finally {
      isLoading.value = false;
    }
  }

  Future<Map<String, dynamic>> analyzeData() async {
    final data = await getAllData();
    if (data.isEmpty) return {};

    double maxSpeed = 0;
    double totalSpeed = 0;
    int hardBrakes = 0;
    double totalDistance = 0;
    double? prevLat, prevLng;

    for (var item in data) {
      double speed = item['speed'] ?? 0;
      double lat = item['lat'] ?? 0;
      double lng = item['lng'] ?? 0;
      double acc = item['acceleration'] ?? 0;

      if (speed > maxSpeed) maxSpeed = speed;
      totalSpeed += speed;

      // ✅ Hard brake threshold
      if (acc.abs() > 3.0) hardBrakes++;

      // ✅ Distance between points
      if (prevLat != null && prevLng != null) {
        totalDistance += _calculateDistance(prevLat, prevLng, lat, lng);
      }
      prevLat = lat;
      prevLng = lng;
    }

    double avgSpeed = totalSpeed / data.length;
    double behaviorScore = 100 - (hardBrakes * 5) - ((maxSpeed > 100) ? 10 : 0);
    behaviorScore = behaviorScore.clamp(0, 100);

    return {
      'max_speed': maxSpeed,
      'avg_speed': avgSpeed,
      'hard_brakes': hardBrakes,
      'total_distance': totalDistance,
      'behavior_score': behaviorScore,
    };
  }

  Future<void> sendSummaryToServer(String driverId, String tripId) async {
    final summary = await analyzeData();
    if (summary.isEmpty) return;

    final body = {
      'driver_id': driverId,
      'trip_id': tripId,
      ...summary,
    };

    CRUD().post(link: AppLink.saveBehavior, payload: (body));

    await clearData();
  }

  Future<void> clearData() async {
    await sql.deleteAllData(TableName.behavior);
  }

  double _calculateDistance(
      double lat1, double lon1, double lat2, double lon2) {
    const p = 0.017453292519943295;
    final a = 0.5 -
        cos((lat2 - lat1) * p) / 2 +
        cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2;
    return 12742 * asin(sqrt(a)); // distance in km
  }
}
