<template>

   <!-- TEST appelle la fonction sans passer par le callback de vis-network
   <button class="btn btn-sm btn-create" @click="addRelationshipModal({ from: 'person_1617', to: 'person_1614' })">add link</button>
   <=== InternalError: too much recursion
   -->

   <div id="visgraph"></div>

   <teleport to="#visgraph-legend">
      <div class="my-4 post-menu legend">
         <h3>{{ $t('visgraph.Legend') }}</h3>
         <div class="list-group">
            <label class="list-group-item" v-for="layer in legendLayers">
               <input
                  class="form-check-input me-1"
                  type="checkbox"
                  :value="layer.id"
                  v-model="checkedLayers"
                  @change="toggleLayer"
                  />
                  {{ layer.label }}
            </label>
         </div>
      </div>
      <button class="btn btn-sm btn-outline-secondary" @click="refreshNetwork">{{ $t('action.refresh') }}</button>
   </teleport>

   <teleport to="body">
      <modal v-if="modal.showModal" :modalDialogClass="modal.modalDialogClass" @close="modal.showModal = false">
         <template v-slot:header>
            <h2 class="modal-title">{{ $t(modal.title) }}</h2>
            <!-- {{ modal.data.id }} -->
         </template>
         <template v-slot:body>
            <div v-if="modal.action === 'delete'">
               <p>{{ $t('visgraph.delete_confirmation_text') }}</p>
            </div>
            <div v-else>
               <form>
                  <div class="row">
                     <div class="col-12 text-center">{{ $t('visgraph.between') }}<br>{{ $t('visgraph.and') }}</div>
                     <div class="col">
                        <h4>
                           {{ getPerson(modal.data.from).text }}
                        </h4>
                        <p class="text-start" v-if="relation && relation.title">
                           <span v-if="reverse">
                              {{ $t('visgraph.relation_from_to_like', [ getPerson(modal.data.from).text, getPerson(modal.data.to).text, relation.reverseTitle.fr.toLowerCase() ])}}
                           </span>
                           <span v-else>
                              {{ $t('visgraph.relation_from_to_like', [ getPerson(modal.data.from).text, getPerson(modal.data.to).text, relation.title.fr.toLowerCase() ])}}
                           </span>
                        </p>
                     </div>
                     <div class="col text-end">
                        <h4>
                           {{ getPerson(modal.data.to).text }}
                        </h4>
                        <p class="text-end" v-if="relation && relation.title">
                           <span v-if="reverse">
                              {{ $t('visgraph.relation_from_to_like', [ getPerson(modal.data.to).text, getPerson(modal.data.from).text, relation.title.fr.toLowerCase() ])}}
                           </span>
                           <span v-else>
                              {{ $t('visgraph.relation_from_to_like', [ getPerson(modal.data.to).text, getPerson(modal.data.from).text, relation.reverseTitle.fr.toLowerCase() ])}}
                           </span>
                        </p>
                     </div>
                  </div>
                  <div class="my-3"><!--
                        :value="relation"
                     -->
                     <VueMultiselect
                        id="relation"
                        label="title"
                        track-by="id"
                        :custom-label="customLabel"
                        :placeholder="$t('Choisissez le lien de parenté')"
                        :close-on-select="true"
                        :multiple="false"
                        :searchable="true"
                        :options="relations"
                        v-model="relation"
                        >
                     </VueMultiselect>
                  </div>
                  <div class="form-check form-switch">
                     <input
                        class="form-check-input"
                        type="checkbox"
                        id="reverse"
                        v-model="reverse"
                        >
                     <label class="form-check-label" for="reverse">{{ $t('visgraph.reverse_relation') }}</label>
                  </div>
               </form>
            </div>
         </template>
         <template v-slot:footer>
            <button class="btn" :class="modal.button.class" @click="submitRelationship">
               {{ $t(modal.button.text)}}</button>
         </template>
      </modal>
   </teleport>

</template>

<script>
import vis from 'vis-network/dist/vis-network'
import { mapState, mapGetters } from "vuex"
import Modal from 'ChillMainAssets/vuejs/_components/Modal'
import VueMultiselect from 'vue-multiselect'
import { getRelationsList, postRelationship } from "./api";
import { splitId } from "./vis-network";

export default {
   name: "App",
   components: {
      Modal,
      VueMultiselect
   },
   data() {
      return {
         container: '',
         checkedLayers: [],
         relations: [],
         relation: null,
         reverse: false,
         modal: {
            showModal: false,
            modalDialogClass: "modal-md",
            title: null,
            action: null,
            data: {},
            button: {
               class: null,
               text: null
            },
         },
      }
   },
   computed: {
      ...mapGetters(['nodes', 'edges',
         // not used
         'isInWhitelist', 'isHouseholdLoading', 'isCourseLoaded', 'isRelationshipLoaded', 'isPersonLoaded', 'isExcludedNode', 'countLinksByNode', 'getParticipationsByCourse', 'getMembersByHousehold', 'getWithFoldedPersons',
      ]),
      ...mapState(['households', 'courses', 'excludedNodesIds', 'persons',
         // not used
         'links', 'relationships', 'whitelistIds', 'personLoadedIds', 'householdLoadingIds', 'courseLoadedIds', 'relationshipLoadedIds',
      ]),

      visgraph_data() {
         console.log('::: visgraph_data :::', this.nodes.length, 'nodes,', this.edges.length, 'edges')
         return {
            nodes: this.nodes,
            edges: this.edges
         }
      },

      refreshNetwork() {
         //console.log('--- refresh network')
         window.network.setData(this.visgraph_data)
      },

      legendLayers() {
         //console.log('--- refresh legend')
         return [
            ...this.households,
            ...this.courses
         ]
      },

      rebuildCheckedLayers() {
         //console.log('--- rebuild checked Layers')
         this.checkedLayers = []
         let layersDisplayed = [
            ...this.nodes.filter(n => n.id.startsWith('household')),
            ...this.nodes.filter(n => n.id.startsWith('accompanying'))
         ]
         layersDisplayed.forEach(layer => {
            this.checkedLayers.push(layer.id)
         })
      },

      checkedLayers() { // required to refresh data checkedLayers
         return this.checkedLayers
      },

      relation: {
         get() {
            return this.relation
         },
         set(value) {
            //console.log('setter relation', value) // <=== InternalError: too much recursion
            this.relation = value
         }
      },

      reverse: {
         get() {
            return this.reverse
         },
         set(value) {
            //console.log('setter reverse', value) // <=== InternalError: too much recursion
            this.reverse = value
         }
      },


   },
   created() {
      eventHub.on('add-relationship-modal', this.addRelationshipModal)
      eventHub.on('edit-relationship-modal', this.editRelationshipModal)
      eventHub.on('delete-relationship-modal', this.deleteRelationshipModal)
   },
   unmounted() {
      eventHub.off('add-relationship-modal', this.addRelationshipModal)
      eventHub.off('edit-relationship-modal', this.editRelationshipModal)
      eventHub.off('delete-relationship-modal', this.deleteRelationshipModal)
   },
   mounted() {
      //console.log('=== mounted: init graph')
      this.initGraph()
      this.listenOnGraph()
      this.getRelationsList()
      this.forceUpdateComponent()
   },
   methods: {
      initGraph() {
         this.container = document.getElementById('visgraph')
         // Instanciate vis objects in separate window variables, see vis-network.js
         window.network = new vis.Network(this.container, this.visgraph_data, window.options)
      },
      listenOnGraph() {
         window.network.on('selectNode', (data) => {

            if (data.nodes.length > 1) {
               throw 'Multi selection is not allowed. Disable it in options.interaction !'
            }
            let node = data.nodes[0]

            let nodeType = splitId(node, 'type')
            switch (nodeType) {
               case 'person':
                  let person = this.nodes.filter(n => n.id === node)[0]
                  console.log('@@@@@@ event on selected Node', person.id)
                  if (person.folded === true) {
                     this.$store.commit('unfoldPerson', person)
                     this.forceUpdateComponent()
                  }
                  break

               case 'household':
                  let household = this.nodes.filter(n => n.id === node)[0]
                  console.log('@@@@@@ event on selected Node', household.id)
                  this.$store.dispatch('unfoldPersonsByHousehold', household)
                  this.forceUpdateComponent()
                  break

               case 'accompanying_period':
                  let course = this.nodes.filter(n => n.id === node)[0]
                  console.log('@@@@@@ event on selected Node', course.id)
                  this.$store.dispatch('unfoldPersonsByCourse', course)
                  this.forceUpdateComponent()
                  break

               default:
                  throw 'event is undefined for this type of node'
            }
         })
      },
      forceUpdateComponent() {
         //console.log('!! forceUpdateComponent !!')
         this.$forceUpdate()
         this.refreshNetwork
      },
      toggleLayer(value) {
         let id = value.target.value
         console.log('@@@@@ toggle Layer', id)
         this.forceUpdateComponent()
         if (this.checkedLayers.includes(id)) {
            this.removeLayer(id)
         } else {
            this.addLayer(id)
         }
      },
      addLayer(id) {
         //console.log('+ addLayer', id)
         this.checkedLayers.push(id)
         this.$store.dispatch('excludedNode', ['remove', id])
      },
      removeLayer(id) {
         //console.log('- removeLayer', id)
         this.checkedLayers = this.checkedLayers.filter(i => i !== id)
         this.$store.dispatch('excludedNode', ['add', id])
      },

      addRelationshipModal(edgeData) {
         this.modal.data = edgeData
         console.log('==- addRelationshipModal', edgeData) // { from: "person_1617", to: "person_1614" }
         this.modal.action = 'create'
         this.modal.title = 'visgraph.add_relationship_link'
         this.modal.button.class = 'btn-create'
         this.modal.button.text = 'action.create'
         this.modal.showModal = true
      },
      editRelationshipModal(edgeData) {
         this.modal.data = edgeData
         console.log('==- editRelationshipModal', edgeData)
         this.modal.action = 'edit'
         this.modal.title = 'visgraph.edit_relationship_link'
         this.modal.button.class = 'btn-edit'
         this.modal.button.text = 'action.edit'
         this.modal.showModal = true
      },
      deleteRelationshipModal(edgeData) {
         this.modal.data = edgeData
         console.log('==- deleteRelationshipModal', edgeData)
         this.modal.action = 'delete'
         this.modal.title = 'visgraph.delete_relationship_link'
         this.modal.button.class = 'btn-delete'
         this.modal.button.text = 'action.delete'
         this.modal.showModal = true
      },
      resetForm() {
         console.log('==- reset Form')
         this.modal.data = {}
         this.modal.action = null
         this.modal.title = null
         this.modal.button.class = null
         this.modal.button.text = null
      },

      getRelationsList() {
         //console.log('fetch relationsList')
         return getRelationsList().then(relations => new Promise(resolve => {
            //console.log('+ relations list', relations.results.length)
            this.relations = relations.results.filter(r => r.isActive === true)
            resolve()
         })).catch()
      },
      customLabel(value) {
         //console.log('customLabel', value)
         return (value.title && value.reverseTitle) ? `${value.title.fr} ↔ ${value.reverseTitle.fr}` : ''
      },
      getPerson(idtext) {
         let person = this.persons.filter(p => p.id === idtext)
         return person[0]
      },

      submitRelationship() {
         console.log('submitRelationship with action', this.modal.action)
         switch (this.modal.action) {

            case 'create':
               return postRelationship(
                  this.getPerson(this.modal.data.from), this.getPerson(this.modal.data.to), this.relation, this.reverse
               )
               .then(relationship => new Promise(resolve => {
                  console.log('post response', relationship)
                  this.$store.dispatch('addLinkFromRelationship', relationship)
                  this.modal.showModal = false
                  this.resetForm()
                  resolve()
               }))
               .catch()

            case 'edit':
               /// TODO
               // récupérer la relationship,
               // la modifier,
               // patcher en reconstruisant le body,
               // récupérer la réponse,
               // mettre le link (edge) à jour
               return patchRelationship(relationship)
               .then(response => new Promise(resolve => {
                  console.log('patch response', response)
                  this.$store.dispatch('updateLinkFromRelationship', response)
                  this.modal.showModal = false
                  this.resetForm()
                  resolve()
               }))
               .catch()

            case 'delete':
               break
            default:
               throw "undefined action"
         }
      }
   }
}
</script>

<style src="vis-network/dist/dist/vis-network.min.css"></style>
<style src="vue-multiselect/dist/vue-multiselect.css"></style>

<style lang="scss" scoped>
div#visgraph {
   height: 700px;
   margin: auto;
}
div#visgraph-legend {
   div.post-menu.legend {
   }
}
.modal-mask {
   background-color: rgba(0, 0, 0, 0.25);
}
</style>
