import { defineStore } from 'pinia';
import { ref, shallowRef, watch } from 'vue';
import { MessagePlugin } from 'tdesign-vue-next';
import type { Song } from '../types/song';
import { pluginManager } from '../plugins/index';
import { parseAnyLyric } from '../utils/lyricUtil';
import { useLogStore } from './log';

export enum PlayMode {
    List = 'list',
    Single = 'single',
    Random = 'random'
}

let audioElement: HTMLAudioElement | null = null;
let audioContext: AudioContext | null = null;
let analyser: AnalyserNode | null = null;
let animationFrameId: number | null = null;

export const usePlayerStore = defineStore('player', () => {
    // State
    const isPlaying = ref(false);
    const currentSong = ref<Song | null>(null);
    const savedVolume = localStorage.getItem('qz-player-volume');
    const volume = ref(savedVolume ? Number(savedVolume) : 50); // 1~100

    // Persistence & Sync
    watch(volume, (newVol) => {
        localStorage.setItem('qz-player-volume', newVol.toString());
        if (audioElement) {
            audioElement.volume = newVol / 100;
        }
    });

    const duration = ref(0); //毫秒级
    const currentTime = ref(0); //毫秒级

    // Audio Visualization State
    const loudness = ref(0);
    const spectrum = ref<number[]>([]);

    // UI State
    const isPlayerFullScreen = ref(false);
    const hideLyricView = ref(false);
    const showPlaylist = ref(false);

    // Playlist State
    const savedPlaylist = localStorage.getItem('qz-player-playlist');
    const savedIndex = localStorage.getItem('qz-player-index');

    const playlist = ref<Song[]>(savedPlaylist ? JSON.parse(savedPlaylist) : []);
    const currentIndex = ref(savedIndex ? Number(savedIndex) : -1);
    const playMode = ref<PlayMode>(PlayMode.List);
    const savedAddMode = localStorage.getItem('qz-player-add-mode');
    const addListMode = ref<'replace' | 'append'>((savedAddMode as 'replace' | 'append') || 'replace');

    // Error Handling
    const playErrorCount = ref(0);
    const MAX_RETRY_COUNT = 3;

    // Lyrics State
    const lyrics = shallowRef<{ lines: any[] }>({ lines: [] });

    // Initialize audio element
    const initAudio = () => {
        if (!audioElement && typeof window !== 'undefined') {
            audioElement = new Audio();
            audioElement.volume = volume.value / 100;

            // Setup audio context for visualization
            if (window.AudioContext || (window as any).webkitAudioContext) {
                audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
                analyser = audioContext.createAnalyser();
                analyser.fftSize = 256;
                const source = audioContext.createMediaElementSource(audioElement);
                source.connect(analyser);
                analyser.connect(audioContext.destination);
            }

            // Event listeners
            audioElement.addEventListener('loadedmetadata', () => {
                if (audioElement) {
                    duration.value = audioElement.duration * 1000;
                }
            });

            audioElement.addEventListener('timeupdate', () => {
                if (audioElement) {
                    currentTime.value = audioElement.currentTime * 1000;
                }
            });

            audioElement.addEventListener('play', () => {
                isPlaying.value = true;
                startVisualization();
                if ('mediaSession' in navigator) {
                    navigator.mediaSession.playbackState = 'playing';
                }
            });

            audioElement.addEventListener('pause', () => {
                isPlaying.value = false;
                stopVisualization();
                if ('mediaSession' in navigator) {
                    navigator.mediaSession.playbackState = 'paused';
                }
            });

            audioElement.addEventListener('ended', () => {
                next(false);
            });

            audioElement.addEventListener('error', (e) => {
                console.error('Audio error:', e);
                handlePlayError();
            });
        }
    };

    const startVisualization = () => {
        if (!analyser || !audioContext) return;
        const bufferLength = analyser.frequencyBinCount;
        const dataArray = new Uint8Array(bufferLength);

        const animate = () => {
            if (!isPlaying.value) return;
            animationFrameId = requestAnimationFrame(animate);
            analyser?.getByteFrequencyData(dataArray);

            // Calculate average loudness
            let sum = 0;
            for (let i = 0; i < bufferLength; i++) {
                sum += dataArray[i];
            }
            loudness.value = sum / bufferLength;

            // Update spectrum
            spectrum.value = Array.from(dataArray);
        };
        animate();
    };

    const stopVisualization = () => {
        if (animationFrameId !== null) {
            cancelAnimationFrame(animationFrameId);
            animationFrameId = null;
        }
    };

    // --- Actions ---

    const setPlaylist = async (list: any[], startIndex = 0) => {
        playlist.value = list;
        currentIndex.value = startIndex;
        if (list.length > 0 && startIndex >= 0 && startIndex < list.length) {
            await playSong(list[startIndex]);
        }
    };

    const playFromList = async (song: Song, contextList: Song[]) => {
        if (addListMode.value === 'replace') {
            const index = contextList.findIndex(s => s.id === song.id);
            if (index !== -1) {
                await setPlaylist(contextList, index);
            } else {
                await setPlaylist([song], 0);
            }
        } else {
            playlist.value.push(song);
            const newIndex = playlist.value.length - 1;
            currentIndex.value = newIndex;
            await playSong(song);
        }
    };

    const playSong = async (song: Song, autoPlay = true) => {
        if (!song) return;
        initAudio();

        currentSong.value = song;
        const foundIndex = playlist.value.findIndex(s => s.id === song.id);
        if (foundIndex !== -1) {
            currentIndex.value = foundIndex;
        }

        updateMediaSession(song);

        if (audioContext && audioContext.state === 'suspended') {
            try { await audioContext.resume(); } catch { /* ignore */ }
        }

        // 1) URL：优先使用 song 自带有效 URL；否则走插件系统
        let playUrl = song.url;
        const isValidUrl = typeof playUrl === 'string' && playUrl.length > 0
            && (/^https?:\/\//i.test(playUrl) || playUrl.startsWith('data:') || playUrl.startsWith('blob:'));

        if (!isValidUrl) {
            try {
                useLogStore().debug('player', `通过音源插件获取播放URL: ${song.name} (${song.id || 'no-id'})`);
                const res = await pluginManager.getSongUrl(song);
                if (res?.success && res.url) {
                    playUrl = res.url;
                    song.url = res.url;
                    useLogStore().info('player', `已获取播放URL: ${song.name}`);
                } else {
                    useLogStore().warn('player', `未能获取播放URL: ${song.name}`, res);
                }
            } catch (e) {
                useLogStore().error('player', `插件获取URL异常: ${song.name}`, e as any);
                console.warn('[Player] 插件获取 URL 失败:', e);
            }
        }

        // 2) 歌词：用插件系统并行获取（不阻塞播放）
        fetchLyrics(song);

        if (playUrl && audioElement) {
            try {
                audioElement.src = playUrl;
                audioElement.load();
                if (autoPlay) {
                    await audioElement.play();
                    useLogStore().info('player', `开始播放: ${song.name} - ${song.artist}`);
                }
                playErrorCount.value = 0;
            } catch (e) {
                useLogStore().error('player', `播放失败: ${song.name}`, e as any);
                console.error('[Player] 播放失败:', e);
                if (autoPlay) handlePlayError();
            }
        } else {
            useLogStore().warn('player', `歌曲无可用 URL: ${song.name}`);
            console.warn('[Player] 歌曲无可用 URL:', song.name);
            MessagePlugin.warning('当前音源插件无法获取这首歌的播放地址').then();
            if (autoPlay) handlePlayError();
        }
    };

    const fetchLyrics = async (song: Song) => {
        lyrics.value = { lines: [] };
        if (!song || !song.id) return;
        try {
            const lyricData = await pluginManager.getLyric(song);
            if (lyricData && (lyricData.raw || lyricData.format)) {
                const parsed = parseAnyLyric(lyricData);
                if (Array.isArray(parsed) && parsed.length > 0) {
                    lyrics.value = { lines: parsed };
                    return;
                }
            }
            // 插件无歌词或解析为空 → 不弹提示打扰用户
        } catch (e) {
            console.error('[Player] 获取歌词失败:', e);
        }
    };

    const updateMediaSession = (song: Song) => {
        if (!('mediaSession' in navigator)) return;

        navigator.mediaSession.metadata = new MediaMetadata({
            title: song.name,
            artist: song.artist,
            album: song.albumName || '',
            artwork: song.picUrl ? [{ src: song.picUrl, sizes: '512x512', type: 'image/png' }] : []
        });

        navigator.mediaSession.setActionHandler('play', () => togglePlay());
        navigator.mediaSession.setActionHandler('pause', () => togglePlay());
        navigator.mediaSession.setActionHandler('previoustrack', () => prev());
        navigator.mediaSession.setActionHandler('nexttrack', () => next(true));
        navigator.mediaSession.setActionHandler('seekto', (details) => {
            if (details.seekTime != null) {
                seek(details.seekTime);
            }
        });
    };

    const next = async (manual = true) => {
        if (playlist.value.length === 0) return;
        let nextIndex = currentIndex.value;
        if (playMode.value === PlayMode.Single && !manual) {
            nextIndex = currentIndex.value;
        } else if (playMode.value === PlayMode.Random) {
            nextIndex = Math.floor(Math.random() * playlist.value.length);
        } else {
            nextIndex = (currentIndex.value + 1) % playlist.value.length;
        }
        currentIndex.value = nextIndex;
        await playSong(playlist.value[nextIndex]);
    };

    const prev = async () => {
        if (playlist.value.length === 0) return;
        let prevIndex = currentIndex.value;
        if (playMode.value === PlayMode.Random) {
            prevIndex = Math.floor(Math.random() * playlist.value.length);
        } else {
            prevIndex = (currentIndex.value - 1 + playlist.value.length) % playlist.value.length;
        }
        currentIndex.value = prevIndex;
        await playSong(playlist.value[prevIndex]);
    };

    const handlePlayError = async () => {
        playErrorCount.value++;
        if (playlist.value.length === 0) {
            isPlaying.value = false;
            playErrorCount.value = 0;
            return;
        }
        if (playErrorCount.value >= MAX_RETRY_COUNT) {
            audioElement?.pause();
            isPlaying.value = false;
            MessagePlugin.error('连续多次播放失败，已停止播放').then();
            playErrorCount.value = 0;
        } else {
            MessagePlugin.warning(`播放失败，尝试播放下一首 (${playErrorCount.value}/${MAX_RETRY_COUNT})`).then();
            next(false);
        }
    };

    const togglePlay = async () => {
        if (!audioElement) {
            initAudio();
        }
        if (audioElement) {
            if (isPlaying.value) {
                audioElement.pause();
            } else {
                await audioElement.play();
            }
        }
    };

    const setVolume = async (vol: number) => {
        volume.value = vol;
        if (audioElement) {
            audioElement.volume = vol / 100;
        }
    };

    const seek = async (time: number) => {
        if (audioElement) {
            audioElement.currentTime = time / 1000;
        }
    };

    const toggleMode = () => {
        if (playMode.value === PlayMode.List) playMode.value = PlayMode.Single;
        else if (playMode.value === PlayMode.Single) playMode.value = PlayMode.Random;
        else playMode.value = PlayMode.List;
    };

    const toggleFullScreen = () => {
        isPlayerFullScreen.value = !isPlayerFullScreen.value;
    };

    const togglePlaylist = () => {
        showPlaylist.value = !showPlaylist.value;
    };

    const removeFromPlaylist = (index: number) => {
        if (index < 0 || index >= playlist.value.length) return;
        const wasCurrent = index === currentIndex.value;
        playlist.value.splice(index, 1);
        if (wasCurrent) {
            if (playlist.value.length === 0) {
                currentIndex.value = -1;
                currentSong.value = null;
                isPlaying.value = false;
                audioElement?.pause();
            } else {
                currentIndex.value = Math.min(currentIndex.value, playlist.value.length - 1);
                const newSong = playlist.value[currentIndex.value];
                currentSong.value = newSong;
                if (isPlaying.value && newSong) {
                    playSong(newSong).then();
                }
            }
        } else if (index < currentIndex.value) {
            currentIndex.value -= 1;
        }
    };

    const clearPlaylist = () => {
        playlist.value = [];
        currentIndex.value = -1;
        currentSong.value = null;
        isPlaying.value = false;
        audioElement?.pause();
    };

    // Persistence Listeners
    watch(() => [playlist.value, currentIndex.value], () => {
        localStorage.setItem('qz-player-playlist', JSON.stringify(playlist.value));
        localStorage.setItem('qz-player-index', currentIndex.value.toString());
    }, { deep: true });

    watch(addListMode, (newMode) => {
        localStorage.setItem('qz-player-add-mode', newMode);
    });

    // Restore initial state
    if (playlist.value.length > 0 && currentIndex.value >= 0 && currentIndex.value < playlist.value.length) {
        const restoredSong = playlist.value[currentIndex.value];
        if (restoredSong) {
            // Do not auto-play on restore
            currentSong.value = restoredSong;
        }
    }

    return {
        isPlaying,
        currentSong,
        volume,
        duration,
        currentTime,
        playlist,
        playMode,
        loudness,
        spectrum,
        isPlayerFullScreen,
        showPlaylist,
        setPlaylist,
        playSong,
        next,
        prev,
        togglePlay,
        setVolume,
        seek,
        toggleMode,
        toggleFullScreen,
        togglePlaylist,
        removeFromPlaylist,
        clearPlaylist,
        currentIndex,
        lyrics,
        fetchLyrics,
        addListMode,
        playFromList,
        hideLyricView
    };
});
