<template>
  <MainContentLayout
    id="edition"
    :reftoscrollto="reftoscrollto"
    :navopened="navopened"
    :headeropened="headeropened"
    @onCenterScrolled="onCenterScrolled"
  >
    <!-- <transition name="fade" mode="out-in"> -->
    <template v-if="!corpusLoaded" #header>
      <span class="loading">Chargement ...</span>
    </template>

    <template v-else #header>
      <span
        class="header-title"
        @click.prevent="onOpenCloseHeader"
        @keyup.enter="onOpenCloseHeader"
      >
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="10" role="presentation" class="vs__open-indicator"><path d="M9.211364 7.59931l4.48338-4.867229c.407008-.441854.407008-1.158247 0-1.60046l-.73712-.80023c-.407008-.441854-1.066904-.441854-1.474243 0L7 5.198617 2.51662.33139c-.407008-.441853-1.066904-.441853-1.474243 0l-.737121.80023c-.407008.441854-.407008 1.158248 0 1.600461l4.48338 4.867228L7 10l2.211364-2.40069z" /></svg>
        Notice
      </span>
      <h1>
        <router-link :to="{ name:'edition', params: { id: editionid }}">{{ title }}</router-link>
      </h1>
      <aside class="notice opened">
        <div v-if="description">
          <p v-html="description" />
        </div>
        <div v-if="author">
          <p>{{ author }}</p>
        </div>
        <!-- <div v-if="date">
          <p>{{ date }}</p>
        </div> -->
        <div v-if="biblio" class="biblio">
          <p v-html="biblio.description" />
          <a
            :href="edition_manifestation_href"
            @click.prevent="onClickManifestation"
            @keyup.enter="onClickManifestation"
          >
            <!-- // todo better label
            {{ biblio.uuid }} -->
          </a>
        </div>
      </aside>

      <nav class="entities-hide-show">
        <span
          v-if="entities_displayed"
          @click.prevent="onCLickEntitiesDisplay"
          @keyup.enter="onCLickEntitiesDisplay"
        >
          <span class="mdi mdi-eye-outline" /> Afficher les marques d'entité
        </span>
        <span
          v-if="!entities_displayed"
          @click.prevent="onCLickEntitiesDisplay"
          @keyup.enter="onCLickEntitiesDisplay"
        >
        <span class="mdi mdi-eye-off-outline" /> Masquer les marques d'entité
        </span>
      </nav>

      <!-- displayed on hover entity on texte -->
      <aside
        v-if="indexitem"
        class="index-tooltip"
        :style="{ top:tooltip_top + 'px' }"
        :data-index="indexitem.index"
        :data-uuid="indexitem.uuid"
        @click.prevent="onClickTooltip"
        @keyup.enter="onClickTooltip"
      >
        <span v-if="indexitem == 'loading'" class="loading">Chargement ...</span>
        <template v-if="indexitem !== 'loading'">
          <h1 v-html="indexitem.title" />
          <p v-if="indexitem.birthDate" class="birthdeath">
            <time>{{ indexitem.birthDate }}</time>, <span class="place">{{ indexitem.birthPlace }}</span><br>
            <time>{{ indexitem.deathDate }}</time>, <span class="place">{{ indexitem.deathPlace }}</span>
          </p>
          <p v-if="indexitem.occupation" class="occupation">
            {{ indexitem.occupation }}
          </p>
          <p v-if="indexitem.type" class="type">
            {{ indexitem.type }}
          </p>
        </template>

      </aside>
    </template>
    <!-- </transition> -->
    <!-- default slot -->
    <div id="text" :class="{ 'entities-displayed': !entities_displayed, 'entities-hidden': entities_displayed }">
      <template v-if="texts.length">
        <infinite-loading
          v-if="flattoc && center_scrolled"
          :identifier="inifinite_load_id"
          direction="top"
          :distance="inifinite_load_distance"
          @infinite="prevText"
        />
        <!-- <transition-group name="edition-texts" tag="div"> -->
        <EdText
          v-for="text in texts"
          :ref="text.content.uuid"
          :key="text.content.uuid"
          :tei="text.content.tei"
          :uuid="text.content.uuid"
          :url="text.content.url"
          :textid="textid"
          :extractid="extractid"
          @onHoverLink="onHoverLink"
          @onLeaveLink="onLeaveLink"
        />
        <!-- </transition-group> -->
        <infinite-loading
          v-if="flattoc"
          :identifier="inifinite_load_id"
          @infinite="nextText"
        />
      </template>
    </div>

    <template #nav>
      <span
        class="nav-title"
        @click.prevent="onOpenCloseNav"
        @keyup.enter="onOpenCloseNav"
      >
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="10" role="presentation" class="vs__open-indicator"><path d="M9.211364 7.59931l4.48338-4.867229c.407008-.441854.407008-1.158247 0-1.60046l-.73712-.80023c-.407008-.441854-1.066904-.441854-1.474243 0L7 5.198617 2.51662.33139c-.407008-.441853-1.066904-.441853-1.474243 0l-.737121.80023c-.407008.441854-.407008 1.158248 0 1.600461l4.48338 4.867228L7 10l2.211364-2.40069z" /></svg>
        Sommaire
      </span>
      <EdToc
        id="toc"
        :toc="toc"
        :loadedtextsuuids="textsuuids"
        :selectedindex="selectedindex"
        @onClickTocItem="onClickTocItem"
      />
      <EdIndexes
        v-if="indexes"
        id="indexes-filters"
        :indexes="indexes"
        @onClickIndexItem="onClickIndexItem"
      />
      <EdPagination
        v-if="pagination"
        id="page-nav"
        :pagination="pagination"
        @onClickPaginationItem="onClickPaginationItem"
      />
    </template>
  </MainContentLayout>
</template>

<script>

import qs from 'querystring'

import { REST } from 'api/rest-axios'
import { mapState, mapActions } from 'vuex'

import MainContentLayout from '../components/Layouts/MainContentLayout'
import EdText from '../components/Content/EdText'
import EdToc from '../components/Content/EdToc'
import EdIndexes from '../components/Content/EdIndexes'
import EdPagination from '../components/Content/EdPagination'

export default {
  name: 'Edition',
  metaInfo () {
    // console.log('metainfo', this.meta)
    return {
      title: this.metainfotitle,
      meta: this.meta
    }
  },
  components: {
    MainContentLayout,
    EdText,
    EdToc,
    EdIndexes,
    EdPagination
  },
  data: () => ({
    meta: [],
    editionid: null,
    textid: null,
    extract: null,
    extractid: null,
    texts: [],
    textsuuids: [],
    metainfotitle: undefined,
    title: undefined,
    biblio: undefined,
    author: undefined,
    date: undefined,
    description: undefined,
    texttitle: undefined,
    //
    indexitem: null,
    tooltip_top: null,
    //
    next_loaded: false,
    center_scrolled: false,
    inifinite_load_distance: 10,
    inifinite_load_id: +new Date(),
    reftoscrollto: null,
    //
    toc: null,
    flattoc: null,
    //
    indexes: null,
    selectedindex: null,
    //
    pagination: null,
    //
    headeropened: false,
    navopened: false,
    //
    entities_displayed: false
  }),
  computed: {
    ...mapState({
      corpusLoaded: state => state.Corpus.corpusLoaded,
      editionslist: state => state.Corpus.editionslist,
      editionsbyuuid: state => state.Corpus.editionsbyuuid
    }),
    edition_manifestation_href () {
      return `${this.biblio.path}${this.biblio.uuid}`
    }
  },
  watch: {
    $route (to, from) {
      console.log('Edition Watcher $route', from, to)
      if (to.params.id !== this.editionid) {
        this.setValues()
      }
      if (to.params.textid) {
        // change textid when route change
        this.textid = to.params.textid
        // change also extract if exists
        this.extractid = null
        if (to.params.extract) {
          console.log('extract params from route', to.params.extract)
          this.extractid = to.params.ocid
          // scrolling is not working :(
          this.reftoscrollto = '#mark-1'
        }
      } else if (this.toc) {
        // if no textid in new route (e.g. edition front)
        // but we have toc
        // get the first item
        // will be replaced by front page of edition
        this.textid = this.toc[0].children[1].uuid
      } else {
        this.textid = null
      }
    },
    reftoscrollto (newref, oldref) {
      console.log('reftoscrollto changed', oldref, newref)
    },
    textid (newid, oldid) {
      // triggered when route change (when TOC item clicked)
      console.log('textid watcher', this, oldid, newid)
      this.texts = []
      this.textsuuids = []
      this.pages = []
      this.pagesOtpions = []
      if (newid) {
        this.getTextContent(newid)
        this.inifinite_load_id += 1
      }
    },
    // textdata (newtxtdata, oldtxtdata) {
    //   console.log('textdata watcher', oldtxtdata, newtxtdata)
    //   this.metainfotitle = `${this.title} ${newtxtdata.meta.title}`
    // },
    page_selected (newp, oldp) {
      console.log('page_selected watcher', oldp, newp)
      this.scrollToPage(newp)
    },
    flattoc (n, o) {
      console.log('flattoc watcher', o, n)
      // this.scrollToPage(newp)
    }
  },
  created () {
    this.setValues()
  },
  // updated () {
  //   this.setValues()
  // },
  methods: {
    ...mapActions({
      getCorpuses: 'Corpus/getCorpuses'
    }),
    setValues () {
      // console.log('Edition this.$route.params.id', this.$route.params.id)
      this.editionid = this.$route.params.id

      // get the text if textid available
      if (this.$route.params.textid) {
        this.textid = this.$route.params.textid
      }

      // get the searchkeys from route param (only comming from result item) for text highlighting
      if (this.$route.params.ocid) {
        this.extractid = this.$route.params.ocid
        // scrolling is not working :(
        this.reftoscrollto = '#mark-1'
      }

      // wait for editions list from Corpus Store if not already loaded
      if (!this.corpusLoaded) {
        // this.getCorpuses()
        // subsribe to store to get the editionbyuuid list
        // https://dev.to/viniciuskneves/watch-for-vuex-state-changes-2mgj
        this.edUuuidsUnsubscribe = this.$store.subscribe((mutation, state) => {
          // console.log('Edition store subscribe', mutation.type)
          if (mutation.type === 'Corpus/setEditionsByUUID') {
            // console.log('Edition state.Coprus.editionsbyuuid', this.editionid, state.Corpus.editionsbyuuid)
            this.title = this.metainfotitle = state.Corpus.editionsbyuuid[this.editionid].title

            this.meta = [
              { name: 'test', content: 'edition chargé' }
            ]

            this.biblio = state.Corpus.editionsbyuuid[this.editionid].biblio
            this.description = state.Corpus.editionsbyuuid[this.editionid].description
            this.date = state.Corpus.editionsbyuuid[this.editionid].date
            this.author = state.Corpus.editionsbyuuid[this.editionid].author
          }
          if (mutation.type === 'Corpus/setTocs') {
            console.log('Edition Corpus/setTocs', this.editionid, state.Corpus.editionsbyuuid)
            this.toc = state.Corpus.editionsbyuuid[this.editionid].toc
          }
          if (mutation.type === 'Corpus/buildFlatTocsAndFilters') {
            console.log('Edition Corpus/buildFlatTocsAndFilters', this.editionid, state.Corpus.editionsbyuuid)
            this.flattoc = state.Corpus.editionsbyuuid[this.editionid].flattoc
            // launch infinitloading
            this.inifinite_load_id += 1
            // if no textid in new route (e.g. edition front)
            // but we have toc
            // get the first item
            // will be replaced by front page of edition
            if (!this.textid) { this.textid = this.flattoc[1] }
            //
            this.indexes = state.Corpus.editionsbyuuid[this.editionid].indexes
          }
          if (mutation.type === 'Corpus/setPaginations') {
            // console.log('Edition state.Coprus.editionsbyuuid', this.editionid, state.Corpus.editionsbyuuid)
            this.pagination = state.Corpus.editionsbyuuid[this.editionid].pagination
          }
        })
      } else {
        // console.log('');
        this.title = this.metainfotitle = this.editionsbyuuid[this.editionid].title

        this.meta = [
          { name: 'test', content: 'edition deja là' }
        ]

        this.biblio = this.editionsbyuuid[this.editionid].biblio
        this.description = this.editionsbyuuid[this.editionid].description
        this.date = this.editionsbyuuid[this.editionid].date
        this.author = this.editionsbyuuid[this.editionid].author
        this.toc = this.editionsbyuuid[this.editionid].toc
        this.flattoc = this.editionsbyuuid[this.editionid].flattoc
        // if no textid in new route (e.g. edition front)
        // but we have toc
        // get the first item
        // will be replaced by front page of edition
        if (!this.textid) { this.textid = this.toc[0].children[0].uuid }
        this.indexes = this.editionsbyuuid[this.editionid].indexes
        this.pagination = this.editionsbyuuid[this.editionid].pagination
      }
    },
    getTextContent (textid, $state = null, direction = 'next') {
      console.log('getTextContent', textid)
      let params = {
        depth: 0
      }
      let q = qs.stringify(params)
      REST.get(`${window.apipath}/items/${textid}?${q}`, {})
        .then(({ data }) => {
          console.log('text REST: data', data)
          if (direction === 'next') {
            this.texts.push(data)
            this.textsuuids.push(data.content.uuid)
          } else {
            this.texts.unshift(data)
            this.textsuuids.unshift(data.content.uuid)
          }
          if ($state) {
            // triggered by infinite scroll
            $state.loaded()
            this.next_loaded = true
          } else {
            // triggered by TOC item click
            // UPDATE METATAGS
            this.updateMetaData(data.meta.metadata)
          }
        })
        .catch((error) => {
          console.warn('Issue with getTextContent', error)
          Promise.reject(error)
          // if some item don't load and if we come from infinite loading
          // retry with next step
          if ($state) {
            switch (direction) {
              case 'next':
                this.nextText($state, 2)
                break
              case 'prev':
                this.prevText($state, 2)
                break
            }
          }
          // this.$router.replace({
          //   name: 'notfound',
          //   query: { fullpath: this.$route.path }
          // })
        })
    },
    updateMetaData (metadata) {
      this.meta = []
      metadata.forEach(m => {
        let o = {}
        o.name = m.name
        if (Array.isArray(m.content)) {
          o.content = m.content.join(', ')
        } else {
          o.content = m.content
        }
        if (typeof m.scheme !== 'undefined') {
          o.scheme = m.scheme
        }
        this.meta.push(o)
      })
    },
    onCenterScrolled (e) {
      console.log('Edition centerScrolled(e)', e.target.scrollTop)
      if (!this.center_scrolled && e.target.scrollTop > this.inifinite_load_distance * 1.5) {
        this.center_scrolled = true
        // this.$store.commit('History/setOpened', false)
      }
      this.indexitem = null
    },
    nextText ($state, indent = 1) {
      console.log('infinite loading nextText()')
      let indexofnext = this.flattoc.indexOf(this.textsuuids[this.textsuuids.length - 1]) + indent
      if (indexofnext < this.flattoc.length) {
        this.getTextContent(this.flattoc[indexofnext], $state, 'next')
      } else {
        $state.complete()
      }
    },
    prevText ($state, indent = 1) {
      console.log('infinite loading prevText()')
      let indexofprev = this.flattoc.indexOf(this.textsuuids[0]) - indent
      if (indexofprev >= 0) {
        this.getTextContent(this.flattoc[indexofprev], $state, 'prev')
      } else {
        $state.complete()
      }
    },
    onHoverLink (elmt) {
      console.log('Edition onHoverLink(elmt)', elmt)
      this.tooltip_top = elmt.rect.top
      this.getIndexItem(elmt)
    },
    onLeaveLink () {
      console.log('Edition onLeaveLink()')
      this.indexitem = null
    },
    getIndexItem (item) {
      this.indexitem = 'loading'
      REST.get(`${window.apipath}/index${item.index.charAt(0).toUpperCase()}${item.index.slice(1)}/${item.uuid}`, {})
        .then(({ data }) => {
          console.log('index tooltip REST: data', data)
          if (this.indexitem === 'loading') {
            this.indexitem = data.content
            this.indexitem.index = item.index
          }
        })
        .catch((error) => {
          console.warn('Issue with index tooltip rest', error)
          Promise.reject(error)
          this.indexitem = null
        })
    },
    onClickTocItem (uuid) {
      console.log('Edition onClickTocItem', uuid, this.$refs)
      if (this.textsuuids.indexOf(uuid) !== -1) {
        // if already loaded, scroll to uuid
        this.reftoscrollto = `.tei[data-uuid="${uuid}"]`
      } else {
        // if not already loaded, change route
        this.$router.push({
          name: `editiontext`,
          params: {
            id: this.editionid,
            textid: uuid
          }
        })
      }
    },
    onClickIndexItem (o) {
      this.selectedindex = o
    },
    onClickPaginationItem (o) {
      console.log('onClickPaginationItem', o)
      if (this.textsuuids.indexOf(o.uuid) !== -1) {
        // if already loaded, scroll to uuid
        // this.scrollToPage(o)
        this.reftoscrollto = `span[role="pageBreak"][id="${o.code}"]`
      } else {
        // if not already loaded, change route
        this.$router.push({
          name: `editiontext`,
          params: {
            id: this.editionid,
            textid: o.uuid
          }
        })
      }
    },
    // scrollToPage (p) {
    //   console.log('scrollToPage', p)
    //
    // },
    onOpenCloseNav (e) {
      console.log('onOpenCloseNav', e)
      this.navopened = !this.navopened
      if (this.navopened) {
        this.headeropened = false
      }
    },
    onOpenCloseHeader (e) {
      console.log('onOpenCloseHeader', e)
      this.headeropened = !this.headeropened
      if (this.headeropened) {
        this.navopened = false
      }
    },
    onClickTooltip (e) {
      console.log(`onClickTooltip index: ${e.target.dataset.index}, uuid: ${e.target.dataset.uuid}`)
      this.$router.push({
        name: e.target.dataset.index,
        params: { id: e.target.dataset.uuid }
      })
    },
    onClickManifestation (e) {
      console.log(`onClickManifestation`)
      this.$router.push({
        name: 'bibliographieItem',
        params: { type: 'manifestations', uuid: this.biblio.uuid }
      })
    },
    onCLickEntitiesDisplay (e) {
      console.log('onCLickEntitiesDisplay')
      this.entities_displayed = !this.entities_displayed
    }
  }
}
</script>

<style lang="scss" scoped>

</style>
