<template>
  <div class="cms-app h-100 d-flex flex-column" v-if="authorizedUser">
    <div class="d-flex">
      <nav class="top-navigation navbar navbar-expand-lg navbar-light bg-white">
        <button class="btn nav-link ml-n3" @click="toggleSidebar">
          <menu-icon />
        </button>
        <dropdown-menu
          v-if="navigation.brand.items.length"
          :label="navigation.brand.label"
          class="navbar-brand border rounded p-0"
        >
          <a
            v-for="(brandItem, index) in navigation.brand.items"
            :key="index"
            class="dropdown-item"
            :href="brandItem.href"
          >{{ brandItem.label }}
          </a>
        </dropdown-menu>
        <a
          v-else-if="navigation.brand && navigation.brand.label"
          href="/"
          class="navbar-brand"
        >{{ navigation.brand.label }}
        </a>
      </nav>
      <top-header :shadow="isOverflowingTop" />
    </div>
    <div class="d-flex h-100 flex-grow-1">
      <div class="d-flex w-100 container-wrapper">
        <navigation-sidebar ref="navigationSidebar" v-if="navigation" :navigation="navigation" />

        <div class="component-container container-fluid p-0 flex-grow-1" ref="component" @scroll="onComponentScroll">
          <alerter ref="alerter"></alerter>
          <div class="component-router-view h-100 d-flex flex-column container-xl py-3">
            <loader :is-loading="!languageStoreInitialized">
              <router-view class="h-100"></router-view>
            </loader>
          </div>
        </div>
      </div>
    </div>
    <portal-target name="modal" />
    <portal-target name="dialog" />
  </div>
  <div class="unauthorized" v-else-if="!authorizedUser">
    <p>Je bent niet gemachtigd als gebruiker. Vraag een administrator om je toe te voegen.</p>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Ref, Watch } from 'vue-property-decorator';
import { namespace } from 'vuex-class';
import _throttle from 'lodash/throttle';

import Alerter from './shared/alerter.vue';
import NavigationSidebar from './shared/navigation-sidebar.vue';
import TopHeader from './shared/top-header.vue';
import Loader from './shared/loader.vue';

import { Navigation } from './types/settings';
import { getCmsSettings } from './tools/settings';
const DataStore = namespace('data');
const LanguageStore = namespace('languages');

@Component({
  components: {
    Alerter,
    NavigationSidebar,
    TopHeader,
    Loader
  }
})
export default class RootComponent extends Vue {
  @Ref() readonly component!: HTMLDivElement;
  @Ref() readonly navigationSidebar!: NavigationSidebar;

  @LanguageStore.State('initialized') readonly languageStoreInitialized!: boolean;
  @DataStore.State('authorized') readonly authorizedUser!: null | boolean;

  navigation: Navigation = getCmsSettings().navigation;
  isOverflowingTop = false;
  isOverflowingBottom = false;

  addNavigationBrandItemsFromDataset () {
    const items = document.documentElement.dataset.navigationBrandItems || null;

    if (!items || !this.navigation.brand?.items) {
      return
    }

    try {
      this.navigation.brand.items = this.navigation.brand.items.concat(
        JSON.parse(items),
      )
    } catch (e) {
      console.error(e);
    }
  }

  toggleSidebar() {
    this.navigationSidebar.toggleSidebar();
  }

  onComponentScroll = _throttle(this.updateOverflowShadow, 50);
  updateOverflowShadow() {
    const el = this.component;
    this.isOverflowingTop = el.scrollTop > 0;
    this.isOverflowingBottom = el.scrollHeight > el.clientHeight + el.scrollTop;
  }

  @Watch('authorizedUser')
  onAuthorizedUserChange() {
    if (this.authorizedUser) {
      this.addNavigationBrandItemsFromDataset();
      this.$nextTick(this.updateOverflowShadow);
    }
  }
}
</script>

<style lang="scss" scoped>
@import 'variables';

.top-navigation {
  padding: .5rem 1rem;
  width: $sidebar-width;
  flex: 0 0 $sidebar-width;
  border-right: 1px solid $border-color;
  z-index: $z-index-header;

  .navbar-nav {
    flex-direction: row;
    flex-wrap: wrap;

    .nav-link {
      padding-right: 0.5rem;
      padding-left: 0.5rem;
    }
  }

  .navbar-brand {
    background: none;
    margin-right: 0;
    font-size: 18px;
    position: relative;
  }
}

.nav-link.active {
  font-weight: bold;
}

.container-wrapper {
  max-height: calc(100vh - 70px);
}

.component-container {
  min-width: 0;
  overflow-y: scroll;

  @media print {
    max-height: unset;
    overflow-y: visible;
  }
}

.unauthorized {
  display: flex;
  height: 100%;
  align-items: center;
  justify-content: center;

  p {
    background-color: white;
    padding: 1rem;
    box-shadow: 4px 2px 10px -3px rgba(0, 0, 0, .3);
  }
}
</style>
