import { EventBus } from './bus.js'
import axios from '@nextcloud/axios'
import { decodeUrl } from '../utils/url.js'
import { formatEpisodeTimestamp } from '../utils/time.js'
import { generateUrl } from '@nextcloud/router'
import router from '../router.js'
import store from './main.js'

const audio = new Audio()
audio.ondurationchange = () => store.commit('player/duration', audio.duration)
audio.onended = () => store.dispatch('player/stop')
audio.onloadeddata = () => store.commit('player/loaded', true)
audio.onplay = () => store.dispatch('player/play')
audio.onpause = () => store.dispatch('player/pause')
audio.onratechange = () => store.commit('player/rate', audio.playbackRate)
audio.onseeked = () => store.commit('player/currentTime', audio.currentTime)
audio.ontimeupdate = () => store.commit('player/currentTime', audio.currentTime)
audio.onvolumechange = () => store.commit('player/volume', audio.volume)

export const player = {
	namespaced: true,
	state: {
		currentTime: null,
		duration: null,
		episode: null,
		loaded: false,
		paused: null,
		podcastUrl: null,
		volume: 1,
		rate: 1,
		started: 0,
	},
	mutations: {
		action: (state, action) => {
			state.episode.action = action

			if (action && action.position && action.position < action.total) {
				audio.currentTime = action.position
				state.started = audio.currentTime
			}
		},
		currentTime: (state, currentTime) => {
			state.currentTime = currentTime
		},
		duration: (state, duration) => {
			state.duration = duration
		},
		episode: (state, episode) => {
			state.episode = episode

			if (episode) {
				state.podcastUrl = decodeUrl(router.currentRoute.params.url)
				audio.src = episode.url
				audio.load()
				audio.play()

				if (episode.action && episode.action.position && episode.action.position < episode.action.total) {
					audio.currentTime = episode.action.position
					state.started = audio.currentTime
				}
			} else {
				state.loaded = false
				state.podcastUrl = null
				audio.src = ''
			}
		},
		loaded: (state, loaded) => {
			state.loaded = loaded
		},
		paused: (state, paused) => {
			state.paused = paused
		},
		volume: (state, volume) => {
			state.volume = volume
		},
		rate: (state, rate) => {
			state.rate = rate
		},
		started: (state, started) => {
			state.started = started
		},
	},
	actions: {
		load: async (context, episode) => {
			context.commit('episode', episode)
			try {
				const action = await axios.get(generateUrl('/apps/repod/episodes/action?url={url}', { url: episode.url }))
				context.commit('action', action.data)
			} catch {}
		},
		pause: (context) => {
			audio.pause()
			context.commit('paused', true)
			context.dispatch('time')
		},
		play: (context) => {
			audio.play()
			context.commit('paused', false)
			context.commit('started', audio.currentTime)
		},
		seek: (context, currentTime) => {
			audio.currentTime = currentTime
			context.dispatch('time')
		},
		stop: (context) => {
			context.dispatch('pause')
			context.commit('episode', null)
		},
		time: async (context) => {
			const episode = context.state.episode
			episode.action = {
				podcast: context.state.podcastUrl,
				episode: context.state.episode.url,
				guid: context.state.episode.guid,
				action: 'play',
				timestamp: formatEpisodeTimestamp(new Date()),
				started: Math.round(context.state.started),
				position: Math.round(audio.currentTime),
				total: Math.round(audio.duration),
			}
			axios.post(generateUrl('/apps/gpoddersync/episode_action/create'), [episode.action])
			EventBus.$emit('updateEpisodesList', episode)
		},
		volume: (_, volume) => {
			audio.volume = volume
		},
		rate: (_, rate) => {
			audio.playbackRate = rate
		},
	},
}

setInterval(() => {
	if (player.state.paused === false) {
		store.dispatch('player/time')
	}
}, 40000)
