import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/sizing.dart';

import '../../app_style/colors.dart';

class ASoundPlayer extends StatefulWidget {
  final String audio;

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

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

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

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

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

  String format(Duration d) {
    if (d == null) return "00:00";
    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;
        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: [
            Material(color: Colors.transparent, child: _getAudioButton()),
            Expanded(
              child: Slider(
                  value: _audioPosition?.inMilliseconds?.toDouble() ?? 0.0,
                  min: 0,
                  max: _audioTime?.inMilliseconds?.toDouble() ?? 60.0,
                  onChangeStart: (value) {
                    _sliderMoving = true;
                  },
                  onChanged: (value) {
                    _audioPosition = Duration(milliseconds: value.round());
                    rebuild();
                  },
                  onChangeEnd: (value) {
                    _sliderMoving = false;
                    _audioPlayer.seek(Duration(milliseconds: value.round()));
                    rebuild();
                  }),
            ),
          ],
        ),
        Row(
          children: [
            Expanded(
              child: Visibility(
                visible: _failedToLoad,
                child: Row(
                  children: [
                    Text(
                      "Failed to load",
                      style: Theme.of(context).textTheme.overline.copyWith(color: AColors.red),
                      textScaleFactor: AppStyle.getScaleFactor(context),
                    ),
                  ],
                ),
              ),
            ),
            Visibility(
              visible: _audioPlayer.state != PlayerState.stopped,
              child: Text(
                "${format(_audioPosition)}/${format(_audioTime)}",
                style: Theme.of(context).textTheme.overline,
                textScaleFactor: AppStyle.getScaleFactor(context),
              ),
            ),
          ],
        )
      ],
    );
  }
}
