import { assetUrl } from '@/commons/assets'

const game1MusicUrl = assetUrl('game1.mp3')
const game2MusicUrl = assetUrl('game2.mp3')
const game3Music1Url = assetUrl('game3_1.mp3')
const game3Music2Url = assetUrl('game3_2.mp3')
const game6Music1Url = assetUrl('game6_1.mp3')
const game6Music2Url = assetUrl('game6_2.mp3')
const go321 = assetUrl('321go.mp3')

console.log('[Music] 音频文件路径:')
console.log('  game1:', game1MusicUrl)
console.log('  game2:', game2MusicUrl)
console.log('  game3_1 (金币):', game3Music1Url)
console.log('  game3_2 (炸弹):', game3Music2Url)
console.log('  game6_1:', game6Music1Url)
console.log('  game6_2:', game6Music2Url)
console.log('  321go:', go321)


const effectTemplates = new Map<string, HTMLAudioElement>()
const playingEffects = new Set<HTMLAudioElement>()
const exclusiveEffects = new Map<string, HTMLAudioElement>()
let pendingPlay = false
let pendingRetry: (() => void) | null = null


export function stopAllMusic() {
    stopGame1Music();
    stopGame2Music();
    stopGame3Music();
    // stopGame4Music();
    // stopGame5Music();
    stopGame6Music();
    playingEffects.clear();
}



function getEffectTemplate(music: string) {
    let template = effectTemplates.get(music)

    if (!template) {
        template = new Audio(music)
        template.loop = false
        template.preload = 'auto'
        template.volume = 1
        template.load()
        effectTemplates.set(music, template)
        
        // 注册用户交互监听器，解决浏览器自动播放策略
        const resumeAudio = async () => {
            // 尝试播放一个静音的音频来激活 AudioContext
            try {
                const silentAudio = new Audio()
                silentAudio.src = 'data:audio/mp3;base64,SUQzBAAAAAAAIgRTU0UAAAAPAAADTGF2ZjU3LjkyLjEzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//uQZAAAA'
                await silentAudio.play()
                silentAudio.pause()
                console.log('[Music] 音频已通过用户交互激活')
            } catch (e) {
                console.log('[Music] 音频激活失败:', e)
            }
            window.removeEventListener('touchstart', resumeAudio)
            window.removeEventListener('click', resumeAudio)
        }
        
        window.addEventListener('touchstart', resumeAudio, { once: true })
        window.addEventListener('click', resumeAudio, { once: true })
    }

    return template
}

function releaseEffect(audio: HTMLAudioElement) {
    audio.pause()
    audio.removeAttribute('src')
    audio.load()
    playingEffects.delete(audio)
}

function clearPendingRetry() {
    if (pendingRetry) {
        window.removeEventListener('pointerdown', pendingRetry)
        window.removeEventListener('keydown', pendingRetry)
        pendingRetry = null
    }
    pendingPlay = false
}

function setPendingRetry(retry: () => void) {
    clearPendingRetry()
    pendingPlay = true
    pendingRetry = retry
    window.addEventListener('pointerdown', retry, { once: true })
    window.addEventListener('keydown', retry, { once: true })
}

async function playEffect(music: string, retry: () => void, exclusive = false) {
    if (exclusive && exclusiveEffects.has(music)) {
        return
    }

    const audio = getEffectTemplate(music).cloneNode(true) as HTMLAudioElement
    audio.loop = false
    audio.volume = 1
    playingEffects.add(audio)
    if (exclusive) {
        exclusiveEffects.set(music, audio)
    }

    const release = () => {
        if (exclusiveEffects.get(music) === audio) {
            exclusiveEffects.delete(music)
        }
        releaseEffect(audio)
    }
    audio.addEventListener('ended', release, { once: true })
    audio.addEventListener('error', release, { once: true })

    try {
        await audio.play()
        if (pendingRetry === retry) {
            clearPendingRetry()
        }
    } catch {
        release()

        if (!pendingPlay) {
            setPendingRetry(retry)
        }
    }
}

function stopEffects() {
    clearPendingRetry()
    for (const audio of playingEffects) {
        releaseEffect(audio)
    }
    playingEffects.clear()
    exclusiveEffects.clear()
}

export async function playGame1Music() {
    await playEffect(game1MusicUrl, playGame1Music)
}

export function stopGame1Music() {
    window.removeEventListener('pointerdown', playGame1Music)
    window.removeEventListener('keydown', playGame1Music)
    stopEffects()
}

/*  3 2 1 go */
export async function playCountdownMusic() {
    await playEffect(go321, playCountdownMusic)
}

export function stopCountdownMusic() {
    window.removeEventListener('pointerdown', playCountdownMusic)
    window.removeEventListener('keydown', playCountdownMusic)
    stopEffects()
}

export async function playGame2Music() {
    await playEffect(game2MusicUrl, playGame2Music, true)
}

export function stopGame2Music() {
    window.removeEventListener('pointerdown', playGame2Music)
    window.removeEventListener('keydown', playGame2Music)
    stopEffects()
}
/*
接到红包3-1
接到炸弹3-2
*/
export async function playGame3Music(index: number) {
    let arr: [string, string, string] = ['', game3Music1Url, game3Music2Url];
    const music = arr[index]

    if (!music) {
        return
    }

    const retry = () => { playGame3Music(index) }
    await playEffect(music, retry)
}

export function stopGame3Music() {
    stopEffects()
}


/*
打地鼠击中爆炸6-1
打小白兔眩晕6-2
*/
export async function playGame6Music(index: number) {
    let arr: [string, string, string] = ['', game6Music1Url, game6Music2Url];
    const music = arr[index]

    if (!music) {
        return
    }

    const retry = () => { playGame6Music(index) }
    await playEffect(music, retry)
}

export function stopGame6Music() {
    stopEffects()
}
