//const faServer = 'http://localhost:7071'; // LocalTest
//const faServer = 'https://vetbook.azurewebsites.net'; // JCD Vis Studio
const faServer = 'https://gvgbook.azurewebsites.net'; // JCD Vis Studio

var VaildityInfo = {
    "lastname": { length: 3, func: null },
    "email": { length: 9, func: validateEmail },
    "petname": { length: 2, func: null },
    "phonenumber": { length: 11, func: null },
    "preferreddate": { length: 3, func: null },
    "apptreason": { length: 3, func: null }
};


$(document).ready(function () {

    $("#requestslot").hide();
    stethoscope();



    // Clear the form to a known state
    $("#lastname").val(getUrlParam('lastname', ''));
    $("#email").val(getUrlParam('email', ''));
    $("#petname").val(getUrlParam('petname', ''));
    $("#phonenumber, #apptreason, #preferreddate").val("");



    $("#PreferredTime_0").prop('checked', true);
    $("#PreferredTime_1, #PreferredTime_2, #PreferredTime_3, #PreferredTime_4").prop('checked', false);
    $("#exsistingclient_0, #exsistingclient_1").prop('checked', false);


    var appttype = getUrlParam('appttype', '0');

    $("#appointmenttype_0").prop('checked', appttype === '0');
    $("#appointmenttype_1").prop('checked', appttype === '1');
    $("#appointmenttype_2").prop('checked', appttype === '2');
    if (appttype !== '0') ChangeCollapseCSS("#divapptreason", HIDESECTION);
    else ChangeCollapseCSS("#divapptreason", SHOWSECTION);
    $("#chosenbranch").prop('selectedIndex', -1);


    //  Time checkboxes
    $("#PreferredTime_0").change(function () {
        $("#PreferredTime_1, #PreferredTime_2, #PreferredTime_3, #PreferredTime_4").prop('checked', false);
    });

    $("#PreferredTime_1, #PreferredTime_2, #PreferredTime_3, #PreferredTime_4").change(function () {
        $("#PreferredTime_0").prop('checked', false);
    });


    // Validity checks

    $("#lastname").on("keyup", function () { markValid("lastname", false) });
    $("#email").on("keyup", function () { markValid("email", false) });
    $("#petname").on("keyup", function () { markValid("petname", false) });


    // Registered/Not Registered bclick and locate details

    $("input[type=radio][name='exsistingclient']").change(function () {


        failedCheck = null;

        $("#lastname, #email, #petname").each(function () {
            if (markValid(this.id, true) === false && failedCheck === null) failedCheck = this.id;
        });



        if (failedCheck !== null) {
            $('#' + failedCheck).focus();
            ChangeCollapseCSS("#FormSection1Errors", SHOWSECTION);
            $("#exsistingclient_0, #exsistingclient_1").prop('checked', false);
            //e.preventDefault();
            FCS_postHeightToParent();
            return;
        }


        ChangeCollapseCSS("#FormSection1Errors", HIDESECTION);

        selected_value = $("input[type=radio][name='exsistingclient']:checked").val();
        if (selected_value === 'newclient') {
            NewDetailsSection(SHOWSECTION);
        }
        else if (selected_value === 'yes') {
            NewDetailsSection(HIDESECTION);
            locateDetails();
            //e.preventDefault();
        }

        FCS_postHeightToParent();
    });

    $("#phonenumber").on("keyup", function () { markValid("phonenumber", false) });

    $("#chosenbranch").change(function () {
        branch = $("#chosenbranch").val();
        if (branch !== "") {


            failedCheck = null;

            $("#lastname, #email, #petname, #phonenumber").each(function () {
                if (markValid(this.id, true) === false && failedCheck === null) failedCheck = this.id;
            });



            if (failedCheck !== null) {
                $('#' + failedCheck).focus();
                ChangeCollapseCSS("#FormSection1Errors", SHOWSECTION);
                $("#exsistingclient_0, #exsistingclient_1").prop('checked', false);
                $("#chosenbranch").prop('selectedIndex', -1);

                FCS_postHeightToParent();
                return;
            }


            ChangeCollapseCSS("#getdetails", HIDESECTION);
            ChangeCollapseCSS("#getdates", SHOWSECTION);

            ShowDetailsSummary($("#chosenbranch option:selected").text(), $("#lastname").val(), false, true);

            $("#requestslot").show();
            $("#preferreddate").focus();

            FCS_postHeightToParent();
        }
    });

    $("input[type=radio][name='appointmenttype']").change(function () {
        selected_value = $("input[type=radio][name='appointmenttype']:checked").val();
        if (selected_value === 'Vet consultation') ChangeCollapseCSS("#divapptreason", SHOWSECTION);
        else {
            ChangeCollapseCSS("#divapptreason", HIDESECTION);
            $('#apptreason').val("");
            resetValidityCSS('#apptreason');
        }

        FCS_postHeightToParent();
    });

    $("#apptreason").on("keyup", function () { markValid("apptreason", false) });

    $("#preferreddate").on("keyup", function () { markValid("preferreddate", false) });

    /*
    Show hide the Calendar
    */
    $('#calendar').on("click", function (e) {
        var today = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate());
        $('#preferreddate').datepicker(
            {
                minDate: today,
                modal: true,
                format: 'dd mmmm yyyy',
                close: function (e) {
                    $('#preferreddate').datepicker().destroy();
                    $('#preferreddate').removeClass().addClass("form-control");
                }
            }).open();

        FCS_postHeightToParent();
    });



    $('#requestslot').on("click", function (e) {



        faulting = null;
        if (markValid('preferreddate', true) === false) faulting = '#preferreddate';
        if ($("input[type=radio][name='appointmenttype']:checked").val() === 'Vet consultation' && markValid('apptreason', true) === false) faulting = '#apptreason';



        if (faulting !== null) {
            $(faulting).focus();
            ChangeCollapseCSS("#FormSection2Errors", SHOWSECTION)
            e.preventDefault();
            FCS_postHeightToParent();
            return;
        }

        ChangeCollapseCSS("#FormSection2Errors", HIDESECTION)
        hideServiceNotice();
        ChangeCollapseCSS("#requestslotDiv", HIDESECTION);
        ChangeCollapseCSS("#getdates", HIDESECTION);
        $("#requestslot").hide();

        ChangeCollapseCSS("#firstSpinner", SHOWSECTION);
        startSlotSearch();
        e.preventDefault();

        FCS_postHeightToParent();
    });


    $('#differentdates').on("click", function (e) {

        hideServiceNotice();
        ChangeCollapseCSS("#firstSpinner", HIDESECTION);
        ChangeCollapseCSS("#availableSlots", HIDESECTION);
        ChangeCollapseCSS("#requestslotDiv", SHOWSECTION);
        ChangeCollapseCSS("#getdates", SHOWSECTION);

        $("#requestslot").show();
        $("#preferreddate").focus();
        e.preventDefault();

        FCS_postHeightToParent();
    });

    /*
    Booking a slotoptions
    */
    $('#bookslot').on("click", function (e) {
        ChangeCollapseCSS("#bookslotDiv", HIDESECTION);
        ChangeCollapseCSS("#secondSpinner", SHOWSECTION);
        bookSlot();
        e.preventDefault();

        FCS_postHeightToParent();
    });

    FCS_postHeightToParent();

});


/*
 * ===========================Doc Ready Ends =======================================================
 */





function resetValidityCSS(id) {
    $(id).removeClass("is-valid");
    $(id).removeClass("is-invalid");
}


function markValid(controlID, markInvalid) {

    id = '#' + controlID;
    minLength = VaildityInfo[controlID].length;
    extraCheck = VaildityInfo[controlID].func;
    resetValidityCSS(id);

    if ($(id).val() !== "" && $(id).val().length >= minLength && (extraCheck === null || extraCheck($(id).val()) === true)) {

        $(id).addClass("is-valid");
        return true;
    }
    if (markInvalid) $(id).addClass("is-invalid");

    return false;
}

function validateEmail(email) {
    const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
}




/*
 Processing for find slots
 */

function startSlotSearch() {
    // Kick off the initial request



    fetch(faServer + '/api/startSlotSearch', {
        method: 'POST', // *GET, POST, PUT, DELETE, etc.
        mode: 'cors', // no-cors, *cors, same-origin
        cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
        credentials: 'same-origin', // include, *same-origin, omit
        headers: {
            'Content-Type': 'application/json'
        },
        redirect: 'follow', // manual, *follow, error
        referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
        body: JSON.stringify($('form').serializeJSON()) // body data type must match "Content-Type" header
    })
        .then(res => res.json())
        .then((out) => {
            startSlotSearchResults(out);
            console.log('Output: ', out);
            FCS_postHeightToParent();
        }).catch(err => {
            ChangeCollapseCSS("#firstSpinner", HIDESECTION);
            showServiceNotice("alert-danger", "Remote Service Not Working!", "We are sorry we cannot complete your booking, many apologies.</br>Please try again later.");
            FCS_postHeightToParent();
        });
}



function startSlotSearchResults(results) {
    if (results.status === 'proceed') {
        showServiceNotice("alert-info", "", results.msg);
        getSlots(results.monitorToken);
    }
    else {
        ChangeCollapseCSS("#firstSpinner", HIDESECTION);
        showServiceNotice("alert-danger", "Date Error!", "Sorry, I do not understand the dates you have specified, please try again or use the calendar.");
        $("#requestslotDiv").removeClass().addClass("collapse.show");
        ChangeCollapseCSS("#getdates", SHOWSECTION);
        ChangeCollapseCSS("#requestslotDiv", SHOWSECTION);
        $("#requestslot").show();
        $("#preferreddate").focus();
    }
}


// Status OK - Problem, Message and ?
function showServiceNotice(colour, heading, body) {
    $("#serviceNoticeHeading").html(heading);
    $("#serviceNoticeBody").html(body);
    $("#serviceNotice").removeClass().addClass("alert").addClass(colour).addClass("collapse.show");
}

// Status OK - Problem, Message and ?
function hideServiceNotice() {
    $("#serviceNotice").removeClass().addClass("collapse");
}


function getSlots(monitorToken) {


    function showGetSlotsResults(result) {
        ChangeCollapseCSS("#firstSpinner", HIDESECTION);
        ChangeCollapseCSS("#availableSlots", SHOWSECTION);

        $("#slotresponseid").val(result.slotresponseid);
        // add them in 
        $("#slotoptions").html("");
        result.slots.forEach((item, index) => { $("#slotoptions").append(buildSlotOption(index, item)); });
        if (result.outsidePreferred === true) ChangeCollapseCSS("#outsidePreferred", SHOWSECTION);
        else ChangeCollapseCSS("#outsidePreferred", HIDESECTION);
        ChangeCollapseCSS("#bookslotDiv", SHOWSECTION);
        $("#bookslot").focus();
        $(document).scrollTop($(document).height());
        FCS_postHeightToParent();
    }

    async function subscribe() {
        let response = await fetch(faServer + '/api/getSlots/' + monitorToken, {
            method: 'GET',
            //mode: 'no-cors',
            cache: 'no-cache',
            credentials: 'same-origin',
            redirect: 'follow',
            referrerPolicy: 'no-referrer',

        });

        if (response.status === 504) { // Timeout
            await subscribe();
        } else if (response.status !== 200) {
            await new Promise(resolve => setTimeout(resolve, 1000));
            await subscribe();
        } else {
            // Got message
            let message = await response.json();
            showGetSlotsResults(message);
        }
    }

    subscribe();

}


function buildSlotOption(index, item) {
    var text = '<div class="custom-control custom-radio">' +
        '<input class="custom-control-input" type="radio" name="appointmentSlot" id="appointmentSlot_' + index + '" value="' + item.slotID + '" ' + (index === 0 ? "checked=checked" : "") + ' />' +
        '<label class="custom-control-label" for="appointmentSlot_' + index + '">' + item.slotname + '</label>' +
        '</div > ';

    return text;

}




/*
Kick the server to wake it up
*/
function stethoscope() {
    fetch(faServer + '/api/heartbeat', {
        method: 'GET', // *GET, POST, PUT, DELETE, etc.
        mode: 'no-cors', // no-cors, *cors, same-origin
        cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
        credentials: 'same-origin', // include, *same-origin, omit
        redirect: 'follow', // manual, *follow, error
        referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url

    })
        .then(res => {
            console.log('Output: ', res.status);
        }).catch(err => {
            console.log('Error: ', err);
        });
}

/*
Helper functions
*/
const HIDESECTION = false;
const SHOWSECTION = true;

function NewDetailsSection(visibility) {
    if (visibility === SHOWSECTION) {
        ChangeCollapseCSS("#collapseBranch", SHOWSECTION);
        ChangeCollapseCSS("#RegisteredSpinner", HIDESECTION);
        ChangeCollapseCSS("#RegisteredServiceNotice", HIDESECTION);
        $("#chosenbranch option:selected").attr("selected", null);
    }
    else {
        ChangeCollapseCSS("#collapseBranch", HIDESECTION);
        ChangeCollapseCSS("#RegisteredSpinner", SHOWSECTION);
    }
}


function ChangeCollapseCSS(id, visibility) {
    if (visibility === SHOWSECTION) $(id).removeClass("collapse").addClass("collapse.show");
    else $(id).removeClass("collapse.show").addClass("collapse");

}


function ShowDetailsSummary(branch, clientname, newpet, newclient) {
    ChangeCollapseCSS("#collapseBranch", HIDESECTION);
    ChangeCollapseCSS("#SummaryDetails", SHOWSECTION);

    strNewpet = (newpet) ? " (New Pet)" : "";
    strNewclient = (newclient) ? " (New Client)" : "";
    strBranchLabel = (newclient) ? "Selected Branch" : "Registered Branch";
    strPhoneNo = (newclient) ? " / " + $("#phonenumber").val() : "";

    txt = "Your Name: <B>" + clientname + strNewclient + "</B><br>" +
        "Contact Details:- <B>" + $("#email").val() + strPhoneNo + "</B><br>" +
        "Pet's Name:- <B>" + $("#petname").val() + strNewpet + "</B><br>" +
        strBranchLabel + ":- <B>" + branch;

    $("#SummaryDetailsTA").html(txt);

}

function locateDetails() {

    subscribe();

    async function subscribe() {
        let response = await fetch(faServer + '/api/checkreg', {
            method: 'POST',
            //mode: 'Access-Control-Allow-Origin',
            cache: 'no-cache',
            credentials: 'same-origin',
            headers: {
                'Content-Type': 'application/json'
            },
            redirect: 'follow', // manual, *follow, error
            referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
            body: JSON.stringify($('form').serializeJSON()) // body data type must match "Content-Type" header

        }).catch(err => {
            $("#firstSpinner").removeClass("collapse.show").addClass("collapse");
            showServiceNotice("alert-danger", "Remote Service Not Working!", "We are sorry we cannot complete your booking, many apologies.</br>Please try again later.");

        });



        if (response.status === 504) await subscribe();
        else if (response.status !== 200) {
            await new Promise(resolve => setTimeout(resolve, 1000));
            await subscribe();
        }
        else {
            // Got message
            let message = await response.json();
            if (message.linkfailed) {
                $("#firstSpinner").removeClass("collapse.show").addClass("collapse");
                showLocateServiceNotice("alert-danger", "Remote Service Not Working!", "We are sorry we cannot complete your booking, many apologies.</br>Please try again later.");

            }
            else showLocateDetailsResults(message);
        }
    }
}



function bookSlot() {


    function showBookSlotResults(result) {


        ChangeCollapseCSS("#secondSpinner", HIDESECTION);

        switch (result) {
            case "Booked":
                $("#bookedNoticeHeading").html("All Booked");
                $("#bookedNoticeBody").html("Your appointment, " + $("input[type=radio][name='appointmentSlot']:checked").next('label:first').html() + " has been booked and we look forward to seeing you. You should shortly receive an email confirming the details.");
                ChangeCollapseCSS("#availableSlots", HIDESECTION);
                ChangeCollapseCSS("#serviceNotice", HIDESECTION);
                ChangeCollapseCSS("#bookedNotice", SHOWSECTION);
                break;

            case "FailedToGetSlot":
                showServiceNotice("alert-danger", "This appointment time is currently unavailable", "We’re very sorry but another user has just booked this appointment. Please try selecting an alternative time.");
                ChangeCollapseCSS("#availableSlots", HIDESECTION);
                $("#slotoptions").html("");
                ChangeCollapseCSS("#getdates", SHOWSECTION);
                ChangeCollapseCSS("#requestslotDiv", SHOWSECTION);
                $("#requestslot").show();
                $("#preferreddate").focus();
                break;
            default:
        }





        // yes all over no allow rebook
        $(document).scrollTop($(document).height());
    }

    async function subscribe() {
        hideServiceNotice();
        let response = await fetch(faServer + '/api/bookSlot', {
            method: 'POST',
            //mode: 'no-cors',
            cache: 'no-cache',
            credentials: 'same-origin',
            headers: {
                'Content-Type': 'application/json'
            },
            redirect: 'follow',
            referrerPolicy: 'no-referrer',
            body: JSON.stringify($('form').serializeJSON())
        }).catch(err => {
            ChangeCollapseCSS("#SecondSpinner", HIDESECTION);
            showServiceNotice("alert-danger", "Remote Service Not Working!", "We are sorry we cannot complete your booking, many apologies.</br>Please try again later.");

        });

        if (response.status === 504) { // Timeout
            await subscribe();
        } else if (response.status !== 200) {
            await new Promise(resolve => setTimeout(resolve, 1000));
            await subscribe();
        } else {
            // Got message
            let message = await response.text();
            showBookSlotResults(message);
        }

    }

    subscribe();

}



function showLocateServiceNotice(colour, heading, body) {
    $("#RegisteredServiceNoticeHeading").html(heading);
    $("#RegisteredServiceNoticeBody").html(body);
    ChangeCollapseCSS("#RegisteredServiceNotice", SHOWSECTION);
}

// Status OK - Problem, Message and ?
function hideLocateServiceNotice() {
    ChangeCollapseCSS("#RegisteredServiceNotice", HIDESECTION);
}



function showLocateDetailsResults(result) {
    ChangeCollapseCSS("#RegisteredSpinner", HIDESECTION);

    if (result.response.registeredbranchshortcode !== '') $('#chosenbranch').val(result.response.registeredbranchshortcode);

    if (result.response.foundclient && result.response.foundpet) {

        ChangeCollapseCSS("#getdetails", HIDESECTION);
        ChangeCollapseCSS("#getdates", SHOWSECTION);

        ShowDetailsSummary($("#chosenbranch option:selected").text(), result.response.clientname, false, false);

        $("#requestslot").show();
    }
    else if (result.response.foundclient && !result.response.foundpet) {
        heading = "Pet not found";
        body = "We believe your details are :- <b>" + result.response.clientname + ", registered @ " + $("#chosenbranch option:selected").text() + "</b></br>" +
            "However, we cannot find a pet named:- <b>" + $("#petname").val() + "</b>, registered to you, perhaps this is a new pet ?</br>" +
            "Please select one of the options below, thank you<br>";
        showLocateServiceNotice("alert-warning", heading, body)
        $("#RSNButton1").html("Alter pet details above").off("click").on("click", function () {
            hideLocateServiceNotice();
            $("#exsistingclient_0").prop('checked', false);
            $("#petname").focus();
        }
        );
        $("#RSNButton2").html("Continue with new pet").off("click").on("click", function () {

            ChangeCollapseCSS("#getdetails", HIDESECTION);
            hideLocateServiceNotice();

            ShowDetailsSummary($("#chosenbranch option:selected").text(), result.response.clientname, true, true);
            ChangeCollapseCSS("#getdates", SHOWSECTION);
            $("#requestslot").show();
            $("#preferreddate").focus();
        }
        );
    }
    else {
        heading = "Client not found";
        body = "I am sorry we cannot find you registered at any of our branches. Perhaps you have supplied an email or telephone number that is not the one registered with us ?<br>Please select one of the options below, thank you<br>";
        showLocateServiceNotice("alert-warning", heading, body)
        $("#RSNButton1").html("Alter details above").off("click").on("click", function () {
            hideLocateServiceNotice();
            $("#exsistingclient_0").prop('checked', false);
            $("#lastname").focus();
        }
        );
        $("#RSNButton2").html("Continue as new client").off("click").on("click", function () {
            hideLocateServiceNotice();
            $("#exsistingclient_0").prop('checked', false);
            $("#exsistingclient_1").prop('checked', true);
            $("#chosenbranch option:selected").attr("selected", null);
            $("#collapseBranch").removeClass("collapse").addClass("collapse.show");
        }

        );

        $(document).scrollTop($(document).height());
    }

    FCS_postHeightToParent();
}

function FCS_postHeightToParent() {
    if (!inIframe) return;
    var height =
        $('#bookFormHeader').outerHeight(true) +
        $('#bookForm').outerHeight(true)
    // var targetOrigin = 'http://goddard-vets.local/book-an-appointment/';
    var targetOrigin = '*';
    parent.postMessage(height + 'px', targetOrigin);
}


function inIframe() {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}


function getUrlVars() {
    var vars = {};
    var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
        vars[key] = value;
    });
    return vars;
}




function getUrlParam(parameter, defaultvalue) {
    var urlparameter = defaultvalue;
    if (window.location.href.indexOf(parameter) > -1) {
        urlparameter = decodeURI(getUrlVars()[parameter]);
    }
    return urlparameter;
}