<template>
  <div
    :style="{ width, maxWidth }"
    class="snt-select">
    <v-select
      ref="select"
      :value="value"
      :items="items"
      :label="label"
      :placeholder="items.length > 0 ? placeholder : ''"
      :item-text="itemText"
      :item-value="itemValue"
      :prepend-inner-icon="prependInnerIcon"
      :return-object="returnObject"
      :clearable="clearable"
      :hide-details="hideDetails"
      :hide-selected="hideSelected"
      :menu-props="{
        'content-class': 'snt-menu',
        'origin': 'center center',
        'transition':'slide-y-transition',
        'nudge-top': '-4px',
        'maxHeight': 320,
        'offset-y': true,
      }"
      :color="color"
      :background-color="backgroundColor"
      :outlined="outlined"
      :dense="dense"
      :loading="loading"
      :height="height"
      :disabled="disabled"
      :chips="chips"
      :rules="rules"
      v-on="$listeners">
      <template #item="{ parent, item }">
        <div :style="{ maxWidth }">
          <div
            class="d-flex align-center"
            :class="`justify-${itemImagePosition}`">
            <img
              v-if="$_.has(item, 'image')"
              :class="{'mr-3': $_.has(item, 'image') && parent.getText(item)}"
              :width="itemImageWidth"
              :height="itemImageHeight"
              :src="getImage(item)" />
            <span class="text-overflow--3">{{ parent.getText(item) }}</span>
          </div>
        </div>
      </template>
      <template #selection="{ parent, item }">
        <v-chip
          v-if="chips"
          class="suggest-chip ma-1"
          color="primary"
          outlined
          label
          small
          close
          @click="select"
          @click:close="$emit('input', null)">
          {{ getValue(item) }}
        </v-chip>
        <div
          v-else
          :style="{maxWidth: '100%'}"
          class="d-flex align-center">
          <img
            v-if="$_.has(item, 'image')"
            :class="{'mr-3': $_.has(item, 'image') && parent.getText(item)}"
            :width="itemImageWidth"
            :height="itemImageHeight"
            :src="getImage(item)" />
          <span :class="`text-overflow--3 ${colorSelection}--text`">{{ parent.getText(item) }}</span>
        </div>
      </template>
      <template #append-item>
        <infinite-loading
          v-if="hasNextPage"
          force-use-infinite-wrapper=".v-select-list"
          @infinite="infiniteHandlerDebounce($event)">
          <div slot="no-more" />
          <div slot="no-results" />
        </infinite-loading>
      </template>
    </v-select>
  </div>
</template>

<script>
import { getPropertyFromItem } from 'vuetify/lib/util/helpers'

export default {
  props: {
    value: {
      type: [String, Array, Number, Boolean, Object],
      default: ''
    },
    items: {
      type: Array,
      default: () => ([])
    },
    rules: {
      type: Array,
      default: () => ([])
    },
    label: {
      type: String,
      default: undefined
    },
    placeholder: {
      type: String,
      default: undefined
    },
    itemText: {
      type: [String, Function],
      default: (v) => v
    },
    itemValue: {
      type: [String, Function],
      default: (v) => v
    },
    itemImage: {
      type: [String, Function],
      default: (v) => v
    },
    height: {
      type: [String, Number],
      default: '100%'
    },
    width: {
      type: [String, Number],
      default: '100%'
    },
    maxWidth: {
      type: [String, Number],
      default: '100%'
    },
    color: {
      type: String,
      default: 'primary'
    },
    backgroundColor: {
      type: String,
      default: '#ffffff'
    },
    prependInnerIcon: {
      type: String,
      default: undefined
    },
    outlined: {
      type: Boolean,
      default: true
    },
    dense: {
      type: Boolean,
      default: true
    },
    callback: {
      type: Function,
      default: () => {}
    },
    itemImagePosition: {
      type: String,
      default: 'start'
    },
    itemImageWidth: {
      type: String,
      default: '20'
    },
    itemImageHeight: {
      type: String,
      default: '20'
    },
    colorSelection: {
      type: String,
      default: 'secondary'
    },
    clearable: Boolean,
    hideSelected: Boolean,
    hideDetails: Boolean,
    returnObject: Boolean,
    loading: Boolean,
    hasNextPage: Boolean,
    disabled: Boolean,
    chips: Boolean
  },
  created () {
    this.infiniteHandlerDebounce = this.$_.debounce(this.infiniteHandler, 100)
  },
  mounted () {
    this.$refs.select.lastItem = 5000
  },
  methods: {
    getImage (item) {
      return getPropertyFromItem(item, this.itemImage, item)
    },
    getText (item) {
      return getPropertyFromItem(item, this.itemText, item)
    },
    getValue (item) {
      return getPropertyFromItem(item, this.itemValue, this.getText(item))
    },
    infiniteHandler ($state) {
      if (this.hasNextPage) {
        this.callback().then(() => {
          $state.loaded()
        })
      } else {
        $state.complete()
      }
    }
  }
}
</script>
<style>
  .snt-menu {
    padding: 8px 4px;
    background: white;
    overflow-y: hidden;
  }
</style>
<style lang="scss" scoped>
  .snt-select {
    ::v-deep {
      .v-input--is-focused {
        fieldset {
          border: 1px solid currentColor;
        }
      }
      .v-select__selections {
        flex-wrap: nowrap;
        line-height: inherit;
      }
      .v-input__control > .v-input__slot {
        min-height: 37px !important;
      }
      .v-input__icon--clear .v-icon {
        font-size: 1rem;
      }
    }
  }
  .snt-menu.v-menu__content {
    > .v-select-list {
      &.v-list {
        padding: 0 4px;
        ::v-deep {
          overflow-y: auto;
          max-height: 304px;
          .v-list-item {
            margin-bottom: 4px;
            border-radius: 4px;
            &::before {
              border-radius: 4px;
            }
            &:hover::before {
              opacity: 0.1;
            }
            &.v-list-item--link:hover {
              color: var(--v-primary-base) !important;
            }
            .v-list-item__title {
              font-size: 1rem !important;
              font-style: normal;
              font-weight: normal;
              line-height: 24px;
            }
          }
        }
      }
    }
  }
  .suggest-chip.v-chip.v-chip--outlined.v-chip.v-chip {
    cursor: pointer;
    background-color: var(--v-select-base) !important;
  }
</style>
