var clientUUID = '';
var advancedDisplayed = false;
var json = {};
var jsonIndex = 0;
var lastId = 1;
var htable_row = 0;
var host = window.location.protocol + "//" + window.location.hostname + ":8097";
var dataModified = false;
const addMessageName = 'addMessage';
const loadMessageName = 'changeMessage';
const removeMessageName = 'removeMessage';

const C_UUID = 'mock-uuid';
const C_ID = 'last-displayed-id';
const C_ADV = 'advanced-mode';

const color_red = "#ff8f8f";
const color_grey = "#6b6b6b";

const setModified = function(){
    setDataModified();
}
const setOrigin = function(){
    setDataOrigin();
}

const getUpdate = function(){
    updateData();
}
const dataRefresh = function(){
    getData();
}
$('#btn-newtile').click(function(){callAddMessage()});
// $('#btn-addRow').click(function(){addRow()});
// $('#btn-save').click(getUpdate);

function getData(){
    $.getJSON(host + '/api/mock/'+clientUUID, function(data) {
        json = data;
        checkUuid();
        
        
        refreshData();
    });
}


function checkUuid(){
    if(clientUUID == null || clientUUID == undefined || clientUUID == ''){
        clientUUID = json[0].clientUUID;
        setCookie();
    }
}

function getDomain(){
    var url = window.location.href;
    var arr = url.split("/");
    var result = arr[0] + "//" + arr[2];
    return result;
}

function httpStatusInvalid(){
    value = $('#httpStatus').val();
    return value == '';
}

function setDataModified(){
    if(httpStatusInvalid()){
        $('#btn-save').removeClass('active');
        $('#btn-save').off();
        document.getElementById("httpStatus").style.backgroundColor = color_red;
        return;
    }
    dataModified = true;
    $('#btn-save').addClass('active');
    $('#btn-save').click(getUpdate);
    document.getElementById("httpStatus").style.backgroundColor = null;
}

//Adding change listener to fields
$('.data-field').change(setModified);

function setDataOrigin(){
    dataModified = false;
    $('#btn-save').removeClass('active');
    $('#btn-save').off();
}

const idToDisplay = function(){
    let defaultId = json[0].mockedResponseId;
    if(lastId == undefined || lastId == null) return defaultId;
    for(let i=0; i<json.length; i++){
        if(json[i].mockedResponseId == lastId){
            return lastId;
        }
    }
    if(jsonIndex <= json.length && jsonIndex > 0){
        jsonIndex -= 1;
        return json[jsonIndex].mockedResponseId;
    } 
    return defaultId;
}

function refreshData(){
    $("#uuid-input").val(clientUUID);
    fillMessageList();
    
    let id = idToDisplay();
    
    loadMessage(id);
    
}

function setCookie(){
    document.cookie = C_UUID + '=' +clientUUID;
    document.cookie = C_ID + '=' + lastId;
    document.cookie = C_ADV + '=' + advancedVisibility;
}

function loadCookies(){
    clientUUID = getCookie(C_UUID);
    lastId = getCookie(C_ID);
    advancedDisplayed = getCookie(C_ADV) == 'true';
}

function getCookie(cname) {
    var name = cname + '=';
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i <ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return '';
}

function callMethodByName(methodObject){
    let name = methodObject.name;
    let id = methodObject.id;
    switch(name){
        case addMessageName: 
            addMessage();
            break;
        case loadMessageName:
            loadMessage(id);
            break;
        case removeMessageName:
            removeMessage(id);
            break;
    }
}


function updateData(){
    var updatedJson = generateJson();
    const dataSaved = function () {
        setDataOrigin();
        refreshData();
        savedModalDisplay();
    }
    $.ajax({
        url: host + '/api/mock',
        type: 'PUT',
        data: JSON.stringify(updatedJson, null, 2),
        contentType: "application/json",
    }).done(dataSaved);
}

function callAddMessage(){
    if(dataModified){
        setMethodToCall(addMessageName, null);
        dataLossModalDisplay();
    }
    else {
        addMessage();
    }
}

function addMessage(){
    $.ajax({
        url: host + '/api/mock/'+clientUUID,
        type: 'POST',
    }).done(dataRefresh);
}

function callRemoveMessage(id){
    if(dataModified){
        setMethodToCall(removeMessageName, id);
        dataLossModalDisplay();
    }
    else {
        removeMessage(id);
    }
}

function removeMessage(id){
    var jsonObject = findJsonById(id);
    $.ajax({
        url: host + '/api/mock/'+clientUUID + '/' + id,
        type: 'DELETE',
    }).done(dataRefresh);
}


function clearMock(){
    fillStaticFields('','','','');
    htable_row = 0;
    $('#httpStatusValues').html('');
}

function initializeMock(index){
        clearMock();
        fillStaticFields(json[index].clientUUID
            , json[index].mockedResponseId
            , json[index].mediaType
            , json[index].messageBody
            , json[index].httpStatus);
        fillHeaderTable(json[index].httpHeaders);
}

function fillStaticFields(uuid, id, mediaType, body, httpStatus){
    let link = createLink(uuid,id);
    let linkHtml = '<a class="hyperlink" target="_blank" href="'+link+'">'+link+'</a>';
    $('#messageLink').html(linkHtml);
    $('#httpStatus').val(httpStatus);
    $('#uuid-input').val(uuid);
    $('#typeSelector').val(mediaType);
    $('#bodyEditor').val(body);
    $('#mockedMessageId').html(id);

}

function changeEditionOfUUID(element){

    var inputFieldId= "#uuid-input"
    var inputFieldDiv = "#uuid-edit-field"
    if(element.checked){
        $(inputFieldId).removeAttr('disabled');
        $(inputFieldDiv).removeClass('disabled');
    } else{
        $(inputFieldId).attr('disabled', true);
        $(inputFieldDiv).addClass('disabled');
    }
}

function copyUUIDToClipboard(){
    navigator.clipboard.writeText( document.getElementById('uuid-input').value );
}


async function fetchUUIDCheck(givenUUID , strategy){
    var newUUID = "UUID" ;
    url = host + "/api/mock/check/";

    switch(strategy){
        case "new":{
            await fetch(url + givenUUID+ "/", { method : "GET" })
                .then ( response => response.text() )
                .then ( data => {
                    newUUID = data;
                    
                } )
            break;
        }
        case "restore":{
            await fetch(url + givenUUID + "/" + clientUUID + "/" , { method: "GET" })
                .then (response => response.text() )
                .then (data => {
                    newUUID = data;
                    
                } )
            break;
        }
    }
    return newUUID ;
}

function checkUUIDChars(uuid) {
    uuid.replace(/ /g,'')
    const regex = new RegExp("^[A-z0-9-]+$");
    
    if(regex.test(uuid) && uuid != ""){
        return uuid ;
    } 
    return "invalid";
 }

function changeUUID(element){

    const uuidStrategy = $('input[name="uuid-validation-type"]:checked').val();
    const givenUUID = checkUUIDChars(element.value);

    if( givenUUID == clientUUID ){
        $("#uuid-input").attr("disabled", true);
        uuidChangeModalDisplay("noChg");
        return;
    }

    var newUUID = fetchUUIDCheck(givenUUID , uuidStrategy);
    var changeMessage = uuidStrategy;
    newUUID
    .then( data => {
        if (givenUUID == data) { 
            changeMessage = "success";
        }
        clientUUID = data;
        $("#editable").attr("checked", false);
        
        uuidChangeModalDisplay(changeMessage);
        document.cookie = C_UUID + '=' + data ;
    } )
    loadCookies();
    refreshData();
}


function createLink(uuid, id){
    var link =  host + '/api/mock/r/'+uuid+'/'+id;
    return link;
}

function fillHeaderTable(headers){
    var innerHTML = buildHeaderMapHtml(headers);
    refreshHeaderTable(innerHTML);
}

function refreshHeaderTable(html){
    $('#headerMapTable').html(html);
    $('.table-map').change(function(){setDataModified()});
    $('.btn-hashmap').click(function(){
        $(this).closest('tr').remove();
        setDataModified();
    })
}

function buildHeaderMapHtml(headers){
    var innerHTML = '';
    for(var key in headers){
        innerHTML += buildRowHtml(key, headers[key]);
    }
    return innerHTML;
}

function addRow(key, value){
    var headerMap = $('#headerMapTable');
    var headersMapHtml = headerMap.html();
    headersMapHtml += buildRowHtml(key, value);
    refreshHeaderTable(headersMapHtml);
}

const newRowInput = function(){
    const hName = $('#headerKeyInput');
    const hValue = $('#headerValueInput');
    if(checkIfInputValid(hName.val()) && checkIfInputValid(hValue.val())){
        addRow(hName.val(), hValue.val());
        hName.val(null);
        hValue.val(null);
        setDataModified();
    }
}

$('#btn-newRow').click(newRowInput);

function checkIfInputValid(input){
    return !(input == '' || input == null || input == undefined);
}

function checkIfHeaderEssential(key){

    if( key == "Connection" || key == "Keep-Alive" || key == "Date" ){
        return true; 
    }
    return false;

}

function buildRowHtml(key, value){

    if(checkIfHeaderEssential(key)){
        return '' + 
        '<tr>' +
            '<td><input class="key data-field" value="' + key + '" readonly></td>' +
            '<td><input class="data-field" value="' + value + '"></td>' +
        '</tr>';
    } 
    return '' + 
    '<tr>' +
        '<td><input class="key data-field" value="' + key + '"></td>' +
        '<td><input class="data-field" value="' + value + '"></td>' +
        '<td><button class="modification-button btn-hashmap"><i class="icon-cancel"></i></button></td>' +
    '</tr>';
}


function fillMessageList(){
    $("#listItems").html('');
    var innerHTML = '';
    for(let i=0; i<json.length; i++){
        innerHTML += generateMessageTileHtml(json[i].mockedResponseId, json[i].httpStatus, json[i].mediaType);
    }
    $("#listItems").append(innerHTML);
    $('.tile').click(function(e) {
        var element = $(this);
        var button = element.find('.btn-tile').children().get(0);
        
        if(!(button == e.target)){
            
            callLoadMessage(parseInt($(this).attr('tileid')));
        }
    });
    $('.btn-tile').click(function(){
        // 
        callRemoveMessage($(this).closest('.tile').attr('tileId'));
    })
}

function findJsonById(id){
    return json[findJsonIndexById(id)];
}

function findJsonIndexById(id){
    for(let i=0; i<json.length; i++)
        if(id == json[i].mockedResponseId) return i;
}

function callLoadMessage(id){
    if(dataModified) {
        setMethodToCall(loadMessageName, id);
        dataLossModalDisplay();
    }
    else {
        loadMessage(id);
    }
}

function loadMessage(id){
    if(id == null || id == undefined){
        
        return;
    }
    lastId = id;
    setCookie();
    setDataOrigin();
    for(let i=0; i<json.length; i++){
        
        if(id == json[i].mockedResponseId){
            jsonIndex = i;
            
            initializeMock(jsonIndex);
            
            selectMessage(id);
            
            return;
        }
    }
    
}


function selectMessage(id){
    const tiles = $('.tile');
    
    tiles.removeClass("active");
    
    $('.tile[tileid="'+id+'"]').addClass("active");
    
    initializeHistory();
    refreshHeaderTable(innerHTML);
}



function generateMessageTileHtml(id, httpStatus, mediaType){
    var innerHTML = '' +
    '<div tileid="' + id + '" class="tile">' +
        '<div class="content">' +
            '<div class="display-space-between">' +
                '<div class="centered-vertically">' +
                    '<p>Id: ' + id + '</p>' +
                    '<p>Status: ' + httpStatus + '</p>' +
                '</div>' +
                '<div>' +
                    '<button class="modification-button btn-tile"><i class="icon-cancel"></i></button>' +
                '</div>' +
            '</div>' +
        '</div>' +
    '</div>';
    return innerHTML;
}



const onbuild = function(){
    loadCookies();
    getData();
    if(advancedDisplayed) {
        changeAdvancedVisibility();
    }
}

$(document).ready(onbuild);

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}



function generateJson(){
    var newJson =
        {
            clientUUID: json[jsonIndex].clientUUID,
            mockedResponseId: json[jsonIndex].mockedResponseId,
            mediaType: $('#typeSelector').val(),
            messageBody: $('#bodyEditor').val(),
            httpStatus: $('#httpStatus').val(),
            httpHeaders: {},
        };
    newJson['httpHeaders'] = convertTableToJson();
    
    json[jsonIndex] = newJson;
    return newJson;
}


function convertTableToJson(){
    const rows = $('#headerMapTable').children();
    
    var obj = {};
    var key;
    for(let i=0; i<rows.length; i++){
        key = rows.eq(i).children().eq(0).children().eq(0).val();
        obj[key] = rows.eq(i).children().eq(1).children().eq(0).val();
    }
    return obj;
}