<template>
	<div>
		<Loading v-if="loading" />
		<ul v-if="!loading">
			<NcListItem
				v-if="!episodes.every((e: EpisodeInterface) => !e.selected)"
				:active="true"
				:force-display-actions="true"
				:name="
					n(
						'repod',
						'%n episode selected',
						'%n episodes selected',
						episodes.filter((e: EpisodeInterface) => e.selected).length,
					)
				"
				:one-line="true">
				<template #actions>
					<NcActionButton
						v-if="
							episodes
								.filter((e: EpisodeInterface) => e.selected)
								.filter((e: EpisodeInterface) => !hasEnded(e)).length
						"
						:aria-label="t('repod', 'Read all')"
						:disabled="
							!episodes
								.filter((e: EpisodeInterface) => e.selected)
								.every((e: EpisodeInterface) => e.duration)
						"
						:name="t('repod', 'Read all')"
						:title="t('repod', 'Read all')"
						@click="read(true)">
						<template #icon>
							<PlaylistPlayIcon :size="20" />
						</template>
					</NcActionButton>
					<NcActionButton
						v-if="
							episodes
								.filter((e: EpisodeInterface) => e.selected)
								.every((e: EpisodeInterface) => hasEnded(e))
						"
						:aria-label="t('repod', 'Unread all')"
						:disabled="
							!episodes
								.filter((e: EpisodeInterface) => e.selected)
								.every((e: EpisodeInterface) => e.duration)
						"
						:name="t('repod', 'Unread all')"
						:title="t('repod', 'Unread all')"
						@click="read(false)">
						<template #icon>
							<PlaylistRemoveIcon :size="20" />
						</template>
					</NcActionButton>
				</template>
				<template #icon>
					<NcAvatar
						v-if="
							episodes.filter((e: EpisodeInterface) => e.selected)
								.length < episodes.length
						"
						class="avatar"
						:display-name="t('repod', 'Select all')"
						:is-no-user="true">
						<template #icon>
							<SelectAllIcon
								class="progress"
								:size="20"
								@click="select(true)" />
						</template>
					</NcAvatar>
					<NcAvatar
						v-if="
							episodes.filter((e: EpisodeInterface) => e.selected)
								.length >= episodes.length
						"
						class="avatar"
						:display-name="t('repod', 'Unselect all')"
						:is-no-user="true">
						<template #icon>
							<SelectRemoveIcon
								class="progress"
								:size="20"
								@click="select(false)" />
						</template>
					</NcAvatar>
				</template>
			</NcListItem>
			<Episode
				v-for="episode in filteredEpisodes"
				:key="episode.guid"
				:episode="episode"
				:url="url"
				@select="episode.selected = !episode.selected" />
		</ul>
	</div>
</template>

<script lang="ts">
import { NcActionButton, NcAvatar, NcListItem } from '@nextcloud/vue'
import { hasEnded, isListening, markAs } from '../../utils/status.ts'
import { n, t } from '@nextcloud/l10n'
import Episode from './Episode.vue'
import type { EpisodeInterface } from '../../utils/types.ts'
import Loading from '../Atoms/Loading.vue'
import PlaylistPlayIcon from 'vue-material-design-icons/PlaylistPlay.vue'
import PlaylistRemoveIcon from 'vue-material-design-icons/PlaylistRemove.vue'
import SelectAllIcon from 'vue-material-design-icons/SelectAll.vue'
import SelectRemoveIcon from 'vue-material-design-icons/SelectRemove.vue'
import axios from '@nextcloud/axios'
import { decodeUrl } from '../../utils/url.ts'
import { generateUrl } from '@nextcloud/router'
import { mapState } from 'pinia'
import { showError } from '../../utils/toast.ts'
import { usePlayer } from '../../store/player.ts'
import { useSettings } from '../../store/settings.ts'

export default {
	name: 'Episodes',
	components: {
		Episode,
		Loading,
		NcActionButton,
		NcAvatar,
		NcListItem,
		PlaylistPlayIcon,
		PlaylistRemoveIcon,
		SelectAllIcon,
		SelectRemoveIcon,
	},
	data: () => ({
		episodes: [] as EpisodeInterface[],
		loading: true,
	}),
	computed: {
		...mapState(usePlayer, ['episode']),
		...mapState(useSettings, ['filters']),
		filteredEpisodes() {
			return this.episodes.filter((episode: EpisodeInterface) => {
				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 as string)
		},
	},
	watch: {
		episode() {
			if (this.episode) {
				this.episodes = this.episodes.map((episode: EpisodeInterface) =>
					episode.url === this.episode?.url ? this.episode : episode,
				)
			}
		},
	},
	async mounted() {
		try {
			this.loading = true
			const episodes = await axios.get<EpisodeInterface[]>(
				generateUrl('/apps/repod/episodes/list?url={url}', {
					url: this.url,
				}),
			)
			this.episodes = [...episodes.data].sort(
				(a: EpisodeInterface, b: EpisodeInterface) =>
					new Date(b.pubDate?.date || '').getTime() -
					new Date(a.pubDate?.date || '').getTime(),
			)
		} catch (e) {
			console.error(e)
			showError(t('repod', 'Could not fetch episodes'))
		} finally {
			this.loading = false
		}
	},
	methods: {
		hasEnded,
		isListening,
		n,
		t,
		async read(read: boolean) {
			try {
				this.episodes = this.episodes.map((episode: EpisodeInterface) =>
					episode.selected ? markAs(episode, read, this.url) : episode,
				)
				await axios.post(
					generateUrl('/apps/gpoddersync/episode_action/create'),
					this.episodes
						.filter((episode: EpisodeInterface) => episode.selected)
						.map((episode: EpisodeInterface) => episode.action),
				)
			} catch (e) {
				console.error(e)
				showError(t('repod', 'Could not change the status of the episode'))
			}
		},
		select(all: boolean) {
			this.episodes = this.episodes.map((episode: EpisodeInterface) => {
				episode.selected = all
				return episode
			})
		},
	},
}
</script>

<style scoped>
.avatar {
	color: var(--color-main-text);
}

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