<template>
  <div
    v-click-outside="
      () => {
        showDropdown = false
      }
    "
    :class="{
      'custom-field-search--main': heritedOptions.display === 'main',
      'open-results': searchModel.length >= 3 && showDropdown
    }"
    class="custom-field-search field-search-request"
  >
    <div class="custom-field-search__input">
      <input
        ref="searchInput"
        v-model="searchModel"
        :placeholder="placeholder"
        type="text"
        @focus="hasDropdown ? (showDropdown = true) : ''"
        @keyup.enter="validateSearch"
      />

      <Icon
        :color="$_theme('colorGrey400')"
        icon="search"
        size="m"
        class="search-icon"
      />

      <transition v-if="searchModel.length >= 3 && showDropdown" name="fadeIn">
        <ul class="custom-field-search__dropdown">
          <transition name="fadeIn" mode="out-in">
            <div
              v-if="isLoading"
              :key="isLoading"
              class="custom-field-search__dropdown__loading df-center-y"
            >
              <loader-ui />

              <BaseText>{{ $_tr('inProgress') }}</BaseText>
            </div>

            <div v-else :key="isLoading">
              <template v-if="autocompletionResults.length > 0">
                <li
                  v-for="(result, index) in autocompletionResults"
                  :key="`result-${index}`"
                  @click="makeRedirection(result)"
                  v-html="result.title"
                />

                <li @click="onClick(searchModel)">
                  {{ $_tc('model', [searchModel]) }}
                </li>
              </template>

              <li v-else class="no-pointer">
                {{ $_tc('empty', [searchModel]) }}
              </li>
            </div>
          </transition>
        </ul>
      </transition>
    </div>
  </div>
</template>

<script>
import MakeRedirectionMixin from '../../../mixins/make-redirection'

import { BaseText, Icon } from 'inside-collection/atoms'

import vClickOutside from 'click-outside-vue3'

export default {
  name: 'FieldSearchRequest',
  $_i18nRootPath: 'customs.SEARCHES.fields',
  components: {
    BaseText,
    Icon
  },
  directives: {
    clickOutside: vClickOutside.directive
  },
  mixins: [MakeRedirectionMixin],
  props: {
    fieldsParameters: {
      type: Array,
      default: () => []
    },
    /*
     * Field with dropdown or not (difference between welcome and main search)
     */
    hasDropdown: {
      default: false,
      type: Boolean
    },
    /*
     * Query 'in' parameter
     */
    in: {
      default: () => [],
      type: Array
    },
    /*
     * Used in SearchFilter - specifies if the search field is a filter
     */
    isFilter: {
      default: false,
      type: Boolean
    },
    /*
     * Query limit
     */
    limit: {
      default: null,
      type: Number
    },
    placeholder: {
      default: '',
      type: String
    },
    /*
     * Show results directly in a dropdown (for welcome search)
     */
    resultsOnMain: {
      default: false,
      type: Boolean
    },
    /*
     * Key to identify the search request in the store info (getSearchQuery array)
     */
    searchKey: {
      default: '',
      type: String
    },
    onValidate: {
      type: Function
    }
  },
  data() {
    return {
      searchModel: this.$store.getters.getSearchQuery(this.searchKey),
      showDropdown: false,
      autocompletionResults: {},
      isLoading: false,
      currentSearchLength: this.$store.getters.getSearchQuery(this.searchKey)
        ? this.$store.getters.getSearchQuery(this.searchKey).length
        : 0
    }
  },
  watch: {
    showDropdown(value) {
      const className = 'field-search__input-no-border'

      this.searchModel.length >= 3 && value
        ? this.$refs.searchInput.classList.add(className)
        : this.$refs.searchInput.classList.remove(className)
    },
    searchModel() {
      this.setStoreAction('setSearchQuery', {
        key: this.searchKey,
        value: this.searchModel
      })

      if (!this.isFilter) {
        /*
         * If is classic search
         */
        if (this.searchModel.length >= 3) {
          if (this.hasDropdown) {
            this.showDropdown = true
          }

          this.requestAutocompletion()
        } else {
          this.showDropdown = false
          this.autocompletionResults = {}
          if (this.searchKey === 'ged') {
            this.setStoreAction('setLoadingGEDStatus', false)
          }

          if (this.currentSearchLength >= 3) {
            this.$emit('resetSearch')
          }
        }
      }
      if (this.searchModel.length >= 3) {
        this.$emit('filterQuery', this.searchModel)
        this.currentSearchLength = this.searchModel.length
      }
    }
  },
  mounted() {
    if (!this.getTablet) {
      if (this.searchKey === 'welcome-search') {
        this.searchModel = ''
      } else {
        this.$refs.searchInput.focus()
      }
    }
  },
  methods: {
    /*
     * Makes autocompletion if not mainSearch
     *
     * @param {boolean} forceMainSearch
     */
    requestAutocompletion(forceMainSearch = false) {
      if (this.searchKey === 'main-search') {
        this.$emit('requestValidated')
      } else {
        this.isLoading = true

        const params = {
          params: {
            terms: this.searchModel,
            content_types: '',
            sort: 'score:desc',
            page: 1,
            perPage: 5
          }
        }

        if (this.searchKey === 'ged') {
          this.setStoreAction('setLoadingGEDStatus', true)
        }

        /*
         * Make search request
         */
        this.get('special/search', params).then(
          response => {
            if (response.status === 200 && this.searchModel.length >= 3) {
              this.autocompletionResults = Object.values(response.data.data)

              this.isLoading = false

              /*
               * Save search results in store
               */
              if (this.searchKey === 'welcome-search' || forceMainSearch) {
                this.setStoreAction('setSearchResults', {
                  key: this.searchKey,
                  value: this.autocompletionResults
                })
              }

              /*
               * Emit to parent
               */
              if (!this.hasDropdown || forceMainSearch) {
                this.$emit('requestValidated', this.autocompletionResults)
              }
            }
          },
          err => {
            this.$_triggerErrorToast({
              text: err
            })
          }
        )
      }
    },
    /*
     * Triggers search request only on certain conditions
     */
    defaultValidateSearch() {
      if (
        this.searchModel.length >= 3 &&
        this.autocompletionResults.length > 0 &&
        this.hasDropdown &&
        this.resultsOnMain
      ) {
        this.showDropdown = false

        this.setStoreAction('setSearchQuery', {
          key: 'main-search',
          value: this.searchModel
        })

        this.setStoreAction('setSearchOpen', true)

        this.requestAutocompletion(true)

        setTimeout(() => {
          this.searchModel = ''
        }, 500)
      }
    },
    onClick(searchModel) {
      if (this.onValidate) {
        this.onValidate(searchModel)
      } else {
        this.defaultValidateSearch()
      }
    }
  }
}
</script>

<style lang="scss">
@use '../../../styles/modules/inside-customs/searches/fields.scss' as *;
</style>
