<template>
  <v-layout column>
    <v-flex>
      <v-subheader>{{ label }}</v-subheader>
    </v-flex>
    <v-flex>
      <v-list dense>
        <v-list-item
          v-for="item in doc"
          :key="item.key"
        >
          <v-list-item-content>
            <v-list-item-title v-text="item.label" />
          </v-list-item-content>

          <v-list-item-action style="margin:0">
            <v-layout>
              <v-flex>
                <v-btn small icon @click="viewItem(item)">
                  <v-icon>mdi-eye</v-icon>
                </v-btn>
              </v-flex>
              <v-flex>
                <v-btn small icon @click="deleteItem(item)">
                  <v-icon>mdi-delete</v-icon>
                </v-btn>
              </v-flex>
            </v-layout>
          </v-list-item-action>
        </v-list-item>
      </v-list>
    </v-flex>
    <v-flex class="text-center">
      <v-btn v-if="mode !== 'adding' && canAdd" @click="add()">
        <v-icon>mdi-plus-circle-outline</v-icon>
      </v-btn>

      <v-autocomplete
        v-if="mode === 'adding'"
        v-model="selectedItem"
        :items="items"
        :search-input.sync="search"
        :loading="isLoading"
        cache-items
        item-text="name"
        item-value="_id"
        hide-no-data
        hide-details
        label="Find"
        @change="addItem"
      />
    </v-flex>
  </v-layout>
</template>

<script>
export default {
  model: { prop: 'value', event: 'change' },
  props: {
    value: { type: Array, default: () => [] },
    label: { type: String, default: 'SelectApi' },
    collection: { type: String, default: '', required: true },
    multiple: { type: [Number, Boolean], default: false }
  },
  data: () => ({
    mode: '',
    items: [],
    isLoading: false,
    selectedItem: null,
    search: '',
    doc: [],
    byId: {},
    fromValueDone: false
  }),
  computed: {
    canAdd () {
      if (this.multiple) {
        if (typeof this.multiple === 'number') {
          return this.doc.length < this.multiple
        } else {
          return true
        }
      } else {
        return this.doc.length === 0
      }
    }
  },
  watch: {
    search (val) {
      val && val.length >= 3 && val !== this.select && this.querySelections(val)
    },
    value (val) {
      if (!val || this.fromValueDone) { return }
      this.doc = val.map(id => ({ id, label: null, key: null }))
      this.updateLabelFromId()
      this.fromValueDone = true
    }
  },
  methods: {
    add () {
      this.mode = 'adding'
    },
    viewItem (item) {
      window.open(`/admin/resources/${this.collection}/${item.id}`, '_blank')
    },
    deleteItem (item) {
      this
        .$confirm(`Supprimer <b>${item.label}</b> ?`)
        .then((res) => {
          if (res) {
            this.doc = this.doc.filter(val => val.id !== item.id)
            this.updateLabelFromId()
            this.$emit('change', this.doc.map(item => item.id))
          }
        })
    },
    addItem () {
      this.doc.push({ id: this.selectedItem, label: null, key: null })
      this.selectedItem = null
      this.mode = ''
      this.search = ''
      this.updateLabelFromId()
      this.$emit('change', this.doc.map(item => item.id))
    },
    querySelections (val) {
      this.isLoading = true
      this.$axios.get(`/cloud/api/${this.collection}?name__regex=${val},i&projection=name:1`)
        .then((res) => {
          this.items = res.data.data
        })
        .finally(() => (this.isLoading = false))
    },
    getTitle (item) {
      return this.byId[item] || item
    },
    updateLabelFromId () {
      const idsToGet = []
      this.doc.forEach((item) => {
        if (!this.byId[item.id]) {
          item.key = this.__generateKey(item.id)
          item.label = item.id
          this.byId[item.id] = item
        }
      })

      for (const key in this.byId) {
        if (this.byId[key].label === key) {
          idsToGet.push(key)
        }
      }

      if (!idsToGet.length) { return }

      this.$axios.get(`/cloud/api/${this.collection}?_id__in=${idsToGet.join(',')}&projection=name:1`)
        .then((res) => {
          res.data.data.forEach((doc) => {
            this.byId[doc._id].label = doc.name
          })
        })
    },
    __generateKey (id) {
      const ts = (new Date()).getTime()
      return `${id}${ts}`
    }

  }
}
</script>
