import 'dart:async';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:sensors_plus/sensors_plus.dart';

import '../print.dart';

class EmergencySignalService {
  static final EmergencySignalService instance = EmergencySignalService._();
  EmergencySignalService._();

  StreamSubscription<AccelerometerEvent>? _accelerometerSubscription;
  DateTime? _lastShakeTime;
  int _shakeCount = 0;

  // Custom thresholds for shaking (force required)
  final double _shakeThresholdGravity = 2.7;
  final int _shakeSlopTimeMs = 500;
  final int _shakeCountResetTimeMs = 3000;
  final int _targetShakes = 5;

  VoidCallback? _onEmergencyTriggered;

  /// Starts listening to phone movement
  void startListening(VoidCallback onEmergencyTriggered) {
    _onEmergencyTriggered = onEmergencyTriggered;

    if (_accelerometerSubscription != null) return;

    _accelerometerSubscription = accelerometerEvents.listen((event) {
      double x = event.x;
      double y = event.y;
      double z = event.z;

      // Calculate the gForce using pythagorean theorem
      double gX = x / 9.80665;
      double gY = y / 9.80665;
      double gZ = z / 9.80665;

      // Overall gForce
      double gForce = sqrt(gX * gX + gY * gY + gZ * gZ);

      if (gForce > _shakeThresholdGravity) {
        final now = DateTime.now();

        // Ignore shakes that are too close to each other
        if (_lastShakeTime != null &&
            now.difference(_lastShakeTime!).inMilliseconds < _shakeSlopTimeMs) {
          return;
        }

        // Reset the counter if elapsed more than the reset window
        if (_lastShakeTime != null &&
            now.difference(_lastShakeTime!).inMilliseconds >
                _shakeCountResetTimeMs) {
          _shakeCount = 0;
        }

        _lastShakeTime = now;
        _shakeCount++;

        if (kDebugMode) {
          Log.print("🚨 Shake detected! Count: $_shakeCount");
        }

        if (_shakeCount >= _targetShakes) {
          _shakeCount = 0; // Reset counter
          if (_onEmergencyTriggered != null) {
            _onEmergencyTriggered!();
          }
        }
      }
    });
  }

  void stopListening() {
    _accelerometerSubscription?.cancel();
    _accelerometerSubscription = null;
    _shakeCount = 0;
  }
}
