import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/app_style/app_text_style.dart';

class ASoundPlayer extends StatefulWidget {
  final String audio;

  const ASoundPlayer({Key? key, required this.audio}) : super(key: key);

  @override
  _ASoundPlayerState createState() => _ASoundPlayerState();
}

class _ASoundPlayerState extends State<ASoundPlayer> {
  //FlutterSoundPlayer _myPlayer = FlutterSoundPlayer();
  bool _sliderMoving = false;
  Duration? _audioTime;
  Duration? _audioPosition;
  late String _audio;
  bool _isLocalFile = false;
  bool _failedToLoad = false;
  late AudioPlayer _audioPlayer;

  Widget audioPlayerButton(IconData icon, VoidCallback onpress) {
    return Container(
      width: 48,
      height: 48,
      decoration: ShapeDecoration(
        color: AppColor.background(context),
        shape: RoundedRectangleBorder(
          side: BorderSide(width: 1, color: (context.isDark ? AppColor.neutral20 : AppColor.neutral30)),
          borderRadius: BorderRadius.circular(32),
        ),
      ),
      child: Icon(
        icon,
        size: 30,
        color: (context.isDark ? AppColor.primary40 : AppColor.primary70).withOpacity(0.5),
      ),
    ).onPress(onpress);
  }

  Widget _getAudioButton() {
    switch (_audioPlayer.state) {
      case PlayerState.playing:
        return audioPlayerButton(Icons.pause_rounded, () async {
          _failedToLoad = false;
          await _audioPlayer.pause();
          rebuild();
        });
      case PlayerState.paused:
        return audioPlayerButton(Icons.play_arrow_rounded, () async {
          _failedToLoad = false;
          await _audioPlayer.resume();
          rebuild();
        });
      case PlayerState.completed:
        return audioPlayerButton(Icons.replay_rounded, () async {
          _failedToLoad = false;
          await _audioPlayer.stop();
          await _audioPlayer.resume();
          rebuild();
        });
      case PlayerState.stopped:
        return audioPlayerButton(_isLocalFile ? Icons.play_arrow_rounded : Icons.download_rounded, () async {
          _failedToLoad = false;
          try {
            await _audioPlayer.play(
              _isLocalFile ? DeviceFileSource(_audio) : UrlSource(_audio),
            );
            rebuild();
          } on Exception {
            _failedToLoad = true;
          }
        });

      default:
        return audioPlayerButton(Icons.replay_rounded, () async {
          _failedToLoad = false;

          try {
            _audioPlayer.seek(const Duration(milliseconds: 0));
            _audioPlayer.stop();
            await _audioPlayer.play(
              _isLocalFile ? DeviceFileSource(_audio) : UrlSource(_audio),
            );
            rebuild();
          } on Exception {
            _failedToLoad = true;
          }
        });
    }
  }

  String format(Duration d) {
    return d.toString().substring(2, 7);
  }

  rebuild() {
    if (!mounted) return;
    setState(() {});
  }

  bool _isLocalUrl(String url) {
    if (url.isEmpty != false) return false;
    return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
  }

  @override
  void initState() {
    super.initState();
    _audioPlayer = AudioPlayer();
    _audioPlayer.release();
    _audio = widget.audio;
    _isLocalFile = _isLocalUrl(_audio);
    _audioPlayer.setReleaseMode(ReleaseMode.stop);
    if (_isLocalFile) {
      _audioPlayer.setSourceDeviceFile(_audio).then((value) {
        rebuild();
      });
    } else {
      _audioPlayer.setReleaseMode(ReleaseMode.stop);
    }
    // set up listeners
    _audioPlayer.onPositionChanged.listen((Duration duration) {
      if (!_sliderMoving) {
        _audioPosition = duration;
        rebuild();
      }
      //setState(() => position = p);
    });
    _audioPlayer.onPlayerStateChanged.listen((event) {
      //_audioPosition = _audioTime;
      rebuild();
    });
    _audioPlayer.onDurationChanged.listen((Duration duration) {
      _audioTime = duration;
      rebuild();
    });
    _audioPlayer.onSeekComplete.listen((event) {
      rebuild();
    });
  }

  @override
  void dispose() {
    super.dispose();
    // _myPlayer.closeAudioSession();
    _audioPlayer.release();
    _audioPlayer.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (_audio != widget.audio) {
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
        _audio = widget.audio;
        print('audio position i got is $_audioPosition');
        if (_isLocalFile) {
          await _audioPlayer.setSourceDeviceFile(_audio);
        } else {
          await _audioPlayer.setSourceUrl(_audio);
        }
        _audioPlayer.seek(const Duration(milliseconds: 0));
        _audioPlayer.stop();
        rebuild();
      });
    }
    return Column(
      crossAxisAlignment: CrossAxisAlignment.end,
      children: [
        Row(
          children: [
            _getAudioButton(),
            SliderTheme(
              data: SliderTheme.of(context).copyWith(trackHeight: 2.0, thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 6.0), overlayShape: SliderComponentShape.noOverlay),
              child: Slider(
                value: _audioPosition?.inMilliseconds.toDouble() ?? 0.0,
                min: 0,
                max: _audioTime?.inMilliseconds.toDouble() ?? 60.0,
                activeColor: context.isDark ? AppColor.primary40 : AppColor.primary70,
                inactiveColor: context.isDark ? AppColor.neutral20 : AppColor.neutral30,
                onChangeStart: (value) {
                  _sliderMoving = true;
                },
                onChanged: (value) {
                  _audioPosition = Duration(milliseconds: value.round());
                  rebuild();
                },
                onChangeEnd: (value) {
                  _sliderMoving = false;
                  _audioPlayer.seek(Duration(milliseconds: value.round()));
                  rebuild();
                },
              ),
            ).paddingOnly(start: 8, end: 8).expanded,
            _failedToLoad
                ? Text("Failed to load", style: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60))
                : Text("${format(_audioPosition??Duration.zero)}/${format(_audioTime??Duration.zero)}", style: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50)),
          ],
        ),
      ],
    );
  }
}
