<template>
  <ValidationProvider
    class="ws-state-autocomplete"
    :rules="rules"
    v-slot="{ errors }"
  >
    <div
      class="ws-state-input__container"
      :class="[{'is-error':errors&&errors.length},{'is-disabled':_disabled}]"
    >
      <v-autocomplete
        class="pt-0"
        :items="_items"
        :value="value"
        outlined
        dense
        @blur="_onBlur()"
        @change="$_onChange()"
        @focus="handleFocus()"
        @input="$emit('input', $event)"
        @keydown="$_onKeyDown($event)"
        :search-input.sync="searching"
        color="primary"
        :multiple="multiple"
        :hide-no-data="loading"
        :placeholder="placeholder"
        :label="label"
        clearable
        @click:clear="$_onClear()"
        single-line
        hide-details
        :disabled="_disabled"
      >
      </v-autocomplete>
      <input
        type="hidden"
        :value="value"
      >
      <div
        v-if="errors&&errors.length"
        class="ws-state__detail"
      >
        <v-icon size="20">mdi-information</v-icon>
        <p>{{errors[0]}}</p>
      </div>
      <div
        v-if="errorMessage"
        class="ws-state__detail"
      >
        <v-icon size="20">mdi-information</v-icon>
        <p>{{errorMessage}}</p>
      </div>
      <div
        v-if="note"
        class="ws-state__detail"
      >
        <v-icon size="20">mdi-information</v-icon>
        <p>{{note}}</p>
      </div>
    </div>
  </ValidationProvider>
</template>
<script>
export default {
  data: () => ({
    c_items: [],
    loading: false,
    searching: "",
    isMounted: false,
    timeout: {
      searchItemsFetch: null
    }
  }),
  methods: {
    $_onChange() {},
    _onBlur() {},
    $_onClear() {
      setTimeout(() => {
        this.searching = "";
        this.itemsFetch();
      }, 0);
    },
    $_onKeyDown() {
      if (!this.searching) {
        return;
      }
      if (!this.searchOnItemsFetch) {
        return;
      }
      this.loading = true;
      clearTimeout(this.timeout.searchItemsFetch);
      this.timeout.searchItemsFetch = setTimeout(() => {
        this.itemsFetch();
      }, 100);
    },
    $_onSearchInput($event) {
      this.searching = $event ? $event : "";
    },
    async itemsFetch() {
      this.loading = true;
      let getUrl =
        this.parentState && this.parent
          ? `/${this.parent}/${this.parentState}/${this.modelName}`
          : `/${this.modelName}`;
      const params = {
        search: this.searching,
        lang: this.locale
      };
      if (this.conditions) {
        this.conditions.forEach(condition => {
          if (condition.type && condition.type == "array" && condition.value) {
            params[condition.key] = condition.value.join();
          } else {
            params[condition.key] = condition.value;
          }
        });
      }
      try {
        const res = await this.$axios.get(getUrl, {
          params: params
        });
        this.c_items = res.data.data;
        this.isMounted = true;
        this.loading = false;
      } catch (error) {
        this.loading = false;
      }
    },
    handleFocus() {
      if (this.items) {
        return;
      }
      this.itemsFetch();
    },
    valueReset() {
      if (this.multiple) {
        this.$emit("input", []);
      }
    },
    valueSet() {
      if (!this.value && this.multiple) {
        this.$emit("input", []);
      }
    }
  },
  mounted() {
    if (this.items) {
      this.c_items = this.items;
      return;
    }
    if (!this.parent) {
      this.itemsFetch();
    } else if (this.parentState) {
      this.itemsFetch();
    }
  },
  computed: {
    _disabled() {
      if (this.parent && !this.parentState) {
        return true;
      } else if (
        this.requiredField &&
        (!this.requiredFieldState || this.requiredFieldState.length == 0)
      ) {
        return true;
      } else {
        return false;
      }
    },
    _items() {
      const _items = [];
      this.c_items.forEach(c_item => {
        let text;
        if (this.getText) {
          text = this.getText(c_item);
        } else {
          text = this.$_CMS_getValueByFieldKey(this.textKey, c_item);
        }
        _items.push({
          value: c_item.id,
          text: text
        });
      });
      return _items;
    }
  },
  watch: {
    parentState: {
      handler() {
        this.valueReset();
      }
    }
  },
  props: {
    note: {
      type: String,
      default: null
    },
    errorMessage: {
      type: String,
      default: null
    },
    conditions: {
      type: Array,
      default: null
    },
    searchOnItemsFetch: {
      type: Boolean,
      default: true
    },
    value: {
      type: [String, Array, Object, Number],
      default: null
    },
    modelName: {
      type: String,
      default: null
    },
    rules: {
      type: String,
      default: null
    },
    getText: {
      type: Function,
      default: null
    },
    textKey: {
      type: String,
      default: "name"
    },
    label: {
      type: String,
      default: null
    },
    multiple: {
      type: Boolean,
      default: null
    },
    inLocale: {
      type: Boolean,
      default: null
    },
    parentState: {
      default: null
    },
    parent: {
      default: null
    },
    requiredField: {
      default: null
    },
    requiredFieldState: {
      default: null
    },
    getSelectionText: {
      type: Function,
      default: null
    },
    items: {
      type: Array,
      default: null
    },
    placeholder: {
      type: String,
      default: null
    }
  }
};
</script>

<style lang="scss">
@import "../assets/scss/ws-state-autocomplete.scss";
</style>