import * as Cookies from "js-cookie";

export interface ILeftMenuModuleOptions {
    /**
     * Selector to toggle and untoggle the menu
     */
    toggleMenuSelector: string;

    /**
     * Indicates if the state should be persisted
     */
    persistState: boolean;

    /**
     * Days the state is saved
     */
    persistStateForDays?: number;

}

export default class LeftMenuModule {

    private options: ILeftMenuModuleOptions;
    private $toggleMenuButton: JQuery;
    private menuHiddenClass = "menu-hidden";
    private menuHiddenCookieName = "leftmenu-hidden";
    private menuHiddenManuallyTriggeredCookieName = "leftmenu-manually-triggered";

    constructor(options: ILeftMenuModuleOptions) {

        this.showMenu = this.showMenu.bind(this);
        this.options = options;

        this.initialiseLeftMenu();
    }

    public isSmallScreen() {
        return window.matchMedia("(max-width: 767px)").matches;
    }

    public isMenuVisible() {
        return $("body").hasClass(this.menuHiddenClass) !== true;
    }

    public showMenu(show: boolean) {

        $(window).trigger("menu-toggle");

        const $body = $("body");
        const hamburgerIcon = $(this.options.toggleMenuSelector).find(".hamburger");
        const hamburgerIconActiveClass = "is-active";

        if (show === true) {
            $body.removeClass(this.menuHiddenClass);
            hamburgerIcon.addClass(hamburgerIconActiveClass);

            if (this.options.persistState === true) {
                Cookies.remove(this.menuHiddenCookieName);
            }
        } else {
            $body.addClass(this.menuHiddenClass);
            hamburgerIcon.removeClass(hamburgerIconActiveClass);

            if (this.options.persistState === true) {

                const cookieOptions: Cookies.CookieAttributes = {};

                if (this.options.persistStateForDays !== undefined && this.options.persistStateForDays > 0) {
                    cookieOptions.expires = this.options.persistStateForDays;
                }

                Cookies.set(this.menuHiddenCookieName, true.toString(), cookieOptions);
            }
        }

        $(".left-menu").one("webkitTransitionEnd otransitionend msTransitionEnd transitionend", function () {
            $(window).trigger("menu-toggled");
        });
    }

    public didManuallyToggleMenu() {
        const manuallyToggledMenuCookie = Cookies.get(this.menuHiddenManuallyTriggeredCookieName);

        if (manuallyToggledMenuCookie !== undefined && manuallyToggledMenuCookie === "true") {
            return true;
        }

        return false;
    }

    private initialiseLeftMenu() {

        this.$toggleMenuButton = $(this.options.toggleMenuSelector);

        if (this.options.persistState === true) {
            $(document).ready(() => {
                const sidebarMenuShouldBeHidden = Cookies.get(this.menuHiddenCookieName) !== undefined;
                if (sidebarMenuShouldBeHidden === true) {
                    if (this.isMenuVisible() === true) {
                        this.showMenu(false);
                    }
                }
            });
        }

        const isSmallScreen = this.isSmallScreen();

        if (isSmallScreen === true && this.isMenuVisible() === true) {
            this.showMenu(false);
        }

        this.$toggleMenuButton.click(() => {

            if (this.options.persistState === true) {

                const cookieOptions: Cookies.CookieAttributes = {};

                if (this.options.persistStateForDays !== undefined && this.options.persistStateForDays > 0) {
                    cookieOptions.expires = this.options.persistStateForDays;
                }

                Cookies.set(this.menuHiddenManuallyTriggeredCookieName, true.toString(), cookieOptions);
            }

            if (this.isMenuVisible() === true) {
                this.showMenu(false);
            } else {
                this.showMenu(true);
            }
        });

        $(".menu-link:not(.sub-menu-header)").click((e) => {
            if (this.isSmallScreen() === true) {
                console.log("menu clicked while small screen", e.target, e.currentTarget, e);

                this.showMenu(false);
            }
        });
    }
}
