/**
 * Replacement for jQuery's $(document).ready() function.
 * This is handy in making sure stuff fires after the DOM is ready to be touched.
 * Stolen from:https://stackoverflow.com/a/53601942/344028
 *
 * @param fn Callback.
 */
function domReady(fn) {
    // If we're early to the party
    document.addEventListener('DOMContentLoaded', fn);

    // If late; I mean on time.
    if (document.readyState === 'interactive' || document.readyState === 'complete') {
        fn();
    }
}

/**
 * TuiTabs controller
 */
function tabsController() {
    // Get all the tab elements (typically li tags).
    const tabs = document.getElementsByClassName('tui-tab');

    if (!tabs.length) {
        // No tabs found, return early and save a couple CPU cycles.
        return;
    }

    for (const tab of tabs) {
        // Add click listeners to them.
        tab.addEventListener('click', function (e) {

            // Check if the clicked tab is disabled
            if(e.target.classList.contains("disabled")) {
                return;
            }

            // Remove the 'active' class from any and all tabs.
            for (const otherTab of tabs) {
                otherTab.classList.remove('active');
            }

            // Get the content element.
            const tabContents = document.getElementsByClassName('tui-tab-content');

            if (tabContents) {
                for (const tabContent of tabContents) {
                    // Hide all tab contents.
                    tabContent.style.display = 'none';
                }
            } else {
                throw 'No tab content elements found.'
            }

            // Get the id of the tab contents we want to show.
            const tabContentId = e.target.getAttribute('data-tab-content');

            if (tabContentId) {
                const tabContent = document.getElementById(tabContentId);
                if (tabContent) {
                    // Show the tab contents.
                    tabContent.style.display = 'block';
                } else {
                    throw 'No tab content element with id "' + tabContentId + '" found.';
                }
            }
            // We are not going to throw an error here, since we could make the tab do something else that a tab
            // normally wouldn't do.

            // Set the clicked tab to have the 'active' class so we can use it in the next part.
            e.target.classList.add('active');

        });
    }

    // Grab the first tab with the active class.
    const activeTab = document.querySelector('.tui-tab.active');
    if (activeTab) {
        // Now click it 'click' it.
        activeTab.click();
    } else {
        // Nothing found, just click the first tab foud.
        tabs[0].click()
    }
}

/**
 * Date/time field controller
 */
function datetimeController() {
    // Get date/time elements.
    const clocks = document.getElementsByClassName('tui-datetime');

    if (!clocks.length) {
        // No date time elements found, return early and save a couple CPU cycles.
        return;
    }

    // Kick off our clock interval stuff.
    datetimeInterval();

    // Synchronize time and set interval to control the clocks
    setTimeout(() => {
        setInterval(datetimeInterval, 1000);
    }, 1000 - new Date().getMilliseconds());

    function datetimeInterval() {
        for (const clock of clocks) {
            if (clock === null) {
                continue;
            }

            // Get the format we want to display in the element.
            let format = clock.getAttribute('data-format');

            // parse out the date and time into constants.
            const today  = new Date();
            const month  = (today.getMonth() + '').length === 2 ? today.getMonth() + 1 : '0' + (today.getMonth() + 1);
            const day    = (today.getDay() + '').length === 2 ? today.getDay() + 1 : '0' + (today.getDay() + 1);
            const year   = today.getFullYear() + '';
            const hour   = (today.getHours() + '').length === 2 ? today.getHours() : '0' + today.getHours();
            const hour12 = (parseInt(hour) + 24) % '12' || '12';
            const minute = (today.getMinutes() + '').length === 2 ? today.getMinutes() : '0' + today.getMinutes();
            const second = (today.getSeconds() + '').length === 2 ? today.getSeconds() : '0' + today.getSeconds();
            const ampm   = parseInt(hour) >= 12 ? 'PM' : 'AM';

            // Replace based on the format.
            format = format.replace('M', month);
            format = format.replace('d', day);
            format = format.replace('y', year);
            format = format.replace('H', hour);
            format = format.replace('h', hour12);
            format = format.replace('m', minute);
            format = format.replace('s', second);
            format = format.replace('a', ampm);

            // Show it in the element.
            clock.innerHTML = format;
        }
    }
}

/**
 * Sidenav Controller
 * There should only side navigation element at the moment.
 */
function sidenavController() {
    // Get the side navigation button (there should be only one, but if not, we are getting the first one).
    const sideNavButton = document.querySelector('.tui-sidenav-button');

    if (!sideNavButton) {
        // No side navigation button found, return early and save a couple CPU cycles.
        return;
    }

    // Add the click event listener to the buttons.
    sideNavButton.addEventListener('click', () => {
        // Get the side navigation element (there should be only one, but if not, we are getting the first one).
        const sideNav = document.querySelector('.tui-sidenav');

        if (sideNav) {
            if (sideNav.classList.contains('active')) {
                sideNav.classList.remove('active');
            } else {
                sideNav.classList.add('active');
            }
        } else {
            throw 'No sidenav element found.'
        }
    });
}

/**
 * Modal controller
 */
function modalController() {
    // Get the overlap (overlay) element (there should be only one, but if not, we are getting the first one).
    const tuiOverlap = document.querySelector('.tui-overlap');

    if (!tuiOverlap) {
        // No overlap found element, return early and save a couple CPU cycles.
        return;
    }

    // Find modal buttons.
    const modalButtons = document.getElementsByClassName('tui-modal-button');
    for (const modalButton of modalButtons) {
        // Add the click event listener to the buttons.
        modalButton.addEventListener('click', (e) => {
            // Show the overlap.
            tuiOverlap.classList.add('active');

            // Get the display element for the modal.
            const modalId = e.target.getAttribute('data-modal');

            if (modalId) {
                const modal = document.getElementById(modalId);

                if (modal) {
                    // Show it.
                    modal.classList.add('active');
                } else {
                    throw 'No modal element with id of "' + modalId + '" found.';
                }
            } else {
                throw 'Modal close button data-modal attribute is empty or not set.'
            }
        });
    }

    // Find the close modal buttons.
    const modalCloseButtons = document.getElementsByClassName('tui-modal-close-button');

    if (modalButtons.length > 0 && !modalCloseButtons.length) {
        // A modal without a close button, is a bad modal.
        throw 'No modal close buttons found.'
    }

    for (const modalCloseButton of modalCloseButtons) {
        // Add the click event listener to the buttons.
        modalCloseButton.addEventListener('click', (e) => {
            // Hide the the overlap.
            tuiOverlap.classList.remove('active');

            // Get the display element id for the modal.
            const modalId = e.target.getAttribute('data-modal');

            if (modalId) {
                // Get the modal element.
                const modal = document.getElementById(modalId);

                if (modal) {
                    // Hide it.
                    modal.classList.remove('active');
                } else {
                    throw 'No modal element with id of "' + modalId + '" found.';
                }
            } else {
                throw 'Modal close button data-modal attribute is empty or not set.'
            }
        });
    }
}

/**
 * Init: This is at the bottom to make sure it is fired correctly.
 */
domReady(function () {
    tabsController();
    datetimeController();
    sidenavController();
    modalController();
});
