import { computed, watchEffect } from 'vue'
import { useStore } from 'vuex'
import { useApp } from '@/app'
import browser from './browser'
// const sounds$ = document.createElement('div')
// sounds$.className = 'audios'
// sounds$.style.display = 'none'
// sounds$.style.position = 'absolute'
// sounds$.style.zIndex = -1
// document.body.appendChild(sounds$)

const retryPlay = player => {
    function onclick() {
        if (player.pauseFromOther) {
            return
        }
        $player.removeEventListener('click', onclick)
        $player.removeEventListener('touchstart', onclick)
        player.sound.play()
    }
    const $player = document.querySelector('.player')
    $player.addEventListener('click', onclick)
    $player.addEventListener('touchstart', onclick)
}

class AudioPlayer extends KanKan.MITT.Emiter {
    constructor(name) {
        super()
        // const loadeddata = e => {
        //     this.duration = this.sound.duration
        // }
        // const timeupdate = e => {}

        // this.sound = document.createElement('audio')
        // this.sound.className = `audio-${name}`
        // //this.sound.autoplay = 'autoplay'
        // this.sound.preload = true
        // this.sound.controls = true
        // this.sound.addEventListener('loadeddata', loadeddata)
        // this.sound.addEventListener('timeupdate', timeupdate)
        // this.duration = 0
        // this.isPlay = false
        // this.isPause = false
        // this.pauseFromOther = false

        // sounds$.appendChild(this.sound)

        this.isPlay = false
        this.isPause = false
        this.pauseFromOther = false

        this._create = (src, options = {}) => {
            return new Promise((resolve, reject) => {
                this._remove()
                setTimeout(() => {
                    this.sound = new Howl({
                        preload: true,
                        src: [src],
                        loop: options.loop || false,
                        html5: options.html5 || false,
                        onloaderror(id, err) {
                            if (!options.html5) {
                                reject(err)
                            }
                        },
                        onplayerror: function (err) {
                            if (!options.html5) {
                                reject(err)
                            }
                        },
                        onload() {
                            if (!options.html5) {
                                resolve()
                            }
                        },
                        onplay: () => {
                            this.isPlay = true
                            this.isPause = false
                            this.emit('play')
                        },
                        onpause: () => {
                            this.isPause = true
                            this.isPlay = false
                            this.emit('pause')
                        },
                        onstop: () => {
                            this.isPause = false
                            this.isPlay = false
                            this.emit('pause')
                        },
                    })
                    if (options.html5) {
                        resolve()
                    }
                }, 50)
            })
        }

        this._remove = () => {
            if (this.sound) {
                if (this.isPlay) {
                    this.sound.stop()
                }
                this.sound.unload()
                this.sound = null
            }
        }
    }
    play() {
        this.sound.play()
    }
    pause(fromOther) {
        if (!this.isPlay) {
            return
        }
        this.sound.pause()
        if (fromOther) {
            this.pauseFromOther = true
        }
    }
    stop() {
        this.sound.stop()
    }
    resume() {
        if (this.pauseFromOther) {
            this.pauseFromOther = false
            if (!this.isPlay) {
                this.play()
            }
        }
    }
    source(src, options = {}) {
        this._init(src, options)
    }
}

class MusicPlayer extends AudioPlayer {
    constructor() {
        super('music')
        const store = useStore()
        const source = computed(() => {
            let music = store.getters['scene/musicURL']
            if (music) {
                return {
                    src: music,
                    loop: true,
                }
            }
            return null
        })

        const ready = () => {
            if (typeof parent.WeixinJSBridge !== 'undefined') {
                parent.WeixinJSBridge.invoke(
                    'getNetworkType',
                    {},
                    e => {
                        this.play()
                    },
                    false
                )
            }
        }

        this.isLock = true
        this.watchPlay = () => {
            if (this.isLock) {
                return
            }
            if (source.value && source.value.src) {
                this._create(source.value.src, {
                    loop: source.value.loop,
                    html5: false,
                })
                    .then(() => {
                        if (browser.detectWeixin()) {
                            if (typeof parent.WeixinJSBridge !== 'undefined') {
                                ready()
                            } else {
                                parent.document.addEventListener('WeixinJSBridgeReady', ready)
                            }
                        } else {
                            retryPlay(this)
                        }
                    })
                    .catch(err => {
                        console.error('err', err)
                    })
            } else {
                setTimeout(() => {
                    this._remove()
                }, 50)
            }
        }

        watchEffect(() => this.watchPlay())
    }
}

class SoundPlayer extends AudioPlayer {
    constructor() {
        super('sound')
        const store = useStore()
        const source = computed(() => {
            return store.getters.sound
        })

        watchEffect(() => {
            if (this.sound.src) {
                this.sound.pause()
            }
            if (source.value && source.value.src) {
                this.sound.src = source.value.src
                this.sound.loop = source.value.loop || false
                this.play()
            } else {
                this.sound.removeAttribute('src')
                this.sound.removeAttribute('loop')
                this.pause()
            }
        })
    }
}

export function useMusicPlayer() {
    if (useMusicPlayer.player === void 0) {
        useMusicPlayer.player = new MusicPlayer()
        useApp().then(app => {
            app.Scene.on('loaded', () => {
                useMusicPlayer.player.isLock = false
                useMusicPlayer.player.watchPlay()
            })
        })
    }
    return useMusicPlayer.player
}

export function useSoundPlayer() {
    if (useSoundPlayer.player === void 0) {
        useSoundPlayer.player = new SoundPlayer()
    }
    return useSoundPlayer.player
}

function wxConfig() {
    wx.config({
        // 配置信息, 即使不正确也能使用 wx.ready
        debug: false,
        appId: '',
        timestamp: 1,
        nonceStr: '',
        signature: '',
        jsApiList: [],
    })
}
