<template>
  <div
    class="ws-state-relationship-select"
    :class="[{'round':round},{active:menuActive},{'is-error':errors&&errors.length},{'is-disabled':_disabled}]"
    v-click-outside="$_onClickOutside"
  >
    <a
      href="#"
      @click.prevent="$_onOpenClick()"
      class="ws-state-relationship-select__button"
    >
      <div
        v-if="value"
        class="ws-state-relationship-select__button-text"
      >{{_valueText}}</div>
      <div
        v-else
        class="ws-state-relationship-select__placeholder"
      >{{placeholder}}</div>
      <v-icon class="icon">mdi-menu-down</v-icon>
    </a>
    <div
      v-if="menuActive"
      class="ws-state-relationship-select__menu"
    >
      <div class="ws-state-relationship-select__search-input-section">
        <div class="ws-state-relationship-select__search-input">
          <v-icon class="icon">mdi-magnify</v-icon>
          <input
            ref="searchInput"
            type="text"
            v-model="searching"
          >
          <a
            @click.prevent="$_onInputClearClick()"
            class="search-input-clear-button"
          >
            <v-icon class="clear-icon">mdi-close-circle</v-icon>
          </a>
        </div>
      </div>
      <div
        v-if="loading"
        class="loading-section"
      >
        <v-progress-circular
          v-if="loading"
          size="20"
          color="primary"
          indeterminate
        ></v-progress-circular>
      </div>
      <div
        v-else-if="_items.length"
        class="ws-state-relationship-select__options"
      >
        <a
          v-for="(item,itemIndex) in _items"
          :key="itemIndex"
          href="#"
          @click.prevent="$_onOptionClick(item)"
          :class="{active:$_activeCheck(item)}"
        >
          <div
            v-show="multiple"
            class="checkbox"
          >
            <v-icon v-if="$_activeCheck(item)">mdi-checkbox-marked</v-icon>
            <v-icon v-else>mdi-checkbox-blank-outline</v-icon>
          </div>
          <p>{{item.text}}</p>
        </a>
      </div>
      <div
        v-else
        class="no-result-text"
      >
        <p v-if="searching">找不到 ”{{searching}}” 相關搜尋結果</p>
        <p v-else>無選項</p>
      </div>
    </div>
  </div>
</template>

<script>
import ClickOutside from "vue-click-outside";
export default {
  data: () => ({
    searching: "",
    menuActive: false,
    modelDatas: [],
    fetchedItems: [],
    loading: false,
    searchTimeout: null,
  }),
  methods: {
    $_activeCheck(item) {
      if (!this.value) {
        return;
      }
      if (this.multiple) {
        return this.value.includes(item.value);
      } else {
        return this.value == item.value;
      }
    },
    $_originValueToFetchedItems() {
      if (!this.originValue) {
        return;
      }
      if (this.multiple) {
        this.originValue.forEach((originValueItem) => {
          const text = this.getText
            ? this.getText(originValueItem)
            : originValueItem[this.textKey];
          this.fetchedItems.push({
            value: originValueItem[this.valueKey],
            text: text,
          });
        });
      } else {
        const text = this.getText
          ? this.getText(this.originValue)
          : this.originValue[this.textKey];
        this.fetchedItems.push({
          value: this.originValue[this.valueKey],
          text: text,
        });
      }
    },
    $_fetchPrepare() {
      this.loading = true;
      this.modelDatas = [];
      clearTimeout(this.searchTimeout);
      this.searchTimeout = setTimeout(() => {
        this.$_itemsFetch();
      }, 500);
    },
    $_onInputClearClick() {
      this.searching = "";
      setTimeout(() => {
        this.$refs.searchInput.focus();
      }, 0);
    },
    $_onOptionClick(item) {
      if (this.multiple) {
        const _value = this.value ? JSON.parse(JSON.stringify(this.value)) : [];
        const itemIndex = _value.findIndex((e) => {
          return e == item.value;
        });
        if (itemIndex >= 0) {
          _value.splice(itemIndex, 1);
        } else {
          _value.push(item.value);
        }
        this.$emit("input", _value);
      } else {
        this.$emit("input", item.value);
        this.menuActive = false;
      }
    },
    $_onClickOutside() {
      this.menuActive = false;
    },
    $_onOpenClick() {
      this.menuActive = !this.menuActive;
      if (this.menuActive) {
        this.$_itemsFetch();
        setTimeout(() => {
          this.$refs.searchInput.focus();
        }, 0);
      }
    },
    async $_itemsFetch() {
      this.loading = true;
      let getUrl =
        this.parentState && this.parent
          ? `/${this.parent}/${this.parentState}/${this.modelName}`
          : `/${this.modelName}`;
      const params = {
        search: this.searching,
      };
      if (this.conditions) {
        this.conditions.forEach((condition) => {
          if (
            condition.type &&
            condition.type == "array" &&
            condition.value &&
            Array.isArray(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.modelDatas = res.data.data;
        this.$_fetchedItemsSet();
        this.loading = false;
      } catch (error) {
        this.loading = false;
      }
    },
    $_fetchedItemsSet() {
      this._items.forEach((item) => {
        const tarIndex = this.fetchedItems.findIndex((e) => {
          return e.value == item.value && e.text == item.text;
        });
        if (tarIndex < 0) {
          this.fetchedItems.push(item);
        }
      });
    },
    valueReset() {
      this.$emit("input", null);
    },
  },
  computed: {
    _disabled() {
      if (this.parent && !this.parentState) {
        return true;
      } else if (
        this.requiredField &&
        (!this.requiredFieldState || this.requiredFieldState.length == 0)
      ) {
        return true;
      } else {
        return false;
      }
    },
    _valueText() {
      if (!this.value) {
        return null;
      } else {
        if (this.multiple) {
          let _valueText = "";
          this.value.forEach((valueItem) => {
            const tarItem = this.fetchedItems.find((e) => {
              return e.value == valueItem;
            });
            if (tarItem) {
              if (_valueText) {
                _valueText += `, ${tarItem.text}`;
              } else {
                _valueText += tarItem.text;
              }
            }
          });
          return _valueText;
        } else {
          const tarItem = this.fetchedItems.find((e) => {
            return e.value == this.value;
          });
          if (!tarItem) {
            return null;
          } else {
            return tarItem.text;
          }
        }
      }
    },
    _items() {
      const _items = [];
      this.modelDatas.forEach((modelData) => {
        let text;
        if (this.getText) {
          text = this.getText(modelData);
        } else {
          text = this.$_CMS_getValueByFieldKey(this.textKey, modelData);
        }
        _items.push({
          value: modelData[this.valueKey],
          text: text,
        });
      });
      return _items;
    },
  },
  props: {
    errors: {
      type: Array,
      default: null,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    rules: {
      type: String,
      default: null,
    },
    note: {
      type: String,
      default: null,
    },
    errorMessage: {
      type: String,
      default: null,
    },
    getText: {
      type: Function,
      default: null,
    },
    conditions: {
      type: Array,
      default: null,
    },
    requiredField: {
      default: null,
    },
    requiredFieldState: {
      default: null,
    },
    parentState: {
      default: null,
    },
    parent: {
      default: null,
    },
    modelName: {
      type: String,
      default: null,
    },
    round: {
      type: Boolean,
      default: true,
    },
    placeholder: {
      type: String,
      default: "select",
    },
    originValue: {},
    value: {},
    textKey: {
      type: String,
      default: "name",
    },
    valueKey: {
      type: String,
      default: "id",
    },
  },
  watch: {
    searching: {
      handler() {
        this.$_fetchPrepare();
      },
    },
    parentState: {
      handler() {
        this.valueReset();
      },
    },
  },
  directives: {
    ClickOutside,
  },
  mounted() {
    this.$_originValueToFetchedItems();
    // this.$_itemsFetch();
  },
};
</script>

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