<template lang="pug">
  div
    .pa-3.d-flex(:class='$vuetify.theme.dark ? `grey darken-5` : `blue darken-3`')
      v-btn.ml-2(
        depressed
        :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`'
        style='min-width:0;'
        @click='goHome'
        :aria-label='$t(`common:header.home`)'
        )
        v-icon(size='20') mdi-home
      v-btn.ml-3(
        depressed
        :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`'
        style='min-width:0;'
        @click='goStudentProfile'
        :aria-label='$t(`common:header.home`)'
      )
        v-icon(size='20') mdi-account-box
      v-btn.ml-2(
        depressed
        :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`'
        style='flex: 1 1 100%;'
        @click='goPlan'
        :aria-label='$t(`common:header.home`)'
      )
        v-icon(size='20') mdi-book-education
    v-divider

    //-> Tree Navigation
    v-treeview(
      activatable
      dense
      open-on-click
      :color='"white"'
      :active='treeDefaultActive'
      :open='treeDefaultOpen'
      :items='treeItems'
      :load-children='fetchTreeChild'
      @update:active='activeTreeItem'
    )
      template(v-slot:prepend="{ item, open }")
        v-icon(v-if="open") mdi-folder-open
        v-icon(v-else) mdi-{{ item.icon }}
      template(v-slot:label="{ item }")
        div(class='tree-item')
          a(v-if="!item.children" :href="'/'+item.locale+'/'+item.path")
            span {{item.name}}
          span(v-else) {{item.name}}
</template>

<script>
import _ from 'lodash'
import gql from 'graphql-tag'
import { get } from 'vuex-pathify'

/* global siteLangs */

export default {
  props: {
    color: {
      type: String,
      default: 'primary'
    },
    dark: {
      type: Boolean,
      default: true
    },
    items: {
      type: Array,
      default: () => []
    },
    navMode: {
      type: String,
      default: 'MIXED'
    }
  },
  data() {
    return {
      currentItems: [],
      currentParent: {
        id: 0,
        title: '/ (root)'
      },
      parents: [],
      loadedCache: [],
      treeItems: [],
      treeDefaultOpen: [],
      treeDefaultActive: []
    }
  },
  computed: {
    path: get('page/path'),
    locale: get('page/locale')
  },
  methods: {
    async fetchBrowseItems (item) {
      this.$store.commit(`loadingStart`, 'browse-load')
      if (!item) {
        item = this.currentParent
      }

      if (this.loadedCache.indexOf(item.id) < 0) {
        this.currentItems = []
      }

      if (item.id === 0) {
        this.parents = []
      } else {
        const flushRightIndex = _.findIndex(this.parents, ['id', item.id])
        if (flushRightIndex >= 0) {
          this.parents = _.take(this.parents, flushRightIndex)
        }
        if (this.parents.length < 1) {
          this.parents.push(this.currentParent)
        }
        this.parents.push(item)
      }

      this.currentParent = item

      const resp = await this.$apollo.query({
        query: gql`
          query ($parent: Int, $locale: String!) {
            pages {
              tree(parent: $parent, mode: ALL, locale: $locale) {
                id
                path
                title
                isFolder
                pageId
                parent
                locale
              }
            }
          }
        `,
        fetchPolicy: 'cache-first',
        variables: {
          parent: item.id,
          locale: this.locale
        }
      })
      this.loadedCache = _.union(this.loadedCache, [item.id])
      this.currentItems = _.get(resp, 'data.pages.tree', [])
      this.$store.commit(`loadingStop`, 'browse-load')
    },
    async loadFromCurrentPath() {
      this.$store.commit(`loadingStart`, 'browse-load')
      const resp = await this.$apollo.query({
        query: gql`
          query ($path: String, $locale: String!) {
            pages {
              tree(path: $path, mode: ALL, locale: $locale, includeAncestors: true) {
                id
                path
                title
                isFolder
                pageId
                parent
                locale
              }
            }
          }
        `,
        fetchPolicy: 'cache-first',
        variables: {
          path: this.path,
          locale: this.locale
        }
      })
      const items = _.get(resp, 'data.pages.tree', [])
      const curPage = _.find(items, ['pageId', this.$store.get('page/id')])
      if (!curPage) {
        console.warn('Could not find current page in page tree listing!')
        return
      }

      let curParentId = curPage.parent
      let invertedAncestors = []
      while (curParentId) {
        const curParent = _.find(items, ['id', curParentId])
        if (!curParent) {
          break
        }
        invertedAncestors.push(curParent)
        curParentId = curParent.parent
      }

      this.parents = [this.currentParent, ...invertedAncestors.reverse()]
      this.currentParent = _.last(this.parents)

      this.loadedCache = [curPage.parent]
      this.currentItems = _.filter(items, ['parent', curPage.parent])
      this.$store.commit(`loadingStop`, 'browse-load')
      if (curPage.isFolder) {
        await this.fetchBrowseItems(curPage)
      }
    },
    goHome (event) {
      const url = siteLangs.length > 0 ? `/${this.locale}/home` : '/'

      if (event.ctrlKey || event.metaKey) {
        // Если зажат Ctrl или Cmd (на Mac), открываем в новом окне
        window.open(url, '_blank')
      } else {
        // Иначе открываем в текущем окне
        window.location.assign(url)
      }
    },
    goStudentProfile (event) {
      const url = '/Users/profile'

      if (event.ctrlKey || event.metaKey) {
        window.open(url, '_blank')
      } else {
        window.location.assign(url)
      }
    },
    goPlan (event) {
      const url = '/plan'

      if (event.ctrlKey || event.metaKey) {
        window.open(url, '_blank')
      } else {
        window.location.assign(url)
      }
    },
    pageItem2TreeItem(item, level) {
      if (item.isFolder) {
        return { id: item.id, icon: item.icon, level: level, pageId: item.pageId, path: item.path, locale: item.locale, name: item.title, children: [] }
      } else {
        return { id: item.id, icon: item.icon, level: level, path: item.path, locale: item.locale, name: item.title }
      }
    },
    activeTreeItem([id]) {
      const find = (items) => {
        for (const item of items) {
          if (item.id === id) {
            return item
          }
          if (item.children && item.children.length) {
            const v = find(item.children)
            if (v) {
              return v
            }
          }
        }
      }
      const item = find(this.treeItems)
      if (item) {
        if (!this.treeDefaultActive.includes(item.id)) {
          location.href = `/${item.locale}/${item.path}`
        } else {
          setTimeout(() => {
            const el = document.querySelector('.v-treeview-node--active')
            el.scrollIntoViewIfNeeded()
          })
        }
      }
    },
    async fetchTreeChild(parent) {
      const items = await this.fetchPages(parent.id)
      parent.children = []
      if (parent.pageId) {
        parent.children.push({
          id: parent.pageId,
          level: parent.level + 1,
          icon: parent.icon,
          path: parent.path,
          locale: parent.locale,
          name: parent.name
        })
      }
      parent.children.push(
        ...items.map(item => this.pageItem2TreeItem(item, parent.level + 1))
      )
      this.checkTreeDefaultOpen(parent.children)
    },
    async fetchTreeRoot() {
      const children = await this.fetchPages(0)
      this.treeItems = children.map(item => this.pageItem2TreeItem(item, 0))
      this.checkTreeDefaultOpen(this.treeItems, 0)
    },
    checkTreeDefaultOpen(items) {
      const autoOpenBlacklist = 'Users'

      const item = items.find(item => {
        if (item.path.startsWith(autoOpenBlacklist)) {
          return false
        }

        return item.children && this.path.startsWith(item.path)
      })
      if (item) {
        setTimeout(() => {
          this.treeDefaultOpen.push(item.id)
        })
      }
      const active = items.find(item => item.path === this.path)
      if (active) {
        this.treeDefaultActive.push(active.id)
      }
    },
    async fetchPages(id) {
      const resp = await this.$apollo.query({
        query: gql`
          query($parent: Int, $locale: String!) {
            pages {
              tree(parent: $parent, mode: ALL, locale: $locale) {
                id
                path
                title
                icon
                isFolder
                pageId
                parent
                locale
              }
            }
          }
        `,
        fetchPolicy: 'cache-first',
        variables: {
          parent: id,
          locale: this.locale
        }
      })

      return _.get(resp, 'data.pages.tree', [])
    }
  },
  mounted () {
    this.currentParent.title = `/ ${this.$t('common:sidebar.root')}`

    this.fetchTreeRoot()
  }
}
</script>

<style lang="scss">
.v-treeview{
  .tree-item {
    font-weight: 500;
    line-height: 1rem;
    font-size: 0.9rem;
  }
  a {
    text-decoration: none;
  }
  &.theme--dark{
    a {
      color: white;
    }
  }
}

.v-treeview-node {
  min-height: 32px;

  .v-treeview-node__root {
    min-height: 32px;
    padding: 1px 0;
  }

  .v-treeview-node__content {
    margin: 1px 0;
  }

  .v-treeview-node__children {
    margin-left: 16px;
  }
}
</style>
