<template>
  <q-layout view="hHh Lpr lff">
    <q-header elevated class="bg-primary text-white">
      <q-toolbar>
        <q-btn dense flat round icon="mdi-menu" @click="openMenu" />

        <q-toolbar-title>
          <router-link :to="{ name: 'dashboard' }" style="text-decoration: none; color: inherit">
            <q-avatar rounded>
              <img src="flaschengeist-logo-white.svg" />
            </q-avatar>
            <span class="gt-xs"> Flaschengeist </span>
          </router-link>
        </q-toolbar-title>

        <!-- Hier kommen die Shortlinks hin -->
        <q-btn icon="mdi-message-bulleted" flat dense round>
          <q-badge color="negative" floating>
            {{ notifications.length }}
          </q-badge>
          <q-menu style="max-height: 400px; overflow: auto">
            <q-btn
              v-if="useNative && noPermission"
              label="Benachrichtigungen erlauben"
              @click="requestPermission"
            />
            <template v-if="notifications.length > 0">
              <Notification
                v-for="(notification, index) in notifications"
                :key="index"
                :model-value="notification"
                @remove="remove"
              />
            </template>
            <div v-else class="q-pa-sm">Keine neuen Benachrichtigungen</div>
          </q-menu>
        </q-btn>
        <drag v-model="shortCuts" item-key="link" ghost-class="ghost">
          <template #item="{ element }">
            <shortcut-link :shortcut="element" context @delete-shortcut="deleteShortcut" />
          </template>
        </drag>
        <q-btn flat round dense icon="mdi-exit-to-app" @click="logout()" />
      </q-toolbar>
    </q-header>

    <q-drawer
      v-model="leftDrawer"
      side="left"
      bordered
      :mini="leftDrawerMini"
      @click.capture="openMenu"
    >
      <!-- Plugins -->
      <essential-expansion-link
        v-for="(entry, index) in mainLinks"
        :key="'plugin' + index"
        :entry="entry"
        @add-short-cut="addShortcut"
      />
      <q-separator />
      <essential-link
        v-for="(entry, index) in essentials"
        :key="'essential' + index"
        :entry="entry"
      />
    </q-drawer>
    <q-page-container>
      <router-view />
    </q-page-container>
  </q-layout>
</template>

<script lang="ts">
import EssentialExpansionLink from 'components/navigation/EssentialExpansionLink.vue';
import EssentialLink from 'src/components/navigation/EssentialLink.vue';
import ShortcutLink from 'src/components/navigation/ShortcutLink.vue';
import Notification from 'src/components/Notification.vue';
import {
  defineComponent,
  ref,
  inject,
  computed,
  onBeforeMount,
  onBeforeUnmount,
  ComponentPublicInstance,
} from 'vue';
import { Screen } from 'quasar';
import config from 'src/config';
import { useRouter } from 'vue-router';
import { useMainStore } from '@flaschengeist/api';
import { FG_Plugin } from '@flaschengeist/types';
import drag from 'vuedraggable';

const essentials: FG_Plugin.MenuLink[] = [
  {
    title: 'Über Flaschengeist',
    link: 'about',
    icon: 'mdi-information',
  },
];

export default defineComponent({
  name: 'MainLayout',
  components: {
    EssentialExpansionLink,
    EssentialLink,
    ShortcutLink,
    Notification,
    drag: <ComponentPublicInstance>drag,
  },
  setup() {
    const router = useRouter();
    const mainStore = useMainStore();
    const flaschengeist = inject<FG_Plugin.Flaschengeist>('flaschengeist');
    const leftDrawer = ref(true);
    const leftDrawerMini = ref(false);
    const mainLinks = flaschengeist?.menuLinks || [];
    const notifications = computed(() => mainStore.notifications.slice().reverse());
    const polling = ref(NaN);
    const useNative = 'Notification' in window && window.Notification !== undefined;
    const noPermission = ref(!useNative || window.Notification.permission !== 'granted');

    onBeforeMount(() => {
      polling.value = window.setInterval(() => pollNotification(), config.pollingInterval);
      pollNotification();
      void mainStore.getShortcuts();
    });
    onBeforeUnmount(() => window.clearInterval(polling.value));

    function openMenu(event: { target: HTMLInputElement }) {
      if (event.target.nodeName === 'DIV') leftDrawerMini.value = false;
      else {
        if (!leftDrawer.value || leftDrawerMini.value) {
          leftDrawer.value = true;
          leftDrawerMini.value = false;
        } else {
          leftDrawerMini.value = Screen.gt.sm && !leftDrawerMini.value;
          leftDrawer.value = leftDrawerMini.value;
        }
      }
    }

    function logout() {
      void router.push({ name: 'login', params: { logout: 'logout' } });
      void mainStore.logout();
    }

    async function remove(id: number) {
      await mainStore.removeNotification(id);
    }

    function requestPermission() {
      void window.Notification.requestPermission().then(
        (p) => (noPermission.value = p !== 'granted')
      );
    }

    function pollNotification() {
      void mainStore
        .loadNotifications(<FG_Plugin.Flaschengeist>flaschengeist)
        .then((notifications) => {
          if (useNative && !noPermission.value)
            notifications.forEach(
              (notif) =>
                new window.Notification(notif.text, {
                  timestamp: notif.time.getTime(),
                })
            );
        });
    }

    const shortCuts = computed({
      get: () => mainStore.shortcuts,
      set: (val: Array<FG_Plugin.MenuLink>) => {
        mainStore.shortcuts = val;
        void mainStore.setShortcuts();
      },
    });

    function addShortcut(val: FG_Plugin.MenuLink) {
      const idx = shortCuts.value.findIndex((a: FG_Plugin.MenuLink) => a.link === val.link);
      if (idx < 0) {
        shortCuts.value.push(val);
        void mainStore.setShortcuts();
      }
    }

    function deleteShortcut(val: FG_Plugin.MenuLink) {
      const idx = shortCuts.value.findIndex((a: FG_Plugin.MenuLink) => a.link === val.link);
      if (idx > -1) {
        shortCuts.value.splice(idx, 1);
        void mainStore.setShortcuts();
      }
    }

    return {
      essentials,
      leftDrawer,
      leftDrawerMini,
      logout,
      mainLinks,
      notifications,
      noPermission,
      openMenu,
      remove,
      requestPermission,
      useNative,
      shortCuts,
      addShortcut,
      deleteShortcut,
    };
  },
});
</script>
<style scoped lang="sass">
.ghost
  opacity: 0.5
  background: $accent
</style>
