<!--
  - @copyright Copyright (c) 2020 Jonas Heinrich
  -
  - @author Jonas Heinrich <onny@project-insanity.org>
  -
  - @license GNU AGPL version 3 or any later version
  -
  - This program is free software: you can redistribute it and/or modify
  - it under the terms of the GNU Affero General Public License as
  - published by the Free Software Foundation, either version 3 of the
  - License, or (at your option) any later version.
  -
  - This program is distributed in the hope that it will be useful,
  - but WITHOUT ANY WARRANTY; without even the implied warranty of
  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  - GNU Affero General Public License for more details.
  -
  - You should have received a copy of the GNU Affero General Public License
  - along with this program. If not, see <http://www.gnu.org/licenses/>.
  -
  -->

<template>
	<Content app-name="podcast">
		<Navigation
			:station-data="tableData" />
		<AppContent>
			<div class="podcastHeader">
				<div
					class="podcastImage"
					:style="{ backgroundImage: `url(${podcast.imgURL})` }" />
				<div class="podcastDescription">
					<h1>{{ podcast.title }}</h1>
					<div class="podcastAuthor">
						by <a href="#">{{ podcast.author }}</a>
					</div>
					<div>{{ podcast.description }}</div>
					<ul
						v-for="(category, idx) in podcast.categories"
						:key="idx"
						:class="podcastCategory">
						<li>{{ podcast.categories[idx] }}</li>
					</ul>
				</div>
			</div>
			<Table
				v-show="!pageLoading && podcast.episodes.length > 0"
				v-resize="onResize"
				:station-data="podcast.episodes"
				:favorites="favorites"
				@doPlay="doPlay"
				@doFavor="doFavor"
				@toggleSidebar="toggleSidebar" />
			<EmptyContent
				v-if="pageLoading"
				icon="icon-loading" />
			<EmptyContent
				v-if="tableData.length === 0 && !pageLoading"
				:icon="emptyContentIcon">
				{{ emptyContentMessage }}
				<template #desc>
					{{ emptyContentDesc }}
				</template>
			</EmptyContent>
		</AppContent>
		<Sidebar
			:show-sidebar="showSidebar"
			:sidebar-station="sidebarStation"
			@toggleSidebar="toggleSidebar" />
	</Content>
</template>

<script>
import Content from '@nextcloud/vue/dist/Components/Content'
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
import Navigation from '../components/Navigation'
import Table from '../components/Table'
import Sidebar from '../components/Sidebar'
import { Howl, Howler } from 'howler'

import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
import axios from '@nextcloud/axios'

let audioPlayer = null
const requesttoken = axios.defaults.headers.requesttoken

export default {
	name: 'Episode',
	components: {
		Navigation,
		Content,
		AppContent,
		Table,
		EmptyContent,
		Sidebar,
	},
	data: () => ({
		podcast: {},
		tableData: [],
		pageLoading: false,
		favorites: [],
		showSidebar: false,
		sidebarStation: {},
		queryParams: {},
	}),
	computed: {
		player() {
			return this.$store.state.player
		},
		emptyContentMessage() {
			if (this.$route.name === 'FAVORITES') {
				return t('podcast', 'No favorites yet')
			} else if (this.$route.name === 'RECENT') {
				return t('podcast', 'No recent stations yet')
			} else if (this.$route.name === 'SEARCH') {
				return t('podcast', 'No search results')
			}
			return 'No stations here'
		},
		emptyContentIcon() {
			if (this.$route.name === 'FAVORITES') {
				return 'icon-star'
			} else if (this.$route.name === 'RECENT') {
				return 'icon-recent'
			} else if (this.$route.name === 'SEARCH') {
				return 'icon-search'
			}
			return 'icon-podcast'
		},
		emptyContentDesc() {
			if (this.$route.name === 'FAVORITES') {
				return t('podcast', 'Stations you mark as favorite will show up here')
			} else if (this.$route.name === 'RECENT') {
				return t('podcast', 'Stations you recently played will show up here')
			} else if (this.$route.name === 'SEARCH') {
				return t('podcast', 'No stations were found matching your search term')
			}
			return t('podcast', 'No stations here')
		},
	},
	watch: {
		$route: 'onRoute',
		'player.volume'(newVolume, oldVolume) {
			if (audioPlayer !== null) {
				audioPlayer.volume(newVolume)
			}
		},
		'player.isPaused'(newState, oldState) {
			if (newState === true && audioPlayer !== null) {
				audioPlayer.pause()
			} else if (newState === false && audioPlayer !== null) {
				audioPlayer.play()
			}
		},
	},
	created() {
		this.loadSettings()
		this.loadFavorites()
	},
	mounted() {
		this.onRoute()
		this.scroll()
	},
	methods: {

		onResize({ width, height }) {
			const contentHeight = document.getElementById('app-content-vue').scrollHeight
			const tableHeight = height
			if (tableHeight < contentHeight) {
				this.preFill()
			}
		},

		preFill() {
			const route = this.$route
			console.log(route)
			// this.queryPodcast(route.name)
		},

		async onRoute() {
			this.tableData = []
			this.pageLoading = true
			const podcastId = this.$route.params.id
			this.queryPodcast(podcastId)
		},

		/**
			 * Favor a new station by sending the information to the server
			 * @param {Object} station Station object
			 */
		async doFavor(station) {
			if (this.favorites.flat().includes(station.stationuuid)) {
				let stationid = null
				try {
					for (let i = 0, len = this.favorites.length; i < len; i++) {
						if (station.stationuuid === this.favorites[i][1]) {
							stationid = this.favorites[i][0]
						}
					}
					axios.defaults.headers.requesttoken = requesttoken
					await axios
						.delete(generateUrl(`/apps/podcast/api/favorites/${stationid}`))
						.then(response => {
							this.favorites = this.favorites.filter(item => item[1] !== station.stationuuid)
						})
				} catch (error) {
					showError(t('podcast', 'Could not remove station from favorites'))
				}
			} else {
				try {
					let stationSrc = ''
					if (!station.url_resolved) {
						stationSrc = station.urlresolved
					} else {
						stationSrc = station.url_resolved
					}
					const stationMap = {
						id: -1,
						name: station.name.toString(),
						urlresolved: stationSrc.toString(),
						favicon: station.favicon.toString(),
						stationuuid: station.stationuuid.toString(),
						bitrate: station.bitrate.toString(),
						country: station.country.toString(),
						language: station.language.toString(),
						homepage: station.homepage.toString(),
						codec: station.codec.toString(),
						tags: station.tags.toString(),
					}
					axios.defaults.headers.requesttoken = requesttoken
					await axios
						.post(generateUrl('/apps/podcast/api/favorites'), stationMap)
						.then(response => {
							this.favorites.push([response.data.id, station.stationuuid])
						})
				} catch (error) {
					showError(t('podcast', 'Could not favor station'))
				}
			}
		},

		/**
			 * Start playing a podcast station and counting the playback
			 * @param {Object} station Station object
			 */
		async doPlay(station) {
			const vm = this

			vm.$store.dispatch('isBuffering', true)

			if (audioPlayer !== null) {
				audioPlayer.fade(vm.player.volume, 0, 500)
			}
			vm.$store.dispatch('setTitle', station.name)

			let stationSrc = ''
			if (!station.url_resolved) {
				stationSrc = station.urlresolved
			} else {
				stationSrc = station.url_resolved
			}
			Howler.unload()
			audioPlayer = new Howl({
				src: stationSrc,
				html5: true,
				volume: vm.player.volume,
				onplay() {
					vm.$store.dispatch('isPlaying', true)
					vm.$store.dispatch('isBuffering', false)
				},
				onpause() {
					vm.$store.dispatch('isPlaying', false)
					vm.$store.dispatch('isBuffering', false)
				},
				onend() {
					showError(t('podcast', 'Lost connection to podcast station, retrying ...'))
					vm.$store.dispatch('isPlaying', false)
					vm.$store.dispatch('isBuffering', true)
				},
			})
			audioPlayer.unload()
			audioPlayer.play()
			audioPlayer.fade(0, vm.player.volume, 500)

			/* Count click */
			try {
				delete axios.defaults.headers.requesttoken
				axios.get(this.$apiUrl + '/json/url/' + station.stationuuid)
			} catch (error) {
				showError(t('podcast', 'Unable to count play on remote API'))
			}

			/* Put into recent stations */
			try {
				let stationSrc = ''
				if (!station.url_resolved) {
					stationSrc = station.urlresolved
				} else {
					stationSrc = station.url_resolved
				}
				const stationMap = {
					id: -1,
					name: station.name.toString(),
					urlresolved: stationSrc.toString(),
					favicon: station.favicon.toString(),
					stationuuid: station.stationuuid.toString(),
					bitrate: station.bitrate.toString(),
					country: station.country.toString(),
					language: station.language.toString(),
					homepage: station.homepage.toString(),
					codec: station.codec.toString(),
					tags: station.tags.toString(),
				}
				axios.defaults.headers.requesttoken = requesttoken
				await axios
					.post(generateUrl('/apps/podcast/api/recent'), stationMap)
			} catch (error) {
				showError(t('podcast', 'Could not add station to recent list'))
			}

		},

		async queryPodcast(podcastId) {

			const vm = this
			podcastId = 1084

			const queryURI = 'https://api.fyyd.de/0.2/podcast/episodes?podcast_id=' + podcastId
			try {
				delete axios.defaults.headers.requesttoken
				await axios.get(queryURI)
					.then(function(response) {
						vm.processPodcast(response.data)
					})
			} catch (error) {
				showError(t('podcast', 'Could not fetch stations from remote API'))
			}
		},

		processPodcast(podcast) {
			this.podcast = podcast.data
			this.pageLoading = false
		},

		/**
		 * On scroll event, load more stations if bottom reached
		 */
		scroll() {
			window.onscroll = () => {
				if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
					const route = this.$route
					console.log(route)
					// this.queryPodcast(route.name)
		    }
			}
		},
		loadSettings() {

			// axios.defaults.headers.common = {
			// 'User-Agent': 'Nextcloud Podcast App/' + this.$version,
			// }
			this.$store.dispatch('getVolumeState')

		},

		async loadFavorites() {
			const vm = this
			try {
				axios.defaults.headers.requesttoken = requesttoken
				await axios.get(generateUrl('/apps/podcast/api/favorites'))
					.then(function(response) {
						const favorites = []
						for (let i = 0, len = response.data.length; i < len; i++) {
							favorites.push([response.data[i].id, response.data[i].stationuuid])
						}
						vm.favorites = favorites
					})
			} catch (error) {
				showError(t('podcast', 'Unable to load favorites'))
			}
		},

		toggleSidebar(station = null) {
			if (station) {
				this.showSidebar = true
				this.sidebarStation = station
			} else {
				this.showSidebar = false
			}
		},
	},
}
</script>

<style lang="scss">

@media only screen and (min-width: 1024px) {
	.app-navigation-toggle {
		display: none;
	}
}

</style>