<template>
    <!-- Mobile => show modal -->
    <hy-modal :modelValue="isModalOpen" @update:modelValue="updateModelValue($event, 'modal')" v-bind="modalOptions">
        <template #header v-if="$slots.header">
            <slot name="header" :menuType="menuType" />
        </template>

        <template #content>
            <slot name="menu" :menuType="menuType" /><!-- For backwards compatability; was renamed to "content" -->
            <slot name="content" :menuType="menuType" />
            <slot :menuType="menuType" />
        </template>

        <template #footer v-if="$slots.footer">
            <slot name="footer" :menuType="menuType" />
        </template>
    </hy-modal>

    <!-- Popover => show popover -->
    <hy-popover :modelValue="isPopoverOpen" @update:modelValue="updateModelValue($event, 'popover')" v-bind="popoverOptions">
        <template #element>
            <!-- Element is only displayed inside popover element slot (which is ofc visible all the time) -->
            <slot name="element" />
        </template>

        <template #header v-if="$slots.header">
            <slot name="header" :menuType="menuType" />
        </template>

        <template #content>
            <slot name="menu" :menuType="menuType" /><!-- For backwards compatability; was renamed to "content" -->
            <slot name="content" :menuType="menuType" />
            <slot :menuType="menuType" />
        </template>

        <template #footer v-if="$slots.footer">
            <slot name="footer" :menuType="menuType" />
        </template>
    </hy-popover>
</template>

<script>
import HyPopover from "./Popover.vue";
import HyModal from "./Modal.vue";
import { useMediaQuery } from "@vueuse/core";

export default {
    name: "HySmartMenu",
    props: {
        // SHARED:
        modelValue: {
            type: Boolean,
            required: true,
        },
        headline: {
            type: String,
            default: null,
        },
        description: {
            type: String,
            default: null,
        },

        // MODAL:
        zIndexModal: {
            type: Number,
            default: 200,
        },
        background: {
            type: String,
            default: null,
        },
        showScrollbars: {
            type: Boolean,
            default: false,
        },
        doBSL: {
            type: Boolean,
            default: true,
        },
        swipeToCloseEnabled: {
            type: Boolean,
            default: true,
        },
        dismissible: {
            type: Boolean,
            default: true,
        },
        forceFullHeightOnMobile: {
            type: Boolean,
            default: false,
        },
        doBlurBg: {
            type: Boolean,
            default: false,
        },

        // POPOVER:
        zIndexPopover: {
            type: Number,
            default: 10,
        },
        reference: {
            type: [HTMLElement, String, Object],
            default: null,
        },
        hideOnClickOutside: {
            type: Boolean,
            default: true,
        },
        doConstrainHeight: {
            type: Boolean,
            default: false,
        },
        minWidth: {
            type: String,
            default: "0",
        },
        maxWidth: {
            type: String,
            default: "unset",
        },
        maxHeight: {
            type: String,
            default: "unset",
        },
        variant: {
            type: String,
            default: "match",
            validator(value) {
                return ["match", "contrast"].includes(value);
            },
        },
        placement: {
            type: String,
            default: "bottom",
        },
        offsetMainAxis: {
            type: Number,
            default: 15,
        },
        offsetCrossAxis: {
            type: Number,
            default: 0,
        },
    },
    data() {
        return {
            isMobile: useMediaQuery("(max-width: 799px)"),
        };
    },
    computed: {
        menuType() {
            // Only for scoped slot => Info for parent element
            return this.isMobile ? "modal" : "popover";
        },
        isModalOpen() {
            return this.modelValue == true && this.isMobile == true;
        },
        isPopoverOpen() {
            return this.modelValue == true && this.isMobile == false;
        },
        modalOptions() {
            return {
                zIndex: this.zIndexModal,
                background: this.background,
                showScrollbars: this.showScrollbars,
                doBSL: this.doBSL,
                swipeToCloseEnabled: this.swipeToCloseEnabled,
                dismissible: this.dismissible,
                forceFullHeightOnMobile: this.forceFullHeightOnMobile,
                doBlurBg: this.doBlurBg,
                headline: this.headline,
                description: this.description,
            };
        },
        popoverOptions() {
            return {
                reference: this.reference,
                zIndex: this.zIndexPopover,
                hideOnClickOutside: this.hideOnClickOutside,
                doConstrainHeight: this.doConstrainHeight,
                minWidth: this.minWidth,
                maxWidth: this.maxWidth,
                maxHeight: this.maxHeight,
                variant: this.variant,
                placement: this.placement,
                offsetMainAxis: this.offsetMainAxis,
                offsetCrossAxis: this.offsetCrossAxis,
                headline: this.headline,
                description: this.description,
            };
        },
    },
    methods: {
        updateModelValue(newValue, source) {
            // Only allow updates if event source element is actively shown

            if (source == "modal" && this.isModalOpen) this.$emit("update:modelValue", newValue);
            if (source == "popover" && this.isPopoverOpen) this.$emit("update:modelValue", newValue);
        },
    },
    components: {
        HyPopover,
        HyModal,
    },
};
</script>

<style lang="scss"></style>
