import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'dart:async';

import '../theme/app_theme.dart';
import '../theme/modern_glass_button.dart';

// Conditional imports for audio
import 'package:just_audio/just_audio.dart'
    if (dart.library.html) 'web_audio_player.dart';

class AudioPlayerBar extends StatefulWidget {
  final String fileName;
  final String fileUrl;
  final VoidCallback? onClose;

  const AudioPlayerBar({
    super.key,
    required this.fileName,
    required this.fileUrl,
    this.onClose,
  });

  @override
  State<AudioPlayerBar> createState() => _AudioPlayerBarState();
}

class _AudioPlayerBarState extends State<AudioPlayerBar>
    with SingleTickerProviderStateMixin {
  late AudioPlayer _audioPlayer;
  late AnimationController _iconController;
  Duration _duration = Duration.zero;
  Duration _position = Duration.zero;
  bool _isPlaying = false;
  bool _isLoading = true;
  StreamSubscription? _positionSubscription;
  StreamSubscription? _durationSubscription;
  StreamSubscription? _playingSubscription;
  StreamSubscription? _errorSubscription;

  @override
  void initState() {
    super.initState();
    _audioPlayer = AudioPlayer();
    _iconController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 250),
    );
    _initAudio();
  }

  @override
  void dispose() {
    _iconController.dispose();
    _positionSubscription?.cancel();
    _durationSubscription?.cancel();
    _playingSubscription?.cancel();
    _errorSubscription?.cancel();
    _audioPlayer.dispose();
    super.dispose();
  }

  String? _errorMsg;
  Future<void> _initAudio() async {
    // Log the file URL for debugging
    // ignore: avoid_print
    print('[AudioPlayerBar] Loading audio URL: ${widget.fileUrl}');
    try {
      await _audioPlayer.setUrl(widget.fileUrl);

      if (kIsWeb) {
        // Web implementation
        _durationSubscription = _audioPlayer.durationStream.listen((d) {
          if (d != null) {
            setState(() {
              _duration = d;
              _isLoading = false;
            });
          }
        });

        _positionSubscription = _audioPlayer.positionStream.listen((pos) {
          setState(() {
            _position = pos;
          });
        });

        _playingSubscription = _audioPlayer.playingStream.listen((playing) {
          setState(() {
            _isPlaying = playing;
          });
          if (playing) {
            if (mounted) _iconController.forward();
          } else {
            if (mounted) _iconController.reverse();
          }
        });

        _errorSubscription = _audioPlayer.errorStream.listen((error) {
          setState(() {
            _errorMsg = error.toString();
            _isLoading = false;
          });
          // ignore: avoid_print
          print('[AudioPlayerBar] Web audio error: $error');
        });

        // Auto-play for web
        await _audioPlayer.play();
      } else {
        // Mobile implementation (just_audio)
        _audioPlayer.durationStream.firstWhere((d) => d != null).then((
          d,
        ) async {
          setState(() {
            _duration = d ?? Duration.zero;
            _isLoading = false;
          });
          try {
            await _audioPlayer.play(); // Start playback automatically
            // For mobile, check playing state after a short delay
            Future.delayed(const Duration(milliseconds: 100), () {
              // Use dynamic access to avoid compilation issues with conditional imports
              final player = _audioPlayer as dynamic;
              if (player.playerState?.playing == true) {
                if (mounted) _iconController.forward();
              } else {
                setState(() {
                  _errorMsg = 'Audio could not be played.';
                });
                // ignore: avoid_print
                print('[AudioPlayerBar] ERROR: Audio could not be played.');
              }
            });
          } catch (e, st) {
            setState(() {
              _errorMsg =
                  'Audio playback error: ' +
                  (e is Exception ? e.toString() : 'Unknown error');
            });
            // ignore: avoid_print
            print('[AudioPlayerBar] Playback error: $e\n$st');
          }
        });
        _audioPlayer.positionStream.listen((pos) {
          setState(() {
            _position = pos;
          });
        });
        // Use dynamic access to avoid compilation issues with conditional imports
        final player = _audioPlayer as dynamic;
        player.playerStateStream.listen((state) {
          setState(() {
            _isPlaying = state.playing;
          });
          if (state.playing) {
            if (mounted) _iconController.forward();
          } else {
            if (mounted) _iconController.reverse();
          }
        });
      }
    } catch (e, st) {
      setState(() {
        _isLoading = false;
        _errorMsg =
            'Audio load error: ' +
            (e is Exception ? e.toString() : 'Unknown error');
      });
      // ignore: avoid_print
      print('[AudioPlayerBar] Load error: $e\n$st');
    }
  }

  void _handlePlayPause() {
    if (_isPlaying) {
      _audioPlayer.pause();
      _iconController.reverse();
    } else {
      // If at end, seek to start
      if (_position >= _duration && _duration > Duration.zero) {
        _audioPlayer.seek(Duration.zero);
      }
      _audioPlayer.play();
      _iconController.forward();
    }
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: const Duration(milliseconds: 300),
      height: 48,
      width:
          MediaQuery.of(context).size.width *
          0.30, // Reduce width to 30% for better fit
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
      decoration: AppTheme.glassDecoration.copyWith(
        borderRadius: BorderRadius.circular(16),
        boxShadow: [
          BoxShadow(
            color: AppTheme.accentColor.withValues(alpha: 0.15),
            blurRadius: 12,
            offset: const Offset(0, 2),
          ),
        ],
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          // Play/Pause button (AnimatedIcon)
          ModernGlassButton(
            onPressed: _isLoading ? () {} : _handlePlayPause,
            child: AnimatedIcon(
              icon: AnimatedIcons.play_pause,
              progress: _iconController,
              color: AppTheme.primaryText,
              size: 22,
            ),
          ),
          const SizedBox(width: 10),
          // File name and slider
          Expanded(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  widget.fileName,
                  style: const TextStyle(
                    color: AppTheme.primaryText,
                    fontWeight: FontWeight.w600,
                    fontSize: 14,
                  ),
                  overflow: TextOverflow.ellipsis,
                ),
                SizedBox(
                  height: 18,
                  child: SliderTheme(
                    data: SliderTheme.of(context).copyWith(
                      trackHeight: 2.2,
                      thumbShape: const RoundSliderThumbShape(
                        enabledThumbRadius: 6,
                      ),
                      overlayShape: SliderComponentShape.noOverlay,
                      activeTrackColor: AppTheme.accentColor,
                      inactiveTrackColor: AppTheme.accentColor.withValues(
                        alpha: 0.18,
                      ),
                    ),
                    child: Slider(
                      min: 0,
                      max: _duration.inMilliseconds.toDouble(),
                      value: _position.inMilliseconds
                          .clamp(0, _duration.inMilliseconds)
                          .toDouble(),
                      onChanged: _isLoading
                          ? null
                          : (value) {
                              _audioPlayer.seek(
                                Duration(milliseconds: value.toInt()),
                              );
                            },
                      activeColor: AppTheme.accentColor,
                      inactiveColor: AppTheme.accentColor.withValues(
                        alpha: 0.18,
                      ),
                    ),
                  ),
                ),
                if (_errorMsg != null)
                  Padding(
                    padding: const EdgeInsets.only(top: 2.0),
                    child: Text(
                      _errorMsg!,
                      style: const TextStyle(
                        color: Colors.red,
                        fontSize: 12,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                  ),
              ],
            ),
          ),
          const SizedBox(width: 10),
          // Time
          Text(
            '${_formatDuration(_position)} / ${_formatDuration(_duration)}',
            style: const TextStyle(
              color: AppTheme.secondaryText,
              fontSize: 12,
              fontWeight: FontWeight.w500,
            ),
          ),
          // Close button (smaller)
          if (widget.onClose != null)
            Padding(
              padding: const EdgeInsets.only(left: 8.0),
              child: ModernGlassButton(
                onPressed: widget.onClose!,
                child: const Icon(
                  Icons.close,
                  color: AppTheme.primaryText,
                  size: 18,
                ),
              ),
            ),
        ],
      ),
    );
  }

  // Utility to format duration
  String _formatDuration(Duration d) {
    String twoDigits(int n) => n.toString().padLeft(2, '0');
    final minutes = twoDigits(d.inMinutes.remainder(60));
    final seconds = twoDigits(d.inSeconds.remainder(60));
    return '$minutes:$seconds';
  }
}
