<template>
  <div
    class="search"
    aria-label="search"
    role="search"
    :class="{
      'is-active': isActive,
      'is-open': isOpen
    }"
  >
    <div class="field">
      <div class="control">
        <a
          v-if="isActive"
          class="search-clear-btn"
          @click="clear"
        >
          &nbsp;
        </a>
        <ds-select
          :id="id"
          ref="input"
          v-model="searchValue"
          class="input"
          name="search"
          type="search"
          icon="search"
          label-prop="id"
          :no-options-available="emptyText"
          :icon-right="isActive ? 'close' : null"
          :filter="item => item"
          :options="results"
          :placeholder="$t('search.placeholder')"
          @keypress.enter.prevent.stop.self="onEnter"
          @focus.capture.native="onFocus"
          @blur.capture.native="onBlur"
          @keyup.delete.native="onDelete"
          @keyup.esc.native="clear"
          @input.exact="onSelect"
          @input.native="handleInput"
          @click.capture.native="isOpen = true"
        >
          <template
            slot="option"
            slot-scope="{option}"
          >
            <ds-flex>
              <ds-flex-item class="search-option-label">
                <ds-text>
                  {{ option.label | truncate(70) }}
                </ds-text>
              </ds-flex-item>
              <ds-flex-item
                class="search-option-meta"
                width="280px"
              >
                <ds-flex>
                  <ds-flex-item>
                    <ds-text
                      size="small"
                      color="softer"
                      class="search-meta"
                    >
                      <span style="text-align: right;">
                        <b>{{ option.commentsCount }}</b> <ds-icon name="comments" />
                      </span>
                      <span style="width: 36px; display: inline-block; text-align: right;">
                        <b>{{ option.shoutedCount }}</b> <ds-icon name="bullhorn" />
                      </span>
                    </ds-text>
                  </ds-flex-item>
                  <ds-flex-item>
                    <ds-text
                      size="small"
                      color="softer"
                      align="right"
                    >
                      {{ option.author.name | truncate(32) }} - {{ option.createdAt | dateTime('dd.MM.yyyy') }}
                    </ds-text>
                  </ds-flex-item>
                </ds-flex>
              </ds-flex-item>
            </ds-flex>
          </template>
        </ds-select>
      </div>
    </div>
  </div>
</template>

<script>
import { isEmpty } from 'lodash'

export default {
  name: 'HcSearchInput',
  props: {
    id: {
      type: String,
      default: 'nav-search'
    },
    value: {
      type: String,
      default: ''
    },
    results: {
      type: Array,
      default: () => []
    },
    delay: {
      type: Number,
      default: 300
    },
    pending: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      searchProcess: null,
      isOpen: false,
      lastSearchTerm: '',
      unprocessedSearchInput: '',
      searchValue: ''
    }
  },
  computed: {
    // #: Unused at the moment?
    isActive() {
      return !isEmpty(this.lastSearchTerm)
    },
    emptyText() {
      return this.isActive && !this.pending
        ? this.$t('search.failed')
        : this.$t('search.hint')
    }
  },
  methods: {
    async query(value) {
      if (isEmpty(value) || value.length < 3) {
        this.clear()
        return
      }
      this.$emit('search', value)
    },
    handleInput(e) {
      clearTimeout(this.searchProcess)
      const value = e.target ? e.target.value.trim() : ''
      this.isOpen = true
      this.unprocessedSearchInput = value
      this.searchProcess = setTimeout(() => {
        this.lastSearchTerm = value
        this.query(value)
      }, this.delay)
    },
    onSelect(item) {
      this.isOpen = false
      this.$emit('select', item)
      this.$nextTick(() => {
        this.searchValue = this.lastSearchTerm
      })
    },
    onFocus(e) {
      clearTimeout(this.searchProcess)
      this.isOpen = true
    },
    onBlur(e) {
      this.isOpen = false
      clearTimeout(this.searchProcess)
      this.searchValue = this.lastSearchTerm
    },
    onDelete(e) {
      clearTimeout(this.searchProcess)
      const value = e.target ? e.target.value.trim() : ''
      if (isEmpty(value)) {
        this.clear()
      }
    },
    /**
     * TODO: on enter we should go to a dedicated seach page!?
     */
    onEnter(e) {
      // console.log('res', this.unprocessedSearchInput)
      // this.isOpen = false
      clearTimeout(this.searchProcess)
      if (!this.pending) {
        // this.lastSearchTerm = this.unprocessedSearchInput
        this.query(this.unprocessedSearchInput)
      }
    },
    clear() {
      clearTimeout(this.searchProcess)
      this.isOpen = false
      this.searchValue = null
      this.lastSearchTerm = null
      this.$emit('clear')
    }
  }
}
</script>

<style lang="scss">
.search {
  display: flex;
  align-self: center;
  width: 100%;
  position: relative;

  $padding-left: $space-x-small;

  .search-option-label {
    align-self: center;
    padding-left: $padding-left;
  }

  .search-option-meta {
    align-self: center;

    .ds-flex {
      flex-direction: column;
    }
  }

  &,
  .ds-select-dropdown {
    transition: box-shadow 100ms;
    max-height: 70vh;
  }

  &.is-open {
    .ds-select-dropdown {
      box-shadow: $box-shadow-x-large;
    }
  }

  .ds-select-dropdown-message {
    opacity: 0.5;
    padding-left: $padding-left;
  }

  .search-clear-btn {
    right: 0;
    z-index: 10;
    position: absolute;
    height: 100%;
    width: 36px;
    cursor: pointer;
  }

  .search-meta {
    float: right;
    padding-top: 2px;
    white-space: nowrap;
    word-wrap: none;

    .ds-icon {
      vertical-align: sub;
    }
  }

  .ds-select {
    z-index: $z-index-dropdown + 1;
    transition: border-bottom 0;
    background-color: $background-color-soft;

    border-color: darken($background-color-soft, 10%);
  }

  .ds-select-is-open {
    .ds-select {
      border-bottom: 0;
    }
  }

  .ds-select-option-hover {
    .ds-text-size-small,
    .ds-text-size-small-x {
      color: rgba(#fff, 0.8);
    }
  }

  .field {
    width: 100%;
    display: flex;
    align-items: center;
  }

  .control {
    width: 100%;
  }
}
</style>
