<template>
  <div class="project-labels-window">
    <h1 class="headline"
        :class="{target: target}"
        @dragover="dragover" @dragleave="dragleave" @drop="drop">
      Labels
    </h1>

    <label-tree-view v-for="label in labelTree" :key="label.identifier"
                     :label="label"
                     :targetable="true"
                     indent="2rem"/>

    <div class="label">
      <input-group>
        <text-input placeholder="New Label"
                    v-model="createLabelValue"
                    @enter="createLabel"/>
        <button-input type="primary" @click="createLabel">
          create
        </button-input>
      </input-group>
    </div>
  </div>
</template>

<script>
import TextInput from "@/components/base/text-input";
import ButtonInput from "@/components/base/button-input";
import InputGroup from "@/components/base/input-group";
import LabelTreeView from "@/components/other/LabelTreeView";

export default {
  name: "project-labels-window",
  components: {LabelTreeView, InputGroup, ButtonInput, TextInput},
  created: function () {
    // get labels
    this.getLabels();

    // subscribe to changes
    this.$root.socket.on('connect', this.getLabels);
    this.$root.socket.on('create-label', this.addLabelToList);
    this.$root.socket.on('remove-label', this.removeLabelFromList);
    this.$root.socket.on('edit-label', this.editLabelInList);
  },
  destroyed: function () {
    this.$root.socket.off('connect', this.getLabels);
    this.$root.socket.off('create-label', this.addLabelToList);
    this.$root.socket.off('remove-label', this.removeLabelFromList);
    this.$root.socket.off('edit-label', this.editLabelInList);
  },
  data: function () {
    return {
      labels: [],
      createLabelValue: '',
      target: false
    }
  },
  computed: {
    // TODO remove
    sortedLabels: function () {
      return [...this.labels].sort((a, b) => a.name < b.name ? -1 : +1);
    },
    labelTree: function () {
      const labels = [...this.labels].sort((a, b) => a.name < b.name ? +1 : -1);

      const tree = [];
      const references = {};

      while (labels.length > 0) {
        const length = labels.length;

        for (let i = labels.length - 1; i >= 0; i--) {
          if (labels[i]['parent_id'] === null) {
            const label = Object.assign({
              // parent: null,
              children: []
            }, labels.splice(i, 1)[0]);

            tree.push(label);
            references[label.identifier] = label;
          } else if (labels[i]['parent_id'] in references) {
            const parent = references[labels[i]['parent_id']];
            const label = Object.assign({
              // parent: parent,
              children: []
            }, labels.splice(i, 1)[0]);

            parent.children.push(label);
            references[label.identifier] = label;
          }
        }

        if (labels.length === length) {
          // TODO show in ui
          console.log('I could not parse all items. Sorry!')
          return tree;
        }
      }

      return tree;
    }
  },
  methods: {
    getLabels: function () {
      this.$root.socket.get(`/projects/${this.$root.project.identifier}/labels`)
          .then(response => response.json())
          .then(labels => {
            this.labels = [];
            labels.forEach(this.addLabelToList);
          });
    },
    addLabelToList: function (label) {
      if (label['project_id'] !== this.$root.project.identifier)
        return;

      for (let l of this.labels)
        if (l.identifier === label.identifier)
          return;

      this.labels.push(label);
    },
    removeLabelFromList: function (label) {
      for (let i = 0; i < this.labels.length; i++) {
        if (this.labels[i].identifier === label.identifier) {
          this.labels.splice(i, 1);
          return;
        }
      }
    },
    editLabelInList: function (label) {
      for (let i = 0; i < this.labels.length; i++) {
        if (this.labels[i].identifier === label.identifier) {
          this.$set(this.labels, i, label);
          return;
        }
      }
    },
    createLabel: function () {
      if (!this.createLabelValue)
        return;

      // TODO then / error
      this.$root.socket.post(`/projects/${this.$root.project.identifier}/labels`, {name: this.createLabelValue});
      this.createLabelValue = '';
    },
    dragover: function (e) {
      e.preventDefault();
      this.target = true;
    },
    dragleave: function () {
      this.target = false;
    },
    drop: function (e) {
      this.dragleave();

      const element = e.dataTransfer.getData('text/identifier');
      this.$root.socket.post(`/projects/${this.$root.project.identifier}/labels/${element}/parent`, {parent: null});
    }
  }
}
</script>

<style scoped>
.project-labels-window {
  padding: 1rem;
  overflow: auto;
}

h1.target {
  text-decoration: underline;
}

/*
/deep/ .element {
  border: none;
}

/deep/ .element:not(:first-child) {
  margin-left: 0.1rem;
}

/deep/ .element:not(:last-child) {
  margin-right: 0.1rem;
}

.no-elements {
  margin-top: 0.5rem;
}
*/
</style>
