<template>
  <div class="menu">
    <BmsIconButton
      @click="toggleMenu(!isMenuOpen)"
      data-testid="openMenu"
      aria-label="Ouvrir le menu"
    >
      <Menu />
    </BmsIconButton>

    <Teleport to="body">
      <Transition :duration="200" name="menu-slide-left-fade">
        <BmsOverlay :active="isMenuOpen">
          <div
            v-if="isMenuOpen"
            ref="menu"
            class="menu__container"
            :class="{ 'is-show': isMenuOpen }"
          >
            <BmsIconButton
              class="menu__close"
              @click="toggleMenu(false)"
              data-testid="closeMenu"
              aria-label="Fermer le menu"
              icon
            >
              <X />
            </BmsIconButton>
            <BmsMenuNav
              :items="items"
              :active-link="route"
              @close-menu="toggleMenu"
            >
              <template #additional="{ closeMenu }">
                <slot name="additional" :closeMenu="closeMenu"></slot>
              </template>
            </BmsMenuNav>

            <div class="menu__copyright">
              <slot name="footer">
                <p class="menu__copyright-madein">Made with ♥ by BMS</p>
              </slot>
            </div>
          </div>
        </BmsOverlay>
      </Transition>
    </Teleport>
  </div>
</template>

<script lang="ts" setup>
import { Menu, X } from 'lucide-vue-next';
import { MenuItem, ParentMenuItem } from '@/models/menu.model';
import { ref } from 'vue';
import BmsOverlay from '../layout/BmsOverlay.vue';
import { BmsIconButton } from '@/index';
import { useRoute } from 'vue-router';
import BmsMenuNav from './BmsMenuNav.vue';
import { onClickOutside } from '@vueuse/core';

const route = useRoute();

interface Props {
  items: (MenuItem | ParentMenuItem)[];
  open?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  open: false,
});

const isMenuOpen = ref(props.open);
const menu = ref(null);

onClickOutside(menu, () => {
  toggleMenu(false);
});

const toggleMenu = (newMenuState: boolean = true) =>
  (isMenuOpen.value = newMenuState);
</script>

<style lang="scss" scoped>
.menu {
  &__container {
    --menu-margin: 1.5rem;

    position: fixed;
    display: flex;
    flex-direction: column;
    top: 0;
    left: 0;
    height: calc(100vh - var(--menu-margin) * 2);
    width: calc(24rem + var(--menu-margin) * 2);
    background: var(--bms-white);
    margin: 1.5rem;
    padding: 0;
    border-radius: 0.5rem;
    z-index: var(--bms-z-index-fixed);
  }

  &__copyright {
    position: sticky;
    padding: 1rem;
    text-align: center;

    &-madein {
      font-size: 0.75em;
      margin: 0;
      opacity: 0.64;
    }
  }

  &__logo {
    width: 100%;
    object-fit: contain;
    height: 4rem;
    display: block;
  }
}

:deep(.menu__close) {
  position: absolute;
  top: 0;
  margin: 0.5rem;
  right: 0;
}

.menu-slide-left-fade-enter-active,
.menu-slide-left-fade-leave-active {
  transition: opacity 0.2s linear;
}

.menu-slide-left-fade-enter-from,
.menu-slide-left-fade-leave-to {
  opacity: 0;
}

.menu-slide-left-fade-enter-active .menu__container,
.menu-slide-left-fade-leave-active .menu__container {
  transition: transform 0.2s ease-in-out;
}

.menu-slide-left-fade-enter-from .menu__container,
.menu-slide-left-fade-leave-to .menu__container {
  transform: translate3d(-10%, 0, 0);
}
</style>
