<template>
    <div class="hy-navigation-container" :class="[sidebarPosition, { isDesktop, sidebarVisibleDesktop, sidebarVisibleMobile }]">
        <div id="sidebar" @click="onSidebarClickOutside($event)" ref="sidebarContainer">
            <slot name="sidebar" />
        </div>

        <div id="tabbar" v-if="isDesktop == false">
            <slot name="tabbar" />
        </div>

        <div id="content">
            <slot name="content" />
        </div>
    </div>
</template>

<script>
export default {
    name: "HyNavigationContainer",
    props: {
        // modelValues for controlling whether sidebar is visible or not
        sidebarVisibleDesktop: {
            type: Boolean,
            default: true,
        },
        sidebarVisibleMobile: {
            type: Boolean,
            default: false,
        },

        // Config parameters
        switchToMobileAt: {
            type: Number,
            default: 850,
        },
        gap: {
            type: String,
            default: "0px",
        },
        doBSL: {
            type: Boolean,
            default: true,
        },

        // Backup props
        sidebarDimensions: {
            type: Object,
            default: null,
        },
        sidebarPosition: {
            type: String,
            default: "left",
        },
    },
    data() {
        return {
            _windowWidth: window.innerWidth,
            _sidebarWidth: "100vw",
        };
    },
    watch: {
        async sidebarVisibleMobile(val) {
            if (this.doBSL == false) return;
            if (this.isDesktop == true) return;

            // Enable / Disable body scroll lock
            const sidebarScrollContainer = this.$refs.sidebarContainer.querySelector("#visual");

            if (val == true) {
                this.hy_bsl_manager.push(sidebarScrollContainer);
            } else {
                this.hy_bsl_manager.remove(sidebarScrollContainer);

                // Wait for transition to finish
                await new Promise((resolve) => setTimeout(() => resolve(), 500));

                // Abort if sidebar was interrupted and reopened before it could close properly
                if (this.modelValue == true) this.hy_bsl_manager.push(sidebarScrollContainer);
            }
        },
        isDesktop() {
            if (this.doBSL == false) return;

            // If BSL was active on mobile, disable it when going into desktop mode
            if (this.isDesktop == true) this.hy_bsl_manager.remove(this.$refs.sidebarContainer.querySelector("#visual"));

            // If the sidebar is open while going into mobile mode, enable BSL
            if (this.isDesktop == false && this.sidebarVisibleMobile == true)
                this.hy_bsl_manager.push(this.$refs.sidebarContainer.querySelector("#visual"));
        },
    },
    computed: {
        sidebarWidth() {
            if (this.sidebarDimensions != null) return this.sidebarDimensions.width;
            else return this._sidebarWidth;
        },
        isDesktop() {
            return this._windowWidth > this.switchToMobileAt;
        },
    },
    methods: {
        receiveSidebarDimensions(dimensions) {
            // Method is triggered by sidebar component (not via an event, but via a method call on the sidebar's parent (this))
            this._sidebarWidth = dimensions.width;
        },
        onSidebarClickOutside(event) {
            if (event.target != this.$refs.sidebarContainer) return; // Only accept clicks directly targeting the sidebarContainer, not the slotted child
            if (this.isDesktop == true) return; // Only on mobile
            if (this.sidebarVisibleMobile == false) return; // Only if sidebar is actually expanded

            this.$emit("update:sidebarVisibleMobile", false);
        },
    },
    mounted() {
        window.addEventListener("resize", (event) => {
            this._windowWidth = event.target.innerWidth;
        });
    },
    beforeUnmount() {
        this.hy_bsl_manager.remove(this.$refs.sidebarContainer.querySelector("#visual"));
    },
};
</script>

<style lang="scss">
.hy-navigation-container {
    --transition: none 0.5s cubic-bezier(0.06, 0.975, 0.195, 0.985);

    #sidebar {
    }

    #content {
        flex: 1;
        position: relative;
        max-width: 100vw;
        min-width: 0;
    }

    &.isDesktop {
        margin: auto;
        display: flex;
        gap: v-bind(gap);

        transition: var(--transition);
        transition-property: gap;

        &.right {
            flex-direction: row-reverse;
        }

        & > #sidebar {
            z-index: 101;
            max-width: v-bind(sidebarWidth);
            overflow: clip;
            box-shadow: var(--hy-section-shadow);

            transition: var(--transition);
            transition-property: max-width;
        }

        &:not(.sidebarVisibleDesktop) {
            gap: 0px;

            & > #sidebar {
                max-width: 0px;
            }
        }
    }

    &:not(.isDesktop) {
        & > #sidebar {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            z-index: 101;
            pointer-events: none;

            transition: var(--transition);
            transition-property: background-color;

            & > * {
                transition: var(--transition);
                transition-property: transform;
            }
        }

        &.left > #sidebar {
            & > * {
                left: 0;
                transform: translateX(-100%);
            }
        }

        &.right > #sidebar {
            & > * {
                left: calc(100vw - v-bind(sidebarWidth));
                transform: translateX(100vw);
            }
        }

        &.sidebarVisibleMobile {
            & > #sidebar {
                pointer-events: all;
                background-color: var(--hy-modal-cover-color-mobile);

                & > * {
                    transform: translateX(0);
                }
            }
        }
    }
}
</style>
