import { computed, onMounted, onUnmounted, ref, type Ref } from "vue";
import { TimeUtils } from "@imengyu/imengyu-utils";
import { toast } from "@/components/utils/DialogAction";

export function useSimpleAudioPlayer(config: {
  onEnded?: () => void;
}) {
  const duration = ref(0);
  const timeSec = ref(0);
  const timeString = ref('00:00');
  const isPlaying = ref(false);
  const isEnded = ref(false);
  const loadedState = ref(false);
  const innerAudioContext = uni.createInnerAudioContext();
  let loading = false

  function load(src: string) {
    loading = true;
    loadedState.value = true;
    innerAudioContext.stop();
    if (innerAudioContext.src != src)
      innerAudioContext.src = src;
    innerAudioContext.play();
    timeString.value = '加载中';
  }
    
  function play() {
    innerAudioContext.play();
  }
  function pause() {
    innerAudioContext.pause();
  }
  function restart() {
    innerAudioContext.seek(0);
    innerAudioContext.play();
  } 
  function playpause() {
    if (isPlaying.value) {
      innerAudioContext.pause();
      return;
    } else {
      innerAudioContext.play();
    }
  }
  function seek(sec: number) {
    innerAudioContext.seek(sec);
  }
  function stop() {
    innerAudioContext.stop();
  }

  innerAudioContext.onEnded(() => {
    isPlaying.value = false;
    isEnded.value = true;
    if (loading)
      return;
    if (config.onEnded)
      config.onEnded();
  });
  innerAudioContext.onPlay(() => {
    loading = false;
    isPlaying.value = true;
    isEnded.value = false;
  });
  innerAudioContext.onPause(() => {
    isPlaying.value = false;
    isEnded.value = false;
  });
  innerAudioContext.onSeeking(() => {
    loading = true;
    timeString.value = '加载中';
  });
  innerAudioContext.onSeeked(() => {
    loading = false;
  });
  innerAudioContext.onWaiting(() => {
    loading = true;
    timeString.value = '加载中';
  });
  innerAudioContext.onError((err) => {
    console.error(err);
    timeString.value = '错误';
    isPlaying.value = false;
    isEnded.value = false;
    loading = false;
  });
  innerAudioContext.onTimeUpdate(() => {
    duration.value = innerAudioContext.duration; 
    timeSec.value = innerAudioContext.currentTime;
    timeString.value = TimeUtils.getTimeStringSec(timeSec.value) + '/' + TimeUtils.getTimeStringSec(duration.value);
  });
  onUnmounted(() => {
    innerAudioContext.destroy();
  });

  return { 
    timeSec,
    timeString,
    loadedState,
    isPlaying, 
    isEnded,
    duration,
    seek,
    load, 
    stop,
    play, 
    playpause,
    restart,
    pause,
  };
}

export interface SimpleListAudioPlayerItem {
  src: string; 
  title: string;
}

export function useSimpleListAudioPlayer<T extends SimpleListAudioPlayerItem>(
  loadList: () => Promise<T[]>,
  autoNext: boolean = false,
  onEnded?: () => void,
) {
  const player = useSimpleAudioPlayer({
    onEnded: () => {
      onEnded?.();
      if (autoNext) {
        next();
      } 
    }
  });
  const list = ref<T[]>([]) as Ref<T[]>;
  const currentIndex = ref(0);
  const currentTitle = computed(() => {
    if (currentIndex.value < 0) 
      return '未在播放';
    return list.value[currentIndex.value]?.title || '未在播放';
  })
  const currentItem = computed(() => {
    if (currentIndex.value < 0) 
      return null;
    return list.value[currentIndex.value] || null;
  })

  onMounted(() => {
    reloadList();
  })

  async function reloadList() {
    list.value = await loadList();
  }

  function loadToPlayer() {
    player.load(list.value[currentIndex.value].src);
  }
  function next() {
    if (list.value.length == 0) {
      toast('没有更多了');
      return;
    }
    currentIndex.value ++;
    if (currentIndex.value > list.value.length - 1) 
      currentIndex.value = 0;
    loadToPlayer();
  }
  function prev() {
    if (list.value.length == 0) {
      toast('没有更多了');
      return;
    }
    currentIndex.value--;
    if (currentIndex.value < 0)
      currentIndex.value = list.value.length - 1;
    loadToPlayer();
  }

  return {
    ...player,
    playpause: () => {
      if (!player.loadedState.value) {
        loadToPlayer();
        return;
      }
      player.playpause();
    },
    list,
    currentIndex,
    currentTitle,
    currentItem,
    next,
    prev,
    reloadList,
  }
}