// Author: fengshengxiong
// Date: 2024/5/30
// Description: 音乐播放器控制器

import 'dart:async';

import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';
import 'package:tone_snap/components/base_easyloading.dart';
import 'package:tone_snap/components/music_bar.dart';
import 'package:tone_snap/data/api/music_api.dart';
import 'package:tone_snap/data/cache/music_cache_manager.dart';
import 'package:tone_snap/data/enum/play_mode.dart';
import 'package:tone_snap/data/models/music_model.dart';
import 'package:tone_snap/data/models/player_model.dart';
import 'package:tone_snap/data/storage/music_box.dart';
import 'package:tone_snap/routes/app_routes.dart';
import 'package:tone_snap/utils/audio_util.dart';
import 'package:tone_snap/utils/log_util.dart';
import 'package:tone_snap/utils/num_util.dart';

class MusicPlayerController extends GetxController {
  static MusicPlayerController get to => Get.put(MusicPlayerController(), permanent: true);
  final _player = AudioPlayer();
  StreamSubscription<Duration>? _bufferedSubscription;
  StreamSubscription<Duration?>? _durationSubscription;
  StreamSubscription<Duration>? _positionSubscription;
  StreamSubscription<PlayerState>? _playerStateSubscription;

  /// 总时长、已播放的时长、缓冲时长
  var totalDuration = Duration.zero.obs;
  var positionDuration = Duration.zero.obs;
  var bufferedDuration = Duration.zero.obs;

  /// 缓存管理器
  // final _cacheManager = DefaultCacheManager();
  final _cacheManager = MusicCacheManager.instance;

  /// 是否正在播放
  var isPlaying = false.obs;

  /// 播放器处理状态
  var processingState = ProcessingState.idle.obs;

  /// _player.seek(Duration.zero) 时，这可能会导致播放状态再次变为 completed。
  /// 为了避免这种情况，在处理 completed 状态时添加一个标志位，确保在处理完成状态时不会重复触发
  /// 是否已经处理过 completed 状态
  bool _isCompletedHandled = false;

  /// 拖动开始时是否是播放状态
  var seekFrontPlaying = true;

  /// 播放模式，默认列表循环
  var playMode = MusicBox().getPlayMode().obs;
  var _playModeIndex = 0;

  /// 播放列表
  var playList = <MusicModel>[].obs;

  /// 播放历史 videoId 集合
  /// 随机播放切换到上一首时，从历史记录中取出上一个播放的 videoId
  final List<String> _playHistory = [];

  /// 播放的歌曲模型
  var musicModel = MusicModel().obs;

  /// 当前播放的歌曲索引
  int _currentIndex = 0;

  @override
  void onInit() {
    super.onInit();
    AudioUtil.configAudioSession();
  }

  @override
  void onClose() {
    MusicBar().hide();
    _cancelListening();
    _player.dispose();
    super.onClose();
  }

  /// 播放指定索引的歌曲
  void playMusicSpecifyIndex(int index) {
    _currentIndex = index;
    playMusic();
  }

  /// 设置播放列表
  void setPlayList(String videoId, List<MusicModel> list) {
    _resetPlaybackStatus();
    playList.value = list;
    _playHistory.clear();

    MusicModel? musicModel = playList.firstWhereOrNull((e) => e.videoId == videoId);
    int index = musicModel != null ? playList.indexOf(musicModel) : 0;
    _currentIndex = index;
  }

  /// 播放歌曲
  Future<void> playMusic() async {
    Get.currentRoute != AppRoutes.playPage ? MusicBar().show() : MusicBar().hide();
    _resetPlaybackStatus();
    if (playList.isNotEmpty) {
      musicModel.update((e) {
        e?.thumbnail = playList[_currentIndex].thumbnail;
        e?.title = playList[_currentIndex].title;
        e?.subTitle = playList[_currentIndex].subTitle;
      });
      if (playList[_currentIndex].url == null) {
        await _getMusicUrl();
      }
      if (playList[_currentIndex].url == null) {
        BaseEasyLoading.toast('Resource not obtained');
        // nextTrack();
        return;
      }
      musicModel.value = playList[_currentIndex].copyWith();
      await _initializePlayer();
    }
  }

  /// 获取当前歌曲的播放 url
  Future<void> _getMusicUrl() async {
    PlayerModel? model = await MusicApi.player(videoId: playList[_currentIndex].videoId);
    if (model != null && model.streamingData != null) {
      var formats = model.streamingData?.formats;
      if (formats != null && playList.isNotEmpty) {
        playList[_currentIndex].url = formats[0].url;
      }
    }
    if (model != null && model.videoDetails?.thumbnail?.thumbnails != null) {

    }
  }

  /// 设置 url 和监听器
  Future<void> _initializePlayer() async {
    try {
      // 检查是否有缓存
      FileInfo? fileInfo = await MusicCacheManager.checkCache(musicModel.value.videoId!);
      if (fileInfo != null) {
        LogUtil.d('读取缓存=${fileInfo.file.path}');

        // 如果有缓存，使用缓存文件
        await _player.setFilePath(fileInfo.file.path);
      } else {
        // 如果没有缓存，通过 url 加载音源并开始播放，
        await _player.setUrl(musicModel.value.url!);

        // 同时启动缓存下载
        _cacheManager.downloadFile(musicModel.value.url!, key: MusicCacheManager.getCacheKey(musicModel.value.videoId!)).then((fileInfo) {
          LogUtil.d('缓存下载成功=${fileInfo.file.path}');
        });
      }
      _cancelListening();
      _addListening();
      _player.play();
    } catch (e) {
      LogUtil.e('Error initializing player: $e');
      BaseEasyLoading.toast('Error initializing player');
    }
  }

  /// 监听
  void _addListening() {
    _durationSubscription = _player.durationStream.listen((duration) {
      totalDuration.value = duration ?? Duration.zero;
    });

    _positionSubscription = _player.positionStream.listen((position) {
      positionDuration.value = position;
    });

    _bufferedSubscription = _player.bufferedPositionStream.listen((bufferedPosition) {
      int comparison = bufferedPosition.compareTo(totalDuration.value);
      if (comparison > 0) {
        bufferedDuration.value = totalDuration.value;
      } else {
        bufferedDuration.value = bufferedPosition;
      }
    });

    _playerStateSubscription = _player.playerStateStream.listen((playerState) {
      isPlaying.value = _player.playing;
      processingState.value = playerState.processingState;
      switch (playerState.processingState) {
        case ProcessingState.idle:
          break;
        case ProcessingState.loading:
          break;
        case ProcessingState.buffering:
          break;
        case ProcessingState.ready:
          _isCompletedHandled = false;
          break;
        case ProcessingState.completed:
          if (!_isCompletedHandled) {
            _isCompletedHandled = true;
            _player.seek(Duration.zero);
            nextTrack();
          }
          break;
      }
    });
  }

  /// 取消监听
  void _cancelListening() {
    _bufferedSubscription?.cancel();
    _durationSubscription?.cancel();
    _positionSubscription?.cancel();
    _playerStateSubscription?.cancel();
  }

  /// 将播放器的播放位置设置为指定的时间
  void seekToPosition(double value) {
    if (processingState.value == ProcessingState.ready) {
      positionDuration.value = Duration(seconds: value.toInt());
      _player.seek(positionDuration.value);
    }
  }

  /// 开始/结束拖动进度条
  Future<void> seekStartEnd(int value) async {
    if (processingState.value == ProcessingState.ready) {
      if (value == 0) {
        seekFrontPlaying = _player.playing;
        if (_player.playing) {
          _player.pause();
        }
      } else {
        // 拖动前如果是播放状态，拖动完成后恢复播放
        if (seekFrontPlaying) {
          _player.play();
        }
      }
    }
  }

  /// 播放/暂停
  Future<void> playPause() async {
    if (_player.playing) {
      _player.pause();
    } else {
      if (processingState.value == ProcessingState.ready) {
        _player.play();
      }
    }
  }

  /// 上一首
  void previousTrack() {
    if (playList.isNotEmpty) {
      switch(playMode.value) {
        case PlayMode.listLoop:
          _currentIndex = (_currentIndex - 1 + playList.length) % playList.length;
          playMusic();
          break;
        case PlayMode.random:
          bool historyExist = false;
          for (var i = _playHistory.length - 1; i >= 0; --i) {
            var history = _playHistory[i];
            MusicModel? model = playList.firstWhereOrNull((e) => e.videoId == history);
            if (model != null) {
              _currentIndex = playList.indexOf(model);
              _playHistory.remove(history);
              historyExist = true;
              break;
            } else {
              _playHistory.remove(history);
            }
          }
          if (!historyExist) {
            _getRandomNumber();
          }
          playMusic();
          break;
        case PlayMode.singleCycle:
          break;
      }
    }
  }

  /// 下一首
  void nextTrack() {
    if (playList.isNotEmpty) {
      switch(playMode.value) {
        case PlayMode.listLoop:
          _currentIndex = (_currentIndex + 1) % playList.length;
          playMusic();
          break;
        case PlayMode.random:
          // 记录当前播放的索引
          _playHistory.add(musicModel.value.videoId!);
          _getRandomNumber();
          playMusic();
          break;
        case PlayMode.singleCycle:
          break;
      }
    }
  }

  /// 在列表范围内生成一个不包括当前索引的随机数
  void _getRandomNumber() {
    _currentIndex = NumUtil.getRandomNumberExcludingCurrent(0, playList.length, _currentIndex);
  }

  /// 切换播放模式
  void switchPlayMode() {
    if (_playModeIndex == PlayMode.values.length - 1) {
      _playModeIndex = 0;
    } else {
      _playModeIndex++;
    }
    playMode.value = PlayMode.values[_playModeIndex];
    MusicBox().putPlayMode(playMode.value);
  }

  /// 重置播放状态
  void _resetPlaybackStatus() {
    _player.stop();
    _player.seek(Duration.zero);
    totalDuration.value = Duration.zero;
    positionDuration.value = Duration.zero;
    bufferedDuration.value = Duration.zero;
    musicModel.update((model) => model = MusicModel());
  }
}
