import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import { get, post } from '../utils/request';
import type { AudioItem, Voice, VoiceParams } from '../types';

export const useAudioStore = defineStore('audio', () => {
  // 状态
  const voices = ref<Voice[]>([]);
  const currentAudio = ref<AudioItem | null>(null);
  const playlist = ref<AudioItem[]>([]);
  const currentIndex = ref(-1);
  const isPlaying = ref(false);
  const currentTime = ref(0);
  const duration = ref(0);
  const playRate = ref(1);

  // 音频上下文
  let audioContext: UniApp.InnerAudioContext | null = null;

  // 计算属性
  const hasPlaylist = computed(() => playlist.value.length > 0);
  const hasNext = computed(() => currentIndex.value < playlist.value.length - 1);
  const hasPrev = computed(() => currentIndex.value > 0);

  // 初始化音频上下文
  function initAudioContext() {
    if (audioContext) return;

    audioContext = uni.createInnerAudioContext();

    audioContext.onPlay(() => {
      isPlaying.value = true;
    });

    audioContext.onPause(() => {
      isPlaying.value = false;
    });

    audioContext.onEnded(() => {
      isPlaying.value = false;
      // 不自动播放下一首，让用户手动选择
    });

    audioContext.onTimeUpdate(() => {
      currentTime.value = audioContext?.currentTime || 0;
      duration.value = audioContext?.duration || 0;
    });

    audioContext.onError((err) => {
      console.error('音频播放错误:', err);
      isPlaying.value = false;
    });
  }

  // 获取音色列表
  async function fetchVoices() {
    const result = await get<{ voices: Voice[] }>('/tts/voices');
    voices.value = result.voices;
    return result.voices;
  }

  // 生成音频
  async function generateAudio(
    text: string,
    voiceId: string,
    voiceParams: VoiceParams
  ) {
    uni.showLoading({ title: '生成中...', mask: true });
    try {
      const result = await post<{
        audioId: string;
        audioUrl: string;
        duration: number;
        size: number;
      }>('/tts/generate', { text, voiceId, voiceParams });

      uni.hideLoading();
      return result;
    } catch (error) {
      uni.hideLoading();
      throw error;
    }
  }

  // 播放音频
  function play(audio: AudioItem) {
    initAudioContext();

    currentAudio.value = audio;
    
    // 如果音频源相同，只切换播放状态
    if (audioContext && audioContext.src === audio.audioUrl) {
      audioContext.play();
    } else if (audioContext) {
      audioContext.src = audio.audioUrl;
      audioContext.play();
    }
  }

  // 暂停
  function pause() {
    if (audioContext) {
      audioContext.pause();
    }
  }

  // 继续播放
  function resume() {
    if (audioContext) {
      audioContext.play();
    }
  }

  // 切换播放/暂停
  function togglePlay() {
    if (isPlaying.value) {
      pause();
    } else {
      resume();
    }
  }

  // 播放上一首
  function playPrev() {
    if (hasPrev.value) {
      currentIndex.value--;
      play(playlist.value[currentIndex.value]);
    }
  }

  // 播放下一首
  function playNext() {
    if (hasNext.value) {
      currentIndex.value++;
      play(playlist.value[currentIndex.value]);
    }
  }

  // 跳转到指定位置
  function seek(time: number) {
    if (audioContext) {
      audioContext.seek(time);
      currentTime.value = time;
    }
  }

  // 设置播放速度
  function setPlayRate(rate: number) {
    playRate.value = rate;
    if (audioContext) {
      audioContext.playbackRate = rate;
    }
  }

  // 设置播放列表
  function setPlaylist(list: AudioItem[], index: number = 0, autoPlay: boolean = true) {
    playlist.value = list;
    currentIndex.value = index;
    if (list.length > 0 && autoPlay) {
      play(list[index]);
    }
  }

  // 销毁音频上下文
  function destroy() {
    if (audioContext) {
      audioContext.destroy();
      audioContext = null;
    }
  }

  return {
    // 状态
    voices,
    currentAudio,
    playlist,
    currentIndex,
    isPlaying,
    currentTime,
    duration,
    playRate,
    // 计算属性
    hasPlaylist,
    hasNext,
    hasPrev,
    // 方法
    fetchVoices,
    generateAudio,
    play,
    pause,
    resume,
    togglePlay,
    playPrev,
    playNext,
    seek,
    setPlayRate,
    setPlaylist,
    destroy,
  };
});