scarecro / MIQ NZ Date Finder

// ==UserScript==
// @author scarecro
// @collaborator username
// @license MIT
// @copyright 2021, scarecro (https://openuserjs.org/users/scarecro)
// @name         MIQ NZ Date Finder
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  Install the Tampermonkey chrome extension & head to https://allocation.miq.govt.nz/, register and go to "step 2 - hold your accomodation", enable this then, scroll to step 3 area, Enter seconds (20+) until refresh, click START AUTO CHECK. To test, adjust speaker volume and click SIMULATE, be sure to then refresh the page and click START AUTO CHECK again. Turn up your volume to be notified when there is a day available, (may take days, keep checking back). When you hear the music, quickly click the date available and use the "I'm not a robot" tick box and "Next" button to continue to step 3. You will then have 48 hours to secure a flight to land on that day. More details at https://openuserjs.org/scripts/scarecro/MIQ_NZ_Date_Finder .
// @author       Scarecro
// @donate       using Bitcoin, donate to 1LPodbPKn8pnHEi9DxmdkGqwwRQeNaxVFt
// @require      http://code.jquery.com/jquery-3.4.1.min.js
// @match        https://allocation.miq.govt.nz/*
// @icon         https://www.google.com/s2/favicons?domain=govt.nz
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_openInTab
// ==/UserScript==

$(document).ready(function() {
    'use strict';
    let inProgress = GM_getValue("Check_InProgress", false);
    var secondsDelay = GM_getValue("Seconds_Delay", 10);
    GM_setValue("HaveJumped",false);

    var getTestButton = $('<button/>', {
        text: 'START AUTO CHECK',
        click: startChecking,
        class: 'a-button-primary'
    });

    function showSecondsDelay(secondsDelay) {
        var secondsInput = $('<input/>', {
            id: 'secondsDelay',
            value: secondsDelay
        });
        var labelSeconds = $('<label/>', {
            for: 'secondsDelay',
        });
        labelSeconds.html("Refresh seconds:");
        $("#step-3").append(labelSeconds);
        $("#step-3").append(secondsInput);
    }

    if (!inProgress) {
        secondsDelay = GM_getValue("Seconds_Delay", 10);
        $("#step-3").append(getTestButton);
        showSecondsDelay(secondsDelay);
    }

    var getStopButton = $('<button/>', {
        text: 'STOP AUTO CHECK',
        click: stopChecking,
        class: 'a-button-primary'
    });

    var getSimulateButton = $('<button/>', {
        text: 'SIMULATE SUCCESS',
        click: simulateSuccess,
        class: 'a-button-primary'
    });

    if (inProgress) {
        $("#step-3").append(getStopButton);
        $("#step-3").append(getSimulateButton);
    }

    function showAlert(textToAlert) {
        var alertText = $('<h2/>');
        alertText.html(textToAlert);
        $("#step-3").append(alertText);
        var alertSubText = $('<p><div>Quickly select the available date, check details above, and tick "I\'m not a robot", then click "Next".</div>');
        $("#step-3").append(alertSubText);
        //GM_openInTab ("https://bit.ly/3wPgVsq");
        var getVideoPlay = $('<iframe width="100" height="100" src="https://www.youtube.com/embed/Wlz2uEuxyyk?autoplay=1&start=39" frameborder="0" allow="autoplay; encrypted-media"></iframe>');
        $("#step-3").append(getVideoPlay);
    }

    if (inProgress) {
        console.log("seconds delay is " + secondsDelay);
        checkAccomodation();
    }

    function startChecking() {
        GM_setValue("HaveAccomodation",0);
        GM_setValue("Check_InProgress", true);

        var secondsDelay = $('#secondsDelay').val();
        GM_setValue("Seconds_Delay", secondsDelay);
        checkAccomodation();
    }

    function stopChecking() {
        GM_setValue("HaveAccomodation",0);
        GM_setValue("Check_InProgress", false);
    }

    function simulateSuccess() {
        GM_setValue("HaveAccomodation",3);
        GM_setValue("Check_InProgress", false);
        GM_setValue("DayOfMonth", "5");
        showAlert("There is accomodation on Month 3!");
        checkAccomodation();
    }

    function checkAccomodation() {
        let haveAccomodation = GM_getValue("HaveAccomodation", 0);
        $("#form_rooms_0_accessibilityRequirement_1").attr('checked', true);

        checkMonth(0);
        let maxMonths = 4;
        var isLast = false;
        for(var i = 1; i <= maxMonths; i += 1) {
            setTimeout(function(i) {
                if (i == maxMonths) {
                    var isLast = true;
                }
                var flatpickr = document.querySelector("#accommodation-calendar")._flatpickr;
                if (flatpickr != undefined) {
                    flatpickr.changeMonth(1);
                } else {
                    console.log("flatpickr not found1");
                }

                checkMonth(i);
                if (isLast == true) {
                    console.log("is last");
                    //var offset = $('#form_next').offset().top - $(window).height();
                    var offset = $(document).height() - $(window).height() - 400;
                    $("html, body").animate({ scrollTop: offset }, 1000);
                    console.log("Scrolled3 to " + offset);
                    let haveAccomodation = GM_getValue("HaveAccomodation",0);
                    if (haveAccomodation == 0) {
                        setTimeout(function(i) {
                            haveAccomodation = GM_getValue("HaveAccomodation",0);
                            if (haveAccomodation == 0) {
                                console.log("reload here");
                                location.reload();
                            } else {
                                console.log("jump1");

                                if (!GM_getValue("HaveJumped", false)) {
                                    GM_setValue("HaveJumped",true);
                                    jumpToDate(maxMonths, haveAccomodation);
                                }
                            }
                        }, 1000 * secondsDelay);
                    } else {
                        GM_setValue("Check_InProgress", false);
                        console.log("jump2");
                        if (!GM_getValue("HaveJumped", false)) {
                            GM_setValue("HaveJumped",true);
                            jumpToDate(maxMonths, haveAccomodation);
                        }
                    }
                }
            }, 50 * i, i);
        };

        setTimeout(function() {
            haveAccomodation = GM_getValue("HaveAccomodation",0);
            inProgress = GM_getValue("Check_InProgress", false);
            if (haveAccomodation == 0 && inProgress == true) {
                console.log("force reload after 20 minutes.");
                location.reload();
            }
        }, 1200000);
    }

    function jumpToDate(maxMonths, haveAccomodation) {
        var flatpickr = document.querySelector("#accommodation-calendar")._flatpickr;
        if (flatpickr != undefined) {
            //flatpickr.jumpToDate(selectedDate, true)
            console.log("maxMonths = " + maxMonths + ", haveAccomodation = " + haveAccomodation);
            for(var goback = maxMonths; goback >= haveAccomodation; goback -= 1) {
                console.log("role back 1");
                flatpickr.changeMonth(-1);
            }
            console.log("month is " + flatpickr.currentMonth);
            console.log("year is " + flatpickr.currentYear);
            var dateToJumpTo = flatpickr.currentYear + "-" + String(flatpickr.currentMonth+1).padStart(2, '0') + "-" + String(GM_getValue("DayOfMonth", 1)).padStart(2, '0');
            console.log("Date to jump to is " + dateToJumpTo);
            flatpickr.jumpToDate(dateToJumpTo);
            flatpickr.setDate(dateToJumpTo, true);
        } else {
            console.log("flatpickr not found2");
        }
    }

    function checkMonth(i) {
        [].forEach.call(document.getElementsByClassName('flatpickr-day'),function(el) {
            if ($(el).attr("class").indexOf("flatpickr-disabled") == -1) {
                console.log($(el).attr("class") + "=" + el.innerText);
                GM_setValue("DayOfMonth", el.innerText);
                GM_setValue("HaveAccomodation", i+1);
                GM_setValue("Check_InProgress", false);
                showAlert("There is accomodation on Month " + (i+1) + "!");

            } else {
                console.log($(el).attr("class") + " = " + el.innerText);
            }
        });
    }
})();