const { existsSync, mkdirSync } = require("fs");
const { join } = require("path");
const { URL } = require("url");

const { dialog } = require("electron");
const is = require("electron-is");
const ytpl = require("ytpl");
const chokidar = require('chokidar');

const { setOptions } = require("../../config/plugins");
const registerCallback = require("../../providers/song-info");
const { sendError } = require("./back");
const { defaultMenuDownloadLabel, getFolder } = require("./utils");

let downloadLabel = defaultMenuDownloadLabel;
let metadataURL = undefined;
let callbackIsRegistered = false;

module.exports = (win, options) => {
	if (!callbackIsRegistered) {
		registerCallback((info) => {
			metadataURL = info.url;
		});
		callbackIsRegistered = true;
	}

	return [
		{
			label: downloadLabel,
			click: async () => {
				const currentURL = metadataURL || win.webContents.getURL();
				const playlistID = new URL(currentURL).searchParams.get("list");
				if (!playlistID) {
					sendError(win, new Error("No playlist ID found"));
					return;
				}

				console.log(`trying to get playlist ID: '${playlistID}'`);
				let playlist;
				try {
					playlist = await ytpl(playlistID, {
						limit: options.playlistMaxItems || Infinity,
					});
				} catch (e) {
					sendError(win, e);
					return;
				}
				const playlistTitle = playlist.title;

				const folder = getFolder(options.downloadFolder);
				const playlistFolder = join(folder, playlistTitle);
				if (existsSync(playlistFolder)) {
					sendError(
						win,
						new Error(`The folder ${playlistFolder} already exists`)
					);
					return;
				}
				mkdirSync(playlistFolder, { recursive: true });

				dialog.showMessageBox({
					type: "info",
					buttons: ["OK"],
					title: "Started Download",
					message: `Downloading Playlist "${playlistTitle}"`,
					detail: `(${playlist.items.length} songs)`,
				});

				if (is.dev()) {
					console.log(
						`Downloading playlist "${playlistTitle}" (${playlist.items.length} songs)`
					);
				}

				const steps = 1 / playlist.items.length;
				let progress = 0;

				win.setProgressBar(2); // starts with indefinite bar

				let dirWatcher = chokidar.watch(playlistFolder);
				dirWatcher.on('add', () => {
					progress += steps;
					if (progress >= 0.9999) {
						win.setProgressBar(-1); // close progress bar
						dirWatcher.close().then(() => dirWatcher = null);
					} else {
						win.setProgressBar(progress);
					}
				});

				playlist.items.forEach((song) => {
					win.webContents.send(
						"downloader-download-playlist",
						song.url,
						playlistTitle,
						options
					);
				});
			},
		},
		{
			label: "Choose download folder",
			click: () => {
				let result = dialog.showOpenDialogSync({
					properties: ["openDirectory", "createDirectory"],
					defaultPath: getFolder(options.downloadFolder),
				});
				if (result) {
					options.downloadFolder = result[0];
					setOptions("downloader", options);
				} // else = user pressed cancel
			},
		},
	];
};
