const buttonCamera = document.getElementById('buttonCamera');
const buttonRecord = document.getElementById('buttonRecord');
const buttonDelete = document.getElementById('buttonDelete');
const buttonCameraIcon = document.getElementById('buttonCameraIcon');
const buttonRecordIcon = document.getElementById('buttonRecordIcon');
const buttonDeleteIcon = document.getElementById('buttonDeleteIcon');
const countdownText = document.getElementById('countdown')

const videoDisplay = document.getElementById('videoDisplay');
const videoContainer = document.getElementById('videoContainer'); // div that contains the videodisplay

var mediaRecorder = null; // interface of the Media Stream Recording API to record the video stream
var stream = null;  // webcam video input stream
let recordedVideoBlob = null;   // recorded videodata
let isRecording = false;    // false to display record button, true to display stop button
let videoAccess = false;    // true if user has given permission to use the webcam

let videotime = 70; // how many seconds video is allowed to be recorded
let timeleft = videotime; // counter for how much time is still left
var countdownTimer; //the timer object that will end the recording if it takes too long

// default video dimensions
let videoHeight = 720;       
let videoWidth = 1280;


// handle form submission
//the Video is beeing send together with the form data
document.getElementById("question_form").addEventListener("submit", function (event) {
    event.preventDefault(); // Prevent the default form submission
    console.log("submit button pressed");
    // create a FormData object
    const formData = new FormData(event.target);

    console.log("form data: ",formData);

    // append the recorded video blob to the FormData object
    if (recordedVideoBlob) {
        console.log("video is available: ", recordedVideoBlob);
        formData.append("recordedVideo", recordedVideoBlob, "recordedVideo.webm");
    }
    
    console.log("Data to be submitted: ",formData);
    
    console.log("try to send the form and video");

    // send the form data and video to the backend
    fetch("/send", {
        method: "POST",
        body: formData
    }).then(response => {
        // code to handle proper redirection after submit
        console.log('Response:', response);
        // check if response is a redirect
        if (response.redirected) {
            console.log("Redirecting to:", response.url);
            window.location.href = response.url; // Redirect to the new page
        } else {
            console.log("No redirect response received.");
        }
    })
    .catch(error => {
        console.error('Error:', error);
    });
});

// enable/disable video recording feature
async function cameraButton() {
    if (!videoAccess) {
        console.log("cameraButton case videoAccess = false");

        try {
            // ask the user for permission to use the webcam
            // if given, assign it to "stream"
            stream = await navigator.mediaDevices.getUserMedia({
                video: true,
            });
        } catch (error) {
            console.log("Error: ", error);
            return;
        }
        console.log("stream is active");

        videoAccess = true;

        // set the dimensions of the webcam stream to the video display
        videoHeight = stream.getVideoTracks()[0].getSettings().height
        videoWidth = stream.getVideoTracks()[0].getSettings().width
        
        // calculate the aspec ratio
        let aspectratio = (videoHeight / videoWidth) *100;
        //console.log("videoHeight: ",videoHeight);
        //console.log("videoWidth: ",videoWidth);
        //console.log("aspect ratio: ",aspectratio);
        //console.log("device: ",stream.getVideoTracks()[0].getSettings().deviceId);

        // adjust CSS to make the video fit properly
        // this makes sure that there is no buggy "jumping" when the video display source changes
        videoContainer.style.setProperty("padding-bottom", "min("+videoHeight+"px,"+aspectratio+"%), 100vh");


        //TODO: Solution for this part:
        // If the video is vertical, I need to set the width to 0, the max-height to 100% and do the padding on the width, so turn the code around
        //This should always make the video fitt

        // adjust the max width for horizontal and vertical video input
        if (videoHeight > videoWidth){ //hochkant video
            // I did this originally to display vertical video on a horizontal screen properly (video should not be higher than the screem)
            // but now I do this by adjusting the paddint to be at most 100vh, so this whole part should be useless now
            // But a new problem could be if I do too little padding and the ratio is lost because of it, so actually I also need to adjust the width
            videoContainer.style.setProperty("max-width", "min(80%,576)");  // maybe actually use the screen height here: instead of 80% maybe 80vh 
        }else{ //normal, horizontal
            videoContainer.style.setProperty("max-width", "100%");
        }

        // show the webcam input stream on the video display
        videoDisplay.srcObject = stream;

        // change the icon to indicate the disable option
        buttonCameraIcon.src = ICON_PATHS.cameraofficon;
        buttonCameraIcon.alt = "Camera-off Icon";

        // display the elements for the video recording
        buttonRecord.style.display = 'inline-block';
        buttonDelete.style.display = 'inline-block';
        videoDisplay.style.display = 'block';
        videoContainer.style.display = 'block';
        videoDisplay.classList.add("videomirror");

        // initialize MediaRecorder, give it the webcam stream as input to record
        mediaRecorder = new MediaRecorder(stream, {
            mimeType: "video/webm",
            audioBitsPerSecond: 0,
            videoBitsPerSecond: 1900000, // Standard bitrate for video is 2,5 mbps
        });

        // when data is available at the mediaRecorder (this means the recording has ended, since I have not specified time intervalls)
        // save the data in "recordedVideoBlob"
        mediaRecorder.addEventListener("dataavailable", (event) => {
            console.log("Data available Event triggered");
            if (event.data.size > 0) {
                recordedVideoBlob = event.data;
                console.log("Data available:", recordedVideoBlob);
            } else {
                console.log("No Data available");
            }
        });

        // when recording is stopped, display the recorded video
        // TODO possibly replace this and just add it to the dataavailable event
        // TODO this would ensure proper order in a concurrent scenario (the stop code here can only be executed after the dataavailable code happened)
        // TODO part of it could also go to the record button function
        mediaRecorder.addEventListener("stop", () => { 
            if (recordedVideoBlob) {
                videoDisplay.srcObject = null;  //remove the stream as input
                videoDisplay.src = URL.createObjectURL(recordedVideoBlob);  // create a url for the recorded video and set it as input
                videoDisplay.controls = true;   // display video controls
                videoDisplay.pause();           // pause, so that it doesn't immediately play, TODO maybe disable autoplay?

                // TODO maybe move this to the record button function
                buttonRecordIcon.src = ICON_PATHS.recordicon; //change the icon of the record button back
                buttonRecordIcon.alt = 'Record Icon';
                isRecording = false;

                console.log('Recording stopped');
                console.log("Src path:", videoDisplay.src);
            }
        });

    } else {
        // -> the user disabled the videorecording feature

        console.log("cameraButton case videoAccess = true");

        stream.getTracks().forEach(track => track.stop()); // stop all tracks to release the camera
        stream = null;
        videoAccess = false;

        // change the icon and hide all the elements again
        buttonCameraIcon.src = ICON_PATHS.cameraicon;
        buttonCameraIcon.alt = "Camera Icon";
        buttonRecord.style.display = 'none';
        buttonDelete.style.display = 'none';
        videoDisplay.style.display = 'none';
        videoContainer.style.display = 'none';
    }
    console.log("camera button function ends");
}


function recordButton() {
    console.log("recordButton pressed");
    if (!isRecording) {
        // a new recording starts

        console.log("recordButton pressed case isRecording = false");

        deleteButton(); //delete previous video 

        videoDisplay.classList.add("videomirror"); // mirror the video while recording, for a more natural experience
        buttonDelete.setAttribute("disabled", ""); // can't delete during recording
        buttonDeleteIcon.classList.add("buttondisable"); // delete button icon indicates that it is disabled

        videoDisplay.src = null;    // get rid of the previous video on the display
        videoDisplay.srcObject = stream;    // set webcam stream as input for the video display
        videoDisplay.controls = false;  // hide the video controls durin recording, because they are confusing
        mediaRecorder.start();  // start recording
        timeleft = videotime;
        countdownTimer = setInterval(countdown, 1000) //stop the recording after "videotime" Seconds
        

        console.log("video bitrate = ",mediaRecorder.videoBitsPerSecond);

        // change icon to indicate "stop"
        buttonRecordIcon.src = ICON_PATHS.stopicon;
        buttonRecordIcon.alt = 'Stop Icon';
        isRecording = true;

        console.log('Recording started');
    } else {
        // recording got stopped

        console.log("recordButton pressed case isRecording = true");

        clearInterval(countdownTimer)

        stopRecording()
        
    }
}

function stopRecording() {
    mediaRecorder.stop(); // stop recording
    videoDisplay.classList.remove("videomirror"); // don't mirror the videodisplay anymore
    clearInterval(countdownTimer);
    console.log("recording stops");

    // enable the deletebutton again
    buttonDelete.removeAttribute("disabled");
    buttonDeleteIcon.classList.remove("buttondisable");
}

function timerStop() {
    // recording got stopped by timer

    console.log("timer stopped the recording");
    clearInterval(countdownTimer);
    stopRecording();
}

function countdown() {
    if(timeleft <= 0){
        countdownText.textContent = "";
        timerStop();
        clearInterval(countdownTimer);
        return;
    }
    if(timeleft >= 60){
        r = timeleft - 60;
        if(r< 10){
            countdownText.textContent = "01:0"+r;
        }else{
            countdownText.textContent = "01:"+r;
        }
    }else{
        if(timeleft< 10){
            countdownText.textContent = "00:0"+timeleft;
        }else{
            countdownText.textContent = "00:"+timeleft;
        }
    }
    timeleft -= 1;
}

function deleteButton() {
    // delete the recorded video
    videoDisplay.controls = false;
    videoDisplay.srcObject = stream; // set webcam stream as source for the video display again
    recordedVideoBlob = null
    videoDisplay.classList.add("videomirror"); // mirror the video display during live feed again

    // disable the deletebutton again
    buttonDelete.setAttribute("disabled", "");
    buttonDeleteIcon.classList.add("buttondisable");
}
