import { Howl, Howler } from 'howler'
import axios from 'axios'
import helper from '@/includes/helper'

export default {
    state: {
        currentSong: {},
        sound: {},
        seek: '0:00',
        duration: '0:00',
        playerProgress: '0%',
        playlist: [],

        current_playlist: [],
        my_playlist: [],
        favorite_playlist: [],
        playlist_id: 0,
        history_group: [],
        index: 0,
        volume: 0.5,
        tab: 'now',

        cursor_favorite: null,
        cursor_loaded: null,
        local_current_playlist: JSON.parse(window.localStorage.getItem('local_current_playlist')),
        local_current_playlist_song: JSON.parse(window.localStorage.getItem('local_current_playlist_song')),
        local_current_playlist_id: parseInt(window.localStorage.getItem('local_current_playlist_id'), 10),
    },
    getters: {
        playing: (state) => {
            if (state.sound.playing) {
                return state.sound.playing()
            }
            return false
        },
        count_playlist: (state) => {
            return state.playlist.length
        },
        volume_step: (state) => {
            if (localStorage.volume_player) {
                return localStorage.volume_player
            }
            return state.volume
        },
        tab_now: (state) => {
            return state.tab === 'now'
        },

        lastFavID: (state) => {
            return state.favorite_playlist[state.favorite_playlist.length - 1]?.id
        },

        lastLoadedID: (state) => {
            return state.my_playlist[state.my_playlist.length - 1]?.id
        },

    },
    mutations: {
        saveStorageCurrentPlaylist(state, [music, playlist, playlist_id]) {

            state.local_current_playlist = playlist
            state.local_current_playlist_song = music
            state.local_current_playlist_id = playlist_id

            window.localStorage.setItem('local_current_playlist', JSON.stringify(playlist))
            window.localStorage.setItem('local_current_playlist_song', JSON.stringify(music))
            window.localStorage.setItem('local_current_playlist_id', playlist_id)

        },

        // resetPlaylistNow(state, payload) {
        //     state.cursor_favorite = null;
        //     state.current_playlist = playlist;
        //     state.favorite_playlist = [];
        // },

        resetPlaylistNow(state) {
            state.playlist = state.current_playlist

            state.cursor_favorite = null
            state.cursor_loaded = null
            state.favorite_playlist = []
            state.my_playlist = []
        },

        putCursor(state, payload) {
            if (state.tab === 'favorite') {
                state.cursor_favorite = payload
            }
            if (state.tab === 'loaded') {
                state.cursor_loaded = payload
            }
        },

        savePagination(state, payload) {
            if (state.tab === 'favorite') {
                for (const prop in payload) {
                    state.favorite_playlist.push(payload[prop])
                }
            }
            if (state.tab === 'loaded') {
                for (const prop in payload) {
                    state.my_playlist.push(payload[prop])
                }
            }

        },

        clearPlaylist(state) {
            state.playlist = []
        },
        replaceTabName(state, payload) {
            state.tab = payload
            if (payload === 'now') {
                state.playlist_id = state.local_current_playlist_id
            } else {
                state.playlist_id = 0
            }
        },
        replacePlaylist(state, payload) {
            state.playlist = payload
        },
        saveMyPlaylist(state, payload) {
            state.my_playlist = payload
        },
        saveFavoritePlaylist(state, payload) {
            state.favorite_playlist = payload
        },
        onlyPlay(state) {
            if (state.sound instanceof Howl) {
                state.currentSong.playing = true
                state.sound.play()
            }
        },
        onlyStop(state) {
            if (state.sound instanceof Howl) {
                state.currentSong.playing = false
                state.sound.pause()
            }
        },
        togglePlayMusic(state) {
            if (state.sound instanceof Howl) {
                if (state.sound.playing()) {
                    state.currentSong.playing = false
                    state.sound.pause()
                } else {
                    state.currentSong.playing = true
                    state.sound.play()
                }
            } else {
                state.sound = new Howl(state.sound)
                state.currentSong.playing = true
                Howler.volume(state.volume)
                state.sound.play()
            }
        },
        initVolume(state) {
            Howler.volume(state.volume)
        },
        updateVolume(state, payload) {
            state.volume = payload
            localStorage.volume_player = payload

            if (state.sound instanceof Howl) {
                Howler.volume(payload)
            }
        },

        updatePosition(state) {
            state.seek = helper.formatTime(state.sound.seek())
            state.duration = helper.formatTime(state.sound.duration())
            state.playerProgress = `${(state.sound.seek() / state.sound.duration()) * 100}%`
        },

        currentPlaylistLoad(state, [music, playlist, playlist_id]) {
            playlist.forEach((track) => {
                track.playing = false
            })
            music.playing = true

            state.playlist = playlist
            state.playlist_id = playlist_id
            state.index = playlist.findIndex(track => track.id === music.id)

            state.current_playlist = playlist


        },
        howlReplace(state, [howl, music]) {
            if (state.sound instanceof Howl) {
                state.sound.unload()
            }
            state.sound = howl
            state.currentSong = music
            state.index = state.playlist.findIndex(track => track.id === music.id)
        },
    },
    actions: {
        tabName({ state, commit }, payload) {
            commit('replaceTabName', payload)

            if (payload === 'favorite') {
                if (state.favorite_playlist.length) {
                    commit('replacePlaylist', state.favorite_playlist)
                }
            }

            if (payload === 'loaded') {
                if (state.my_playlist.length) {
                    commit('replacePlaylist', state.my_playlist)
                }
            }
            if (payload === 'now') {
                if (state.current_playlist.length) {
                    commit('replacePlaylist', state.current_playlist)
                }
            }
        },

        initLoadedPlaylist({ state, commit }) {
            if (state.my_playlist.length > 0) {
                return
            }
            return new Promise(resolve => {
                commit('clearPlaylist')
                axios.get('/loaded-playlist').then(response => response.data)
                    .then(playlist => {
                        commit('putCursor', playlist.cursor)
                        commit('saveMyPlaylist', playlist.collection)
                        commit('replacePlaylist', playlist.collection)
                        commit('initVolume')
                        resolve(playlist)
                    })
                    .catch(() => {
                        //commit(mutationTypes.getArticleFailure)
                    })
            })
        },


        initFavoritedPlaylist({ state, commit }) {
            if (state.favorite_playlist.length > 0) {
                return Promise.resolve()
            }
            return new Promise(resolve => {
                commit('clearPlaylist')
                axios.get('/favorited-playlist').then(response => response.data)
                    .then(playlist => {
                        commit('putCursor', playlist.cursor)
                        commit('saveFavoritePlaylist', playlist.collection)
                        commit('replacePlaylist', playlist.collection)
                        commit('initVolume')
                        resolve(playlist)
                    })
                    .catch(() => {
                        //commit(mutationTypes.getArticleFailure)
                    })
            })
        },


        paginationFavPlaylist({ state, commit }) {
            if (state.cursor_favorite === null) {
                return Promise.resolve(null)
            }
            return new Promise(resolve => {
                const url = `/favorited-playlist?cursor=${state.cursor_favorite}`
                axios.get(url).then(response => response.data)
                    .then(playlist => {
                        commit('putCursor', playlist.cursor)
                        commit('savePagination', playlist.collection)
                        resolve(playlist)
                    })
                    .catch(() => {
                        //commit(mutationTypes.getArticleFailure)
                    })
            })
        },


        paginationLoadedPlaylist({ state, commit }) {
            if (state.cursor_loaded === null) {
                return Promise.resolve(null)
            }
            return new Promise(resolve => {
                const url = `/loaded-playlist?cursor=${state.cursor_loaded}`
                axios.get(url).then(response => response.data)
                    .then(playlist => {
                        commit('putCursor', playlist.cursor)
                        commit('savePagination', playlist.collection)
                        resolve(playlist)
                    })
                    .catch(() => {
                        //commit(mutationTypes.getArticleFailure)
                    })
            })
        },

        async loadExsitPlaylist({ state, commit, dispatch }) {
            if (state.local_current_playlist_id) {
                //dispatch('instanceHowl', state.local_current_playlist_song);
                dispatch('instanceHowlLazy', state.local_current_playlist_song)
                commit('currentPlaylistLoad', [
                    state.local_current_playlist_song,
                    state.local_current_playlist,
                    state.local_current_playlist_id
                ])
            }
        },
        async skipToIndexByMusic({ state, commit, dispatch }, payload) {
            commit('onlyStop')
            dispatch('instanceHowl', payload)
            commit('onlyPlay')

            if (state.tab === 'now') {
                commit('saveStorageCurrentPlaylist', [payload, state.playlist, state.playlist_id])
            }
        },

        async defaultPlaylistReset({ commit }) {
            commit('replaceTabName', 'now')
            commit('resetPlaylistNow')
        },

        async newCurrentPlaylist({ commit, dispatch }, [music, playlist, playlist_id]) {
            commit('replaceTabName', 'now')
            commit('onlyStop')
            dispatch('instanceHowl', music)
            commit('currentPlaylistLoad', [music, playlist, playlist_id])
            commit('initVolume')
            commit('onlyPlay')

            commit('saveStorageCurrentPlaylist', [music, playlist, playlist_id])

        },


        async instanceHowlLazy({ dispatch, commit }, payload) {
            let objectHowl = {
                src: [payload.url],
                html5: true,
                onend: () => {
                    dispatch('skipTrack', 'next')
                },
                onplay: () => {
                    requestAnimationFrame(() => {
                        dispatch('progress')
                    })
                },
            }
            commit('howlReplace', [objectHowl, payload])
        },

        async instanceHowl({ dispatch, commit }, payload) {
            let objectHowl = {
                src: [payload.url],
                html5: true,
                //preload: false,
                onend: () => {
                    dispatch('skipTrack', 'next')
                },
                onplay: () => {
                    requestAnimationFrame(() => {
                        dispatch('progress')
                    })
                },
            }
            objectHowl = new Howl(objectHowl)
            commit('howlReplace', [objectHowl, payload])
        },

        async skipTrack({ state, dispatch }, payload) {
            if (!state.playlist.length) {
                return
            }

            let index = 0
            if (payload === 'next') {
                index = state.index + 1
                if (index >= state.playlist.length) {
                    index = 0
                }
            } else {
                index = state.index - 1
                if (index < 0) {
                    index = state.playlist.length - 1
                }
            }
            dispatch('skipToIndexByMusic', state.playlist[index])
        },

        async changeVolume({ commit }, payload) {
            commit('updateVolume', payload)
        },
        async toggleAudio({ state, commit }) {
            // if (!state.sound.playing) {
            //     return;
            // }
            commit('togglePlayMusic')
        },
        progress({ commit, state, dispatch }) {
            commit('updatePosition')
            if (state.sound.playing()) {
                requestAnimationFrame(() => {
                    dispatch('progress')
                })
            }
        },
        updateSeek({ state, dispatch }, payload) {
            if (!state.sound.playing) {
                return
            }

            const { x, width } = payload.currentTarget.getBoundingClientRect()
            // Document = 2000, Timeline = 1000, Click = 500, Distance = 500
            const clickX = payload.clientX - x
            const percentage = clickX / width
            const seconds = state.sound.duration() * percentage

            state.sound.seek(seconds)

            state.sound.once('seek', () => {
                dispatch('progress')
            })
        },
    },
}
