import 'dart:js_interop';
import 'package:web/web.dart' as web;
import 'package:em2rp/utils/debug_log.dart';

/// Service pour émettre des feedbacks sonores lors des interactions (Web)
class AudioFeedbackService {
  static bool _isInitialized = false;
  static bool _audioUnlocked = false;

  /// Initialiser le service
  static Future<void> _initialize() async {
    if (_isInitialized) return;

    try {
      DebugLog.info('[AudioFeedbackService] Initializing audio service for Web...');
      _isInitialized = true;
    } catch (e) {
      DebugLog.error('[AudioFeedbackService] Error initializing audio', e);
    }
  }

  /// Débloquer l'audio (à appeler lors de la première interaction utilisateur)
  static Future<void> unlockAudio() async {
    if (_audioUnlocked) {
      DebugLog.info('[AudioFeedbackService] Audio already unlocked');
      return;
    }

    try {
      if (!_isInitialized) await _initialize();

      DebugLog.info('[AudioFeedbackService] Attempting to unlock audio...');

      // Créer un audio temporaire et le jouer avec volume 0
      final tempAudio = web.HTMLAudioElement();
      tempAudio.src = 'assets/assets/sounds/ok.mp3';
      tempAudio.volume = 0.01; // Volume très faible mais pas 0
      tempAudio.preload = 'auto';

      try {
        await tempAudio.play().toDart;
        await Future.delayed(const Duration(milliseconds: 100));
        tempAudio.pause();
        _audioUnlocked = true;
        DebugLog.info('[AudioFeedbackService] ✓ Audio unlocked successfully');
      } catch (e) {
        DebugLog.warning('[AudioFeedbackService] ⚠ Could not unlock audio: $e');
        DebugLog.warning('[AudioFeedbackService] User interaction may be required');
      }
    } catch (e) {
      DebugLog.error('[AudioFeedbackService] Error unlocking audio', e);
    }
  }

  /// Créer et jouer un son
  static Future<void> _playSound(String assetPath, double volume) async {
    try {
      if (!_isInitialized) await _initialize();

      DebugLog.info('[AudioFeedbackService] Attempting to play: $assetPath (volume: $volume)');

      // Créer un nouvel élément audio à chaque fois
      final audio = web.HTMLAudioElement();
      audio.src = assetPath;
      audio.volume = volume;
      audio.preload = 'auto';

      // Ajouter des événements pour debug
      audio.onloadeddata = ((web.Event event) {
        DebugLog.info('[AudioFeedbackService] Audio data loaded: $assetPath');
      }.toJS);

      audio.onerror = ((web.Event event) {
        DebugLog.error('[AudioFeedbackService] ✗ Audio error for $assetPath: ${audio.error}');
      }.toJS);

      audio.onplay = ((web.Event event) {
        DebugLog.info('[AudioFeedbackService] Audio started playing');
      }.toJS);

      audio.onended = ((web.Event event) {
        DebugLog.info('[AudioFeedbackService] Audio finished playing');
      }.toJS);

      try {
        // Essayer de jouer
        await audio.play().toDart;
        DebugLog.info('[AudioFeedbackService] ✓ Sound played successfully');
      } catch (e) {
        DebugLog.error('[AudioFeedbackService] ✗ Play failed: $e');

        // Si c'est un problème d'autoplay, essayer de débloquer
        if (!_audioUnlocked) {
          DebugLog.info('[AudioFeedbackService] Trying to unlock audio on error...');
          _audioUnlocked = false; // Forcer le déblocage
          await unlockAudio();

          // Réessayer une fois après déblocage
          try {
            final retryAudio = web.HTMLAudioElement();
            retryAudio.src = assetPath;
            retryAudio.volume = volume;
            await retryAudio.play().toDart;
            DebugLog.info('[AudioFeedbackService] ✓ Sound played on retry');
          } catch (retryError) {
            DebugLog.error('[AudioFeedbackService] ✗ Retry also failed: $retryError');
          }
        }
      }
    } catch (e) {
      DebugLog.error('[AudioFeedbackService] Error in _playSound', e);
    }
  }

  /// Jouer un son de succès
  static Future<void> playSuccessBeep() async {
    await _playSound('assets/assets/sounds/ok.mp3', 1.0);
  }

  /// Jouer un son d'erreur
  static Future<void> playErrorBeep() async {
    await _playSound('assets/assets/sounds/error.mp3', 0.8);
  }

  /// Jouer un feedback complet (son uniquement, sans vibration)
  static Future<void> playFullFeedback({bool isSuccess = true}) async {
    if (isSuccess) {
      await playSuccessBeep();
    } else {
      await playErrorBeep();
    }
  }

  /// Nettoyer les ressources
  static Future<void> dispose() async {
    try {
      _isInitialized = false;
      _audioUnlocked = false;
    } catch (e) {
      DebugLog.error('[AudioFeedbackService] Error disposing', e);
    }
  }
}

