window.addEventListener("load", main);

let displaySelectDialog;
let audioSinkSelectDialog;
let openNewVideoDialog;
let closeVideoDialog;

let closeVideoDialogID;

let videoTemplate;
let videoContainer;
let currentVideos = [];
let currentVideoData;

let seekbar;
let volumeBar;
let playPauseButton;
let playPauseButtonIcon;
let replayButton;
let forwardButton;
let currentTimestamp;
let videoLength;

async function main() {
    displaySelectDialog = document.querySelector("#display-select-dialog");
    audioSinkSelectDialog = document.querySelector("#audio-sink-select-dialog");
    openNewVideoDialog = document.querySelector("#open-new-video-dialog");
    closeVideoDialog = document.querySelector("#close-video-dialog");

    videoTemplate = document.querySelector("#video-template");
    videoContainer = document.querySelector("#video-container");

    seekbar = document.querySelector("#seekbar");
    volumeBar = document.querySelector("#volume-bar");
    playPauseButton = document.querySelector("#play-pause");
    playPauseButtonIcon = playPauseButton.querySelector(".material-symbols-outlined");
    replayButton = document.querySelector("#replay");
    forwardButton = document.querySelector("#forward");
    currentTimestamp = document.querySelector("#current-timestamp");
    videoLength = document.querySelector("#video-length");
    
    playPauseButton.addEventListener("click", onPlayPauseButtonClicked);
    replayButton.addEventListener("click", onReplayButtonClicked);
    forwardButton.addEventListener("click", onForwardButtonClicked);
    seekbar.addEventListener("change", onSeekbarChanged);
    volumeBar.addEventListener("input", onVolumeBarChanged);

    updateUI();
    setInterval(updateUI, 1000);
}

async function updateUI() {
    const videoDatas = await listVideos();
    const currentDisplay = localStorage.getItem("display");
    currentVideoData = videoDatas.find(videoData => videoData.display == currentDisplay);

    if (currentVideoData !== undefined) {
        console.log(currentVideoData);

        seekbar.disabled = false;
        volumeBar.disabled = false;
        playPauseButton.disabled = false;
        replayButton.disabled = false;
        forwardButton.disabled = false;

        const {progress, duration} = formatTimestamps(currentVideoData.progress, currentVideoData.duration);
        currentTimestamp.textContent = progress;
        videoLength.textContent = duration;
        seekbar.max = currentVideoData.duration;
        seekbar.setValue(currentVideoData.progress);
        volumeBar.setValue(currentVideoData.volume);
        playPauseButtonIcon.textContent = currentVideoData.paused ? "play_circle" : "pause_circle";
    } else {
        seekbar.disabled = true;
        seekbar.setValue(0);
        volumeBar.disabled = true;
        playPauseButton.disabled = true;
        playPauseButtonIcon.textContent = "play_circle";
        replayButton.disabled = true;
        forwardButton.disabled = true;
        currentTimestamp.textContent = "";
        videoLength.textContent = "";
    }

    await refreshVideoList(videoDatas);
}

async function refreshVideoList(videoDatas) {
    const videoIDs = videoDatas.map(videoData => videoData.id);
    const shownVideoIDs = currentVideos.map(video => video.videoID);
    const missingVideoIDs = videoIDs.filter(videoID => !shownVideoIDs.includes(videoID));
    const unneededVideoIDs = shownVideoIDs.filter(shownVideoID => !videoIDs.includes(shownVideoID));

    for (let unneededVideoID of unneededVideoIDs) {
        const index = currentVideos.findIndex(video => video.videoID == unneededVideoID);
        const video = currentVideos[index];
        video.hide();
        currentVideos.splice(index, 1);
    }

    for (let index in videoDatas) {
        const videoData = videoDatas[index];

        if (missingVideoIDs.includes(videoData.id)) {
            const video = new Video(videoData);
            video.showAt(index);
            currentVideos.splice(index, 0, video);
        } else {
            const video = currentVideos.find(currentVideo => currentVideo.videoID == videoData.id);
            video.update(videoData);
        }
    }
}

async function onShowSelectDisplayDialogClicked() {
    const displays = await listDisplays();
    const currentDisplay = localStorage.getItem("display");
    
    const displaySelectForm = document.querySelector("#display-select-dialog-form");
    displaySelectForm.clearChildren();

    for (let display of displays) {
        const input = document.createElement("input");
        input.setAttribute("type", "radio");
        input.setAttribute("name", "display");
        input.setAttribute("id", `display_${display}`);
        input.setAttribute("value", display);
        input.addEventListener("change", onCloseSelectDisplayDialogClicked);
        if (display == currentDisplay) input.setAttribute("checked", "checked");
        displaySelectForm.appendChild(input);

        const label = document.createElement("label");
        label.setAttribute("for", `display_${display}`);
        label.textContent = display;
        displaySelectForm.appendChild(label);
    }

    displaySelectDialog.showModal();
}

function onCloseSelectDisplayDialogClicked() {
    const selectedDisplay = document.forms["display-select-dialog-form"].elements["display"].value;    
    localStorage.setItem("display", selectedDisplay);
    setTimeout(() => displaySelectDialog.close(), 100);
}

async function onShowSelectAudioSinkDialogClicked() {
    const audioSinks = await listAudioSinks();
    const currentAudioSink = localStorage.getItem("audio-sink");
    
    const audioSinkSelectForm = document.querySelector("#audio-sink-select-dialog-form");
    audioSinkSelectForm.clearChildren();

    for (let index in audioSinks) {
        const audioSink = audioSinks[index];

        const input = document.createElement("input");
        input.setAttribute("type", "radio");
        input.setAttribute("name", "audiosink");
        input.setAttribute("id", `audiosink_${index}`);
        input.setAttribute("value", audioSink.description);
        input.addEventListener("change", onCloseSelectAudioSinkDialogClicked);
        if (audioSink.name == currentAudioSink) input.setAttribute("checked", "checked");
        audioSinkSelectForm.appendChild(input);

        const label = document.createElement("label");
        label.setAttribute("for", `audiosink_${index}`);
        label.textContent = audioSink.description;
        audioSinkSelectForm.appendChild(label);
    }

    audioSinkSelectDialog.showModal();
}

function onCloseSelectAudioSinkDialogClicked() {
    const selectedAudioSink = document.forms["audio-sink-select-dialog-form"].elements["audiosink"].value;
    localStorage.setItem("audio-sink", selectedAudioSink);
    changeAudioSink(selectedAudioSink);
    setTimeout(() => audioSinkSelectDialog.close(), 100);
}

function onShowOpenNewVideoDialogClicked() {
    const link = document.querySelector("#open-new-video-dialog-link");
    link.value = "";
    openNewVideoDialog.showModal();
}

function onOpenVideoButtonClicked() {
    const link = document.forms["open-new-video-dialog-form"].elements["link"].value;
    openVideo(link);
    openNewVideoDialog.close();
}

function onOpenVideoInBackgroundButtonClicked() {
    const link = document.forms["open-new-video-dialog-form"].elements["link"].value;
    openVideoInBackground(link);
    openNewVideoDialog.close();
}

function onCloseOpenNewVideoDialogClicked() {
    openNewVideoDialog.close();
}

function askForCloseVideoConfirmation(videoID, videoTitle) {
    const videoTitleElement = document.querySelector("#close-video-dialog-title");
    videoTitleElement.textContent = videoTitle;
    closeVideoDialogID = videoID;
    closeVideoDialog.showModal();
}

function onCloseCloseVideoDialogClicked() {
    closeVideoDialog.close();
}

function onCloseVideoButtonClicked() {
    closeVideo(closeVideoDialogID)
    closeVideoDialog.close();
}

function onCancelCloseVideoButtonClicked() {
    closeVideoDialog.close();
}

function formatTimestamps(progress, duration) {
    const progressHours = Math.floor(progress / 3600);
    const progressRemaining = progress % 3600;
    const progressMinutes = Math.floor(progressRemaining / 60);
    const progressSeconds = progressRemaining % 60;

    const durationHours = Math.floor(duration / 3600);
    const durationRemaining = duration % 3600;
    const durationMinutes = Math.floor(durationRemaining / 60);
    const durationSeconds = durationRemaining % 60;
    
    if (durationHours > 0) {
        return {
            progress: `${progressHours.pad(2)}:${progressMinutes.pad(2)}:${progressSeconds.pad(2)}`,
            duration: `${durationHours.pad(2)}:${durationMinutes.pad(2)}:${durationSeconds.pad(2)}`
        };
    } else {
        return {
            progress: `${progressMinutes.pad(2)}:${progressSeconds.pad(2)}`,
            duration: `${durationMinutes.pad(2)}:${durationSeconds.pad(2)}`
        };
    }
}

function onPlayPauseButtonClicked() {
    if (currentVideoData.paused) {
        unpauseVideo(currentVideoData.id);
    } else {
        pauseVideo(currentVideoData.id);
    }
}

function onReplayButtonClicked() {
    seekVideoRelative(currentVideoData.id, -10);
}

function onForwardButtonClicked() {
    seekVideoRelative(currentVideoData.id, 10);
}

function onSeekbarChanged() {
    seekVideo(currentVideoData.id, parseInt(seekbar.value));
}

function onVolumeBarChanged() {
    setVolume(parseFloat(volumeBar.value));
}