<template>
	<modal title="Edit Playlist">
		<div slot="body">
			<nav class="level">
				<div class="level-item has-text-centered">
					<div>
						<p class="heading">
							Total Length
						</p>
						<p class="title">
							{{ totalLength() }}
						</p>
					</div>
				</div>
			</nav>
			<hr />
			<aside class="menu">
				<ul class="menu-list">
					<li v-for="(song, index) in playlist.songs" :key="index">
						<a href="#" target="_blank">{{ song.title }}</a>
						<div class="controls">
							<a href="#" v-on:click="promoteSong(song.songId)">
								<i class="material-icons" v-if="index > 0"
									>keyboard_arrow_up</i
								>
								<i
									v-else
									class="material-icons"
									style="opacity: 0"
									>error</i
								>
							</a>
							<a href="#" v-on:click="demoteSong(song.songId)">
								<i
									v-if="playlist.songs.length - 1 !== index"
									class="material-icons"
									>keyboard_arrow_down</i
								>
								<i
									v-else
									class="material-icons"
									style="opacity: 0"
									>error</i
								>
							</a>
							<a
								href="#"
								v-on:click="removeSongFromPlaylist(song.songId)"
							>
								<i class="material-icons">delete</i>
							</a>
						</div>
					</li>
				</ul>
				<br />
			</aside>
			<div class="control is-grouped">
				<p class="control is-expanded">
					<input
						v-model="searchSongQuery"
						class="input"
						type="text"
						placeholder="Search for Song to add"
						autofocus
						@keyup.enter="searchForSongs()"
					/>
				</p>
				<p class="control">
					<a class="button is-info" @click="searchForSongs()" href="#"
						>Search</a
					>
				</p>
			</div>
			<table v-if="songQueryResults.length > 0" class="table">
				<tbody>
					<tr
						v-for="(result, index) in songQueryResults"
						:key="index"
					>
						<td>
							<img :src="result.thumbnail" />
						</td>
						<td>{{ result.title }}</td>
						<td>
							<a
								class="button is-success"
								href="#"
								@click="addSongToPlaylist(result.id)"
								>Add</a
							>
						</td>
					</tr>
				</tbody>
			</table>
			<div class="control is-grouped">
				<p class="control is-expanded">
					<input
						v-model="directSongQuery"
						class="input"
						type="text"
						placeholder="Enter a YouTube id or URL directly"
						autofocus
						@keyup.enter="addSong()"
					/>
				</p>
				<p class="control">
					<a class="button is-info" @click="addSong()" href="#"
						>Add</a
					>
				</p>
			</div>
			<div class="control is-grouped">
				<p class="control is-expanded">
					<input
						v-model="importQuery"
						class="input"
						type="text"
						placeholder="YouTube Playlist URL"
						@keyup.enter="importPlaylist(false)"
					/>
				</p>
				<p class="control">
					<a
						class="button is-info"
						@click="importPlaylist(true)"
						href="#"
						>Import music</a
					>
				</p>
				<p class="control">
					<a
						class="button is-info"
						@click="importPlaylist(false)"
						href="#"
						>Import all</a
					>
				</p>
			</div>
			<button class="button is-info" @click="shuffle()">Shuffle</button>
			<h5>Edit playlist details:</h5>
			<div class="control is-grouped">
				<p class="control is-expanded">
					<input
						v-model="playlist.displayName"
						class="input"
						type="text"
						placeholder="Playlist Display Name"
						@keyup.enter="renamePlaylist()"
					/>
				</p>
				<p class="control">
					<a class="button is-info" @click="renamePlaylist()" href="#"
						>Rename</a
					>
				</p>
			</div>
		</div>
		<div slot="footer">
			<a class="button is-danger" v-on:click="removePlaylist()" href="#"
				>Remove Playlist</a
			>
		</div>
	</modal>
</template>

<script>
import { mapState, mapActions } from "vuex";

import Toast from "toasters";
import Modal from "../Modal.vue";
import io from "../../../io";
import validation from "../../../validation";

export default {
	components: { Modal },
	data() {
		return {
			playlist: { songs: [] },
			songQueryResults: [],
			searchSongQuery: "",
			directSongQuery: "",
			importQuery: ""
		};
	},
	computed: mapState("user/playlists", {
		editing: state => state.editing
	}),
	mounted() {
		io.getSocket(socket => {
			this.socket = socket;
			this.socket.emit("playlists.getPlaylist", this.editing, res => {
				if (res.status === "success") this.playlist = res.data;
				this.playlist.oldId = res.data._id;
			});
			this.socket.on("event:playlist.addSong", data => {
				if (this.playlist._id === data.playlistId)
					this.playlist.songs.push(data.song);
			});
			this.socket.on("event:playlist.removeSong", data => {
				if (this.playlist._id === data.playlistId) {
					this.playlist.songs.forEach((song, index) => {
						if (song.songId === data.songId)
							this.playlist.songs.splice(index, 1);
					});
				}
			});
			this.socket.on("event:playlist.updateDisplayName", data => {
				if (this.playlist._id === data.playlistId)
					this.playlist.displayName = data.displayName;
			});
			this.socket.on("event:playlist.moveSongToBottom", data => {
				if (this.playlist._id === data.playlistId) {
					let songIndex;
					this.playlist.songs.forEach((song, index) => {
						if (song.songId === data.songId) songIndex = index;
					});
					const song = this.playlist.songs.splice(songIndex, 1)[0];
					this.playlist.songs.push(song);
				}
			});
			this.socket.on("event:playlist.moveSongToTop", data => {
				if (this.playlist._id === data.playlistId) {
					let songIndex;
					this.playlist.songs.forEach((song, index) => {
						if (song.songId === data.songId) songIndex = index;
					});
					const song = this.playlist.songs.splice(songIndex, 1)[0];
					this.playlist.songs.unshift(song);
				}
			});
		});
	},
	methods: {
		formatTime(duration) {
			if (duration <= 0) return "0 seconds";

			const hours = Math.floor(duration / (60 * 60));
			const formatHours = () => {
				if (hours > 0) {
					if (hours > 1) {
						if (hours < 10) return `0${hours} hours `;
						return `${hours} hours `;
					}
					return `0${hours} hour `;
				}
				return "";
			};

			const minutes = Math.floor((duration - hours * 60 * 60) / 60);
			const formatMinutes = () => {
				if (minutes > 0) {
					if (minutes > 1) {
						if (minutes < 10) return `0${minutes} minutes `;
						return `${minutes} minutes `;
					}
					return `0${minutes} minute `;
				}
				return "";
			};

			const seconds = Math.floor(
				duration - hours * 60 * 60 - minutes * 60
			);
			const formatSeconds = () => {
				if (seconds > 0) {
					if (seconds > 1) {
						if (seconds < 10) return `0${seconds} seconds `;
						return `${seconds} seconds `;
					}
					return `0${seconds} second `;
				}
				return "";
			};

			return formatHours() + formatMinutes() + formatSeconds();
		},
		totalLength() {
			let length = 0;
			this.playlist.songs.forEach(song => {
				length += song.duration;
			});
			return this.formatTime(length);
		},
		searchForSongs() {
			let query = this.songQuery;
			if (query.indexOf("&index=") !== -1) {
				query = query.split("&index=");
				query.pop();
				query = query.join("");
			}
			if (query.indexOf("&list=") !== -1) {
				query = query.split("&list=");
				query.pop();
				query = query.join("");
			}
			this.socket.emit("apis.searchYoutube", query, res => {
				if (res.status === "success") {
					this.songQueryResults = [];
					for (let i = 0; i < res.data.items.length; i += 1) {
						this.songQueryResults.push({
							id: res.data.items[i].id.videoId,
							url: `https://www.youtube.com/watch?v=${this.id}`,
							title: res.data.items[i].snippet.title,
							thumbnail:
								res.data.items[i].snippet.thumbnails.default.url
						});
					}
				} else if (res.status === "error")
					new Toast({ content: res.message, timeout: 3000 });
			});
		},
		addSongToPlaylist(id) {
			this.socket.emit(
				"playlists.addSongToPlaylist",
				id,
				this.playlist._id,
				res => {
					new Toast({ content: res.message, timeout: 4000 });
				}
			);
		},
		/* eslint-disable prefer-destructuring */
		addSong() {
			let id = "";

			if (this.directSongQuery.length === 11) id = this.directSongQuery;
			else {
				const match = this.directSongQuery.match("v=([0-9A-Za-z_-]+)");
				if (match.length > 0) id = match[1];
			}

			this.addSongToPlaylist(id);
		},
		/* eslint-enable prefer-destructuring */
		shuffle() {
			this.socket.emit("playlists.shuffle", this.playlist._id, res => {
				new Toast({ content: res.message, timeout: 4000 });
				if (res.status === "success") {
					this.playlist = res.data;
				}
			});
		},
		importPlaylist(musicOnly) {
			new Toast({
				content:
					"Starting to import your playlist. This can take some time to do.",
				timeout: 4000
			});
			this.socket.emit(
				"playlists.addSetToPlaylist",
				this.importQuery,
				this.playlist._id,
				musicOnly,
				res => {
					new Toast({ content: res.message, timeout: 4000 });
					if (res.status === "success") {
						new Toast({
							content: `Successfully added ${res.stats.songsAddedSuccessfully} songs. Failed to add ${res.stats.songsFailedToAdd} songs.`,
							timeout: 4000
						});
						if (musicOnly) {
							new Toast({
								content: `${res.stats.songsInPlaylistTotal} of the ${res.stats.videosInPlaylistTotal} videos in the playlist were songs.`,
								timeout: 4000
							});
						}
					}
				}
			);
		},
		removeSongFromPlaylist(id) {
			this.socket.emit(
				"playlists.removeSongFromPlaylist",
				id,
				this.playlist._id,
				res => {
					new Toast({ content: res.message, timeout: 4000 });
				}
			);
		},
		renamePlaylist() {
			const { displayName } = this.playlist;
			if (!validation.isLength(displayName, 2, 32))
				return new Toast({
					content:
						"Display name must have between 2 and 32 characters.",
					timeout: 8000
				});
			if (!validation.regex.ascii.test(displayName))
				return new Toast({
					content:
						"Invalid display name format. Only ASCII characters are allowed.",
					timeout: 8000
				});

			return this.socket.emit(
				"playlists.updateDisplayName",
				this.playlist._id,
				this.playlist.displayName,
				res => {
					new Toast({ content: res.message, timeout: 4000 });
				}
			);
		},
		removePlaylist() {
			this.socket.emit("playlists.remove", this.playlist._id, res => {
				new Toast({ content: res.message, timeout: 3000 });
				if (res.status === "success") {
					this.closeModal({
						sector: "station",
						modal: "editPlaylist"
					});
				}
			});
		},
		promoteSong(songId) {
			this.socket.emit(
				"playlists.moveSongToTop",
				this.playlist._id,
				songId,
				res => {
					new Toast({ content: res.message, timeout: 4000 });
				}
			);
		},
		demoteSong(songId) {
			this.socket.emit(
				"playlists.moveSongToBottom",
				this.playlist._id,
				songId,
				res => {
					new Toast({ content: res.message, timeout: 4000 });
				}
			);
		},
		...mapActions("modals", ["closeModal"])
	}
};
</script>

<style lang="scss" scoped>
@import "styles/global.scss";

.menu {
	padding: 0 20px;
}

.menu-list li {
	display: flex;
	justify-content: space-between;
}

.menu-list a:hover {
	color: $black !important;
}

li a {
	display: flex;
	align-items: center;
}

.controls {
	display: flex;

	a {
		display: flex;
		align-items: center;
	}
}

.table {
	margin-bottom: 0;
}

h5 {
	padding: 20px 0;
}
</style>