<script lang="ts">
  import MenuHome from '@assets/img/menu-home.webp';
  import MenuSignup from '@assets/img/menu-signup.webp';
  import MenuRules from '@assets/img/menu-rules.webp';
  import MenuFaq from '@assets/img/menu-faq.webp';
  import MenuFeature from '@assets/img/menu-features.webp';
  import MenuAdmins from '@assets/img/menu-admins.webp';
  import MenuButton from '@assets/img/menu-button.webp';
  import MenuInventoryBar from '@assets/img/menu-inventory-bar.webp';
  import MenuSelectedFrame from '@assets/img/menu-selected-frame.webp';
  import { navigate } from 'astro:transitions/client';
  import { onMount } from 'svelte';

  // html bindings
  let navElem: HTMLDivElement;

  // states
  let navPaths = $state([
    {
      name: 'Startseite',
      sprite: MenuHome.src,
      href: '',
      active: false
    },
    {
      name: 'Registrieren',
      sprite: MenuSignup.src,
      href: 'signup',
      active: false
    },
    {
      name: 'Regeln',
      sprite: MenuRules.src,
      href: 'rules',
      active: false
    },
    {
      name: 'FAQ',
      sprite: MenuFaq.src,
      href: 'faq',
      active: false
    },
    {
      name: 'Features',
      sprite: MenuFeature.src,
      href: 'features',
      active: false
    },
    {
      name: 'Admins',
      sprite: MenuAdmins.src,
      href: 'admins',
      active: false
    }
  ]);

  let showMenuPermanent = $state(import.meta.env.SSR ? false : localStorage.getItem('showMenuPermanent') === 'true');
  let isTouch = $state(false);
  let isOpen = $state(false);
  let windowHeight = $state(0);

  // lifecycle
  $effect(() => {
    localStorage.setItem('showMenuPermanent', `${showMenuPermanent}`);
  });

  onMount(() => {
    updateActiveNavPath();
    // the mutation observer callback runs too fast, hence the call to `updateActiveNavPath` must be wrapped in an empty
    // setTimeout to not cause any visual bugs
    new MutationObserver(() => setTimeout(updateActiveNavPath)).observe(document.head, { childList: true });
  });

  // functions
  function updateActiveNavPath() {
    for (let i = 0; i < navPaths.length; i++) {
      navPaths[i].active = new URL(document.baseURI).pathname + navPaths[i].href === window.location.pathname;
    }
  }
</script>

<svelte:window bind:innerHeight={windowHeight} />
<svelte:body
  ontouchend={(e) => {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    if (isTouch && !navElem.contains(e.target)) showMenuPermanent = false;
  }}
/>

<div
  class="fixed bottom-4 right-4 sm:left-4 sm:right-[initial] group/menu-bar flex flex-col-reverse justify-center items-center z-50 main-menu"
  bind:this={navElem}
>
  <button
    class={isTouch ? 'btn btn-square relative w-16 h-16' : 'btn btn-square group/menu-button relative w-16 h-16'}
    onclick={() => {
      if (!isTouch) {
        let activePath = navPaths.find((path) => path.active);
        if (activePath !== undefined) {
          navigate(activePath.href);
        }
        showMenuPermanent = !showMenuPermanent;
      }
    }}
    ontouchend={() => {
      isTouch = true;
      showMenuPermanent = !showMenuPermanent;
    }}
  >
    <img class="absolute w-full h-full p-1 pixelated" src={MenuButton.src} alt="menu" />
    <img
      class="opacity-0 transition-opacity delay-50 group-hover/menu-button:opacity-100 absolute w-full h-full p-[3px] pixelated"
      class:opacity-100={isOpen || (isTouch && showMenuPermanent)}
      src={MenuSelectedFrame.src}
      alt="menu hover"
    />
  </button>
  <div
    class:hidden={!(isOpen || showMenuPermanent)}
    class={isTouch ? 'pb-3' : 'group-hover/menu-bar:block pb-3'}
    onmouseenter={() => (isOpen = true)}
    onmouseleave={() => (isOpen = false)}
    role="tooltip"
  >
    <ul class="bg-base-200 rounded">
      {#each navPaths as navPath, i (navPath.href)}
        <li
          class="flex justify-center tooltip"
          class:tooltip-left={windowHeight > 450}
          class:sm:tooltip-right={windowHeight > 450}
          class:tooltip-top={windowHeight <= 450}
          class:tooltip-open={isTouch || windowHeight <= 450}
          data-tip={navPath.name}
        >
          <a
            class="btn btn-square border-none group/menu-item relative w-[3.5rem] h-[3.5rem] flex justify-center items-center"
            href={navPath.href}
            onclick={() => navigate(navPath.href)}
          >
            <div
              style="background-image: url({MenuInventoryBar.src}); background-position: -{i * 3.5}rem 0;"
              class="block w-full h-full bg-no-repeat bg-horizontal-sprite pixelated"
            ></div>
            <div class="absolute flex justify-center items-center w-full h-full">
              <img class="w-1/2 h-1/2 pixelated" src={navPath.sprite} alt={navPath.name} />
            </div>
            <img
              class="transition-opacity delay-50 group-hover/menu-item:opacity-100 absolute w-full h-full pixelated scale-110 z-10"
              class:opacity-0={!navPath.active}
              src={MenuSelectedFrame.src}
              alt="menu hover"
            />
          </a>
        </li>
      {/each}
    </ul>
  </div>
</div>

<style>
  @media (max-height: 450px) {
    .main-menu {
      flex-direction: row;
    }
    .main-menu > div {
      padding: 0.25rem 0 0 0.5rem;
    }
    .main-menu li {
      display: inline-block;

      &::before {
        transform-origin: 0;
        transform: rotate(-90deg);
        margin-bottom: -0.5rem;
      }
    }
  }

  .pixelated {
    image-rendering: pixelated;
  }

  .bg-horizontal-sprite {
    background-size: auto 100%;
  }
</style>
