<template>
	<div>
		<Loading v-if="loading" />
		<ul v-if="!loading">
			<NcListItem
				v-for="episode in filteredEpisodes"
				:key="episode.guid"
				:active="isCurrentEpisode(episode)"
				:class="hasEnded(episode) ? 'ended' : ''"
				:details="formatLocaleDate(new Date(episode.pubDate?.date))"
				:force-display-actions="true"
				:name="episode.name"
				:title="episode.description"
				@click="modalEpisode = episode">
				<template #extra-actions>
					<NcActionButton
						v-if="!isCurrentEpisode(episode)"
						:aria-label="t('repod', 'Play')"
						:title="t('repod', 'Play')"
						@click="load(episode)">
						<template #icon>
							<PlayIcon :size="20" />
						</template>
					</NcActionButton>
					<NcActionButton
						v-if="isCurrentEpisode(episode)"
						:aria-label="t('repod', 'Stop')"
						:title="t('repod', 'Stop')"
						@click="load(null)">
						<template #icon>
							<StopIcon :size="20" />
						</template>
					</NcActionButton>
				</template>
				<template #actions>
					<NcActionButton
						v-if="episode.duration && !hasEnded(episode)"
						:aria-label="t('repod', 'Mark as read')"
						:disabled="loadingAction"
						:name="t('repod', 'Mark as read')"
						:title="t('repod', 'Mark as read')"
						@click="markAs(episode, true)">
						<template #icon>
							<PlaylistPlayIcon :size="20" />
						</template>
					</NcActionButton>
					<NcActionButton
						v-if="episode.duration && hasEnded(episode)"
						:aria-label="t('repod', 'Mark as unread')"
						:disabled="loadingAction"
						:name="t('repod', 'Mark as unread')"
						:title="t('repod', 'Mark as unread')"
						@click="markAs(episode, false)">
						<template #icon>
							<PlaylistRemoveIcon :size="20" />
						</template>
					</NcActionButton>
					<NcActionLink
						v-if="episode.link"
						:href="episode.link"
						:name="t('repod', 'Open website')"
						target="_blank"
						:title="t('repod', 'Open website')">
						<template #icon>
							<OpenInNewIcon :size="20" />
						</template>
					</NcActionLink>
					<NcActionLink
						v-if="episode.url"
						:href="episode.url"
						:name="t('repod', 'Download')"
						target="_blank"
						:title="t('repod', 'Download')">
						<template #icon>
							<DownloadIcon :size="20" />
						</template>
					</NcActionLink>
				</template>
				<template #icon>
					<NcAvatar
						:display-name="episode.name"
						:is-no-user="true"
						:url="episode.image" />
				</template>
				<template #indicator>
					<NcProgressBar
						v-if="isListening(episode)"
						class="progress"
						:value="
							(episode.action.position * 100) / episode.action.total
						" />
				</template>
				<template #subname>
					{{ episode.duration }}
				</template>
			</NcListItem>
		</ul>
		<NcModal v-if="modalEpisode" @close="modalEpisode = null">
			<Modal
				:description="modalEpisode.description"
				:image="modalEpisode.image"
				:link="modalEpisode.link"
				:name="modalEpisode.name"
				:size="modalEpisode.size"
				:title="modalEpisode.title"
				:url="modalEpisode.url" />
		</NcModal>
	</div>
</template>

<script>
import {
	NcActionButton,
	NcActionLink,
	NcAvatar,
	NcListItem,
	NcModal,
	NcProgressBar,
} from '@nextcloud/vue'
import {
	durationToSeconds,
	formatEpisodeTimestamp,
	formatLocaleDate,
} from '../../utils/time.js'
import DownloadIcon from 'vue-material-design-icons/Download.vue'
import { EventBus } from '../../store/bus.js'
import Loading from '../Atoms/Loading.vue'
import Modal from '../Atoms/Modal.vue'
import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue'
import PlayIcon from 'vue-material-design-icons/Play.vue'
import PlaylistPlayIcon from 'vue-material-design-icons/PlaylistPlay.vue'
import PlaylistRemoveIcon from 'vue-material-design-icons/PlaylistRemove.vue'
import StopIcon from 'vue-material-design-icons/Stop.vue'
import axios from '@nextcloud/axios'
import { decodeUrl } from '../../utils/url.js'
import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'

export default {
	name: 'Episodes',
	components: {
		DownloadIcon,
		Loading,
		Modal,
		NcActionButton,
		NcActionLink,
		NcAvatar,
		NcListItem,
		NcModal,
		NcProgressBar,
		OpenInNewIcon,
		PlayIcon,
		PlaylistPlayIcon,
		PlaylistRemoveIcon,
		StopIcon,
	},
	data() {
		return {
			episodes: [],
			loading: true,
			loadingAction: false,
			modalEpisode: null,
		}
	},
	computed: {
		currentEpisode() {
			return this.$store.state.player.episode
		},
		filters() {
			return this.$store.state.settings.filters
		},
		filteredEpisodes() {
			return this.episodes.filter((episode) => {
				if (!this.filters.listened && this.hasEnded(episode)) {
					return false
				}

				if (!this.filters.listening && this.isListening(episode)) {
					return false
				}

				if (!this.filters.unlistened && !this.isListening(episode)) {
					return false
				}

				return true
			})
		},
		url() {
			return decodeUrl(this.$route.params.url)
		},
	},
	async mounted() {
		try {
			this.loading = true
			const episodes = await axios.get(
				generateUrl('/apps/repod/episodes/list?url={url}', {
					url: this.url,
				}),
			)
			this.episodes = [...episodes.data].sort(
				(a, b) => new Date(b.pubDate?.date) - new Date(a.pubDate?.date),
			)
			EventBus.$on('updateEpisodesList', this.updateList)
		} catch (e) {
			console.error(e)
			showError(t('repod', 'Could not fetch episodes'))
		} finally {
			this.loading = false
		}
	},
	destroyed() {
		EventBus.$off('updateEpisodesList')
	},
	methods: {
		formatLocaleDate,
		hasEnded(episode) {
			return (
				episode.action &&
				(episode.action.action === 'DELETE' ||
					(episode.action.position > 0 &&
						episode.action.total > 0 &&
						episode.action.position >= episode.action.total))
			)
		},
		isCurrentEpisode(episode) {
			return this.currentEpisode && this.currentEpisode.url === episode.url
		},
		isListening(episode) {
			return (
				episode.action &&
				episode.action.action.toLowerCase() === 'play' &&
				!this.hasEnded(episode)
			)
		},
		load(episode) {
			this.$store.dispatch('player/load', episode)
		},
		async markAs(episode, read) {
			try {
				this.loadingAction = true
				episode.action = {
					podcast: this.url,
					episode: episode.url,
					guid: episode.guid,
					action: 'play',
					timestamp: formatEpisodeTimestamp(new Date()),
					started: episode.action ? episode.action.started : 0,
					position: read ? durationToSeconds(episode.duration) : 0,
					total: durationToSeconds(episode.duration),
				}
				await axios.post(
					generateUrl('/apps/gpoddersync/episode_action/create'),
					[episode.action],
				)
				this.updateList(episode)
			} catch (e) {
				console.error(e)
				showError(t('repod', 'Could not change the status of the episode'))
			} finally {
				this.loadingAction = false
			}
		},
		updateList(episode) {
			this.episodes = this.episodes.map((e) =>
				e.url === episode.url ? episode : e,
			)
		},
	},
}
</script>

<style scoped>
.ended {
	opacity: 0.4;
}

.progress {
	margin-top: 0.4rem;
}
</style>
