//Номер баги
let bugId = getIdFromUrl() || getBugIdFromField();

// Если id нет, то мы имеем дело с новой багой
if (!bugId) {
    const currentTime = new Date().getTime()
    // Присвоим текущее время, чтобы при создании следующей баги значения не сохранились
    bugId = `c${currentTime}`;
}

// получим протокол
const {
    protocol
} = window.location;

//Изменение баги
var changed_remain = 0;

// Создание баги
const isBugCreation = window.location.pathname.includes("enter");

function initTimer(config) {
    // Показываем время только сотрудникам Etersoft
    if (!isEtersoft()) return;

    // достанем все необходимые параметры
    // для конфигурирования таймера
    const {
        updateInterval,
        selector,
        protocol,
        bugId,
        udpateTimerCallback
    } = config

    // покажем сам таймер
    document.querySelector(selector).style.display = "block";

    const timer = new Timer(`bug:${protocol}${bugId}`, udpateTimerCallback);
    timer.setAutoUpdate(updateInterval);

    return timer
}

// Конфиг для валидации комментарии
const VALIDATION_CONFIG = {
    minLength: 9,
    maxTime: 8,
}

// Конфиг таймера
const TIMER_CONFIG = {
    // Интервал обновления таймера в мс, на точность не влияет
    updateInterval: 1000,
    // Селектор элемента, в котором лежит сам таймер
    selector: "#timerblock",
    // протокол
    protocol,
    // номер баги
    bugId,
    // функция updateTimer
    udpateTimerCallback: updateTimer
}

// Объект таймера, создается при инициализации
// Подробнее про таймер см. timer_common.js
const timer = initTimer(TIMER_CONFIG);

// this при вызове - объект таймера
function updateTimer() {
    setPauseDisplay(this.isPaused());
    document.querySelector("#timespent").value = this.getFormattedString();
}

// Установка в поле отработанного времени в минутах
function setWorkTime(manualTime) {
    const minutes = Math.ceil(timer.getElapsedSeconds() / 60);

    document.querySelector("#realworktime").value = manualTime ?
        manualTime :
        minutes;
}

// переключение видимости по селектору
function toggleVisibility(selector, isHidden) {
    document.querySelector(selector).style.visibility = isHidden ?
        "hidden" :
        "visible"
}

// меняем вид таймера при паузе
function setPauseDisplay(pause) {
    document.querySelector("#timespent").style.color = pause ? "gray" : "black";

    // прячем кнопку для паузы
    toggleVisibility("#timer_pause", pause);
    // показываем кнопку для включения
    toggleVisibility("#timer_play", !pause);
}

// Получение номера баги из поля
function getBugIdFromField() {
    const field = document.querySelector("#changeform input[name=id]");

    if (field) {
        return parseInt(field.value);
    }

    return false;
}

// Является ли пользователь сотрудником Etersoft
function isEtersoft() {
    const email = document.getElementById("useremail").className;

    if (!email) return false;

    const domain = email.split("@")[1];

    return domain === "etersoft.ru";
}

// Является ли пользователь ответственным
function isWorker() {
    const email = document.getElementById("useremail").className;
    const assignemail = document.getElementById("assigntoemail").className;

    return email == assignemail;
}

// функция для получения времени с таймера в минутах
function getTimespentValue() {
    return Math.round(timer.getElapsedSeconds() / 60);
}

// лямбда для получения числового значения времени по селектору
const parseTimeInt = (selector) => parseInt(document.querySelector(selector).value);

// лямбда для получения числового значения времени из элемента
const parseTimeIntFromData = (elem) => parseInt(elem.dataset["time"]);

// лямбда для перевода времени из минут в часы
const calcTimeValue = (time) => Math.ceil((time / 60) * 100) / 100;

// функция для обновления оставшегося времени
function updateRemainingTime(workTimeValue) {
    // получаем estimatedTime
    const estimatedTimeElement = document.querySelector('#estimated_time');
    const workedTimeElement = document.querySelector('.bz_time_tracking_table > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(3)');

    if (estimatedTimeElement && workedTimeElement) {
        const estimatedTime = Number(estimatedTimeElement.value);

        // получаем отработанное время
        const workedTime = Number(workedTimeElement.innerText);

        // пересчитанное отработанное время
        const updatedWorkedTime = ((workedTime * 100) + (workTimeValue * 100)) / 100;

        // считаем сколько осталось
        const remainingTimeValue = Math.ceil(((estimatedTime * 100) - (updatedWorkedTime * 100))) / 100;

        // обновляем оставшееся время
        document.querySelector("#remaining_time").value = remainingTimeValue > 0 ? remainingTimeValue : 0;
    }
}

// функция для отправки комментария
function submitComment(commentData) {
    const validatedComment = validateComment(...commentData);

    const { error, text } = validatedComment;

    if (error) {
        alert(text);
        return;
    }

    const bugForm = isBugCreation ? "#Create" : "#changeform";
    document.querySelector(bugForm).submit();
    timer.clear();
    localStorage.removeItem("time");    
}

// функция для валидации комментария
function validateComment(comment, workTimeValue, productiveTimeValue, validationConfig = VALIDATION_CONFIG) {
    const commentLength = comment.length;

    const isMinLength = commentLength > validationConfig.minLength;

    const isMaxWorkTime = workTimeValue > validationConfig.maxTime;
    const isMaxProductiveTime = productiveTimeValue > validationConfig.maxTime;

    const isProductiveTimeHigher = productiveTimeValue > workTimeValue;

    const isNotCommentTooShort = productiveTimeValue > 2 &&
        comment.length < productiveTimeValue * 60;
    
    const isZeroTime = !comment.length && workTimeValue === 0 && productiveTimeValue === 0;

    let error = "";

    if (commentLength) {
        if (!isMinLength) {
            error = "Слишком короткий комментарий";
        } else if (isMaxWorkTime || isMaxProductiveTime) {
            error =  "Недопустимо указывать отработанное/продуктивное время более восьми часов. Правильным следованием рабочему процессу было бы выполнение работы по частям, о каждой из которых будет написано отдельно.";
        } else if (isNotCommentTooShort) {
            error = "Недопустимо коротко комментировать длительные работы. Мы ожидаем не менее 60 символов на каждый указанный час.";
        } else if (isProductiveTimeHigher) {
            error = "Продуктивное время не может быть больше отработанного!";
        }
    } else if (!isZeroTime) {
        error = "Поле комментария не может быть пустым!";
    }

    const errorObj = {
        error: false,
        text: ""
    };

    if (error) {
        errorObj.error = true;
        errorObj.text = error;
    }

    return errorObj;
}

//вывод окна с подтверждением при перезагрузке или закрытии страницы в случае, если поле комментария не пусто
window.addEventListener('beforeunload', function (event) {
    // Cancel the event
    if (document.getElementById("comment").value.length != 0){
        // If you prevent default behavior in Mozilla Firefox prompt will always be shown
        event.preventDefault();
        // Chrome requires returnValue to be set
        event.returnValue = '';
    }
});

window.addEventListener("load", function() {
    // работа с модальным окном
    const openButton = document.querySelector("#commit");
    const closeButton = document.querySelector("#timeQuestionDiv .close");
    const dialog = document.querySelector("#timeQuestionDiv");

    // функция для открытия модального окна для ввода времени
    function opetTimeModal(event) {
        event.preventDefault();

        closeButton.addEventListener("click", () => {
            dialog.style.display = "none";
        })

        if (!isEtersoft()) {
            const comment = document.querySelector('#comment').value.length;

            if (!comment) {
                alert('Поле комментария не может быть пустым!');
                return
            }

            const bugForm = isBugCreation ? "#Create" : "#changeform";
            document.querySelector(bugForm).submit();

            return
        }

        const timespentValue = getTimespentValue();

        dialog.style.display = "block";

        focusManager.capture(dialog);

        // записываем отработанное время
        document.querySelector("#realworktime").value =
            !localStorage.time ? timespentValue : localStorage.time;

        document.querySelector("#saveTime").dataset["time"] = timespentValue;
    }

    openButton.addEventListener("click", opetTimeModal);

    // если кнопка сохранить есть сверху, то добавим то же событие
    // и на неё
    const openButtonTop = document.getElementById("commit_top");

    if (openButtonTop) {
        openButtonTop.addEventListener("click", opetTimeModal);
    }

    function updateTimeValue() {
        document.querySelector("#saveTime").dataset["time"] = this.value;
        localStorage.time = this.value;
    }

    document
        .querySelector("#realworktime")
        .addEventListener("change", updateTimeValue);

    document
        .querySelector("#realworktime")
        .addEventListener("paste", updateTimeValue);

    // add listener for enter key down to work time input
    document.querySelector("#realworktime").addEventListener("keyup", (event) => {
        if (event.key === "Enter") {
            document.querySelector("#realworktime").blur();
            document.querySelector("#ProductTime").focus();
        }
    });

    // add listener for enter key down to productive time input
    document.querySelector("#ProductTime").addEventListener("keyup", () => {
        if (event.key === "Enter") {
            document.querySelector("#saveTime").click();
        }
    });

    // add listener for time commit
    const saveTimeButton = document.querySelector("#saveTime");

    saveTimeButton.addEventListener("click", function(event) {
        // cancel form submiting
        event.preventDefault();

        // let's calc time for #work_time input
        let workTime = parseTimeInt("#realworktime");

        const timeFromButton = parseTimeIntFromData(saveTimeButton);

        // если время совпадает с тем что ввёл пользователь
        // будем использовать его
        // иначе будем использовать отработанное
        workTime = workTime === timeFromButton
            ? timeFromButton
            : workTime;

        // если время не задано, то пусть будет нулём
        workTime = workTime || 0;

        const workTimeValue = calcTimeValue(workTime);

        const productiveTime = parseTimeInt("#ProductTime") || workTime;

        const productiveTimeValue = calcTimeValue(productiveTime);

        document.querySelector("#work_time").value = workTimeValue;
        document.querySelector("#productive_time").value = productiveTimeValue;

        // обновим оставшееся время
        if (document.getElementById('estimated_time')) {
            updateRemainingTime(workTimeValue);
        }

        // check comment before submit
        const comment = document.querySelector("#comment").value;

        const commentData = [
            comment,
            workTimeValue,
            productiveTimeValue
        ];

        submitComment(commentData);
    });
});

// let's validate!
function validate(_event) {
    console.log(_event);

    const event = _event || window.event;

    console.log(event);

    let key = event.keyCode || event.which;

    key = String.fromCharCode(key);

    const regex = /[0-9\s]/;

    if (!regex.test(key)) {
        event.returnValue = false;

        if (event.preventDefault) event.preventDefault();
    }
}

function addValidationToElement(selector) {
    // добавляем слушатель на keypress
    document
        .querySelector(selector)
        .addEventListener("keypress", validate);

    // добавляем слушатель на paste
    document
        .querySelector(selector)
        .addEventListener("paste", validate);
}

addValidationToElement("#realworktime");
addValidationToElement("#ProductTime");

