import 'package:get_it/get_it.dart';
import 'package:flutter/foundation.dart';

import '../core/constants/app_constants.dart';
import '../core/ai/obstacle_analyzer.dart';
import '../core/ai/yolo_detector.dart';
import '../core/network/api_client.dart';
import '../core/services/haptic_service.dart';
import '../core/services/call_service.dart';
import '../core/services/fcm_service.dart';
import '../core/services/location_reporter_service.dart';
import '../core/services/offline_queue_service.dart';
import '../core/services/stt_service.dart';
import '../core/services/tts_service.dart';
import '../core/services/voice_command_handler.dart';
import '../core/services/websocket_service.dart';
import '../core/storage/secure_storage.dart';

final sl = GetIt.instance;

Future<void> initDependencies() async {
  sl.registerLazySingleton<SecureStorage>(() => SecureStorage());
  sl.registerLazySingleton<ApiClient>(() => ApiClient(sl<SecureStorage>()));
  sl.registerLazySingleton<TtsService>(() => TtsService());
  sl.registerLazySingleton<SttService>(() => SttService());
  sl.registerLazySingleton<HapticService>(() => HapticService());
  sl.registerLazySingleton<ObstacleAnalyzer>(() => ObstacleAnalyzer());
  sl.registerLazySingleton<YoloDetector>(() => YoloDetector(sl<ObstacleAnalyzer>()));
  sl.registerLazySingleton<OfflineQueueService>(() => OfflineQueueService());
  sl.registerLazySingleton<FcmService>(() => FcmService(sl<ApiClient>()));
  sl.registerLazySingleton<WebSocketService>(() => WebSocketService(sl<SecureStorage>()));
  sl.registerLazySingleton<LocationReporterService>(() => LocationReporterService(sl<ApiClient>(), sl<OfflineQueueService>()));
  sl.registerLazySingleton<CallService>(() => CallService(sl<ApiClient>()));
  sl.registerLazySingleton<VoiceCommandHandler>(
    () => VoiceCommandHandler(sl<SttService>(), sl<TtsService>()),
  );

  final serverUrl = await AppConstants.getServerUrl();
  if (serverUrl != null && serverUrl.isNotEmpty) {
    await sl<ApiClient>().init(serverUrl);
  }

  try {
    await sl<TtsService>().init();
  } catch (e) {
    debugPrint('TTS init skipped: $e');
  }
  await sl<YoloDetector>().init();
  if (!kIsWeb) {
    try {
      await sl<SttService>().init();
    } catch (e) {
      debugPrint('STT init skipped: $e');
    }
  }
  sl<VoiceCommandHandler>().loadDefaultCommands();
  if (!kIsWeb) {
    await sl<FcmService>().init();
  }
}
