import { PickerEditorController } from '@ibiz-template/controller';
import { ref, Ref, watch, computed, defineComponent, PropType } from 'vue';
import { useNamespace } from '@ibiz-template/vue-util';
import { debounce } from 'lodash-es';
import { isEmpty } from 'ramda';
import '@/styles/components/editor/ibiz-picker-dropdown/ibiz-picker-dropdown.scss';

export const IBizPickerDropdown = defineComponent({
  name: 'IBizPickerDropdown',
  props: {
    value: {
      type: String,
    },
    controller: {
      type: PickerEditorController,
    },
    data: {
      type: Object as PropType<IData>,
      required: true,
    },
    disable: {
      type: Boolean,
    },
  },
  emits: {
    change: (_value?: string | Array<string> | IData | null, _tag?: string) =>
      true,
  },
  setup(props, { emit }) {
    const ns = useNamespace('picker-dropdown');

    const c = props.controller as PickerEditorController;

    // 允许搜索
    const allowSearch = ref(true);

    // 当前值
    const curValue: Ref<Array<string> | string | null> = ref('');

    // 实体数据集
    const items: Ref<IData[]> = ref([]);

    // 是否显示所有数据
    const isShowAll = ref(true);

    watch(
      () => props.value,
      newVal => {
        if (newVal || newVal === null) {
          curValue.value = newVal;
          const value = props.data[c.valueItem];
          const index = items.value.findIndex((item: IData) =>
            Object.is(item[c.keyName], value),
          );
          if (index !== -1) {
            return;
          }
          // items里匹配不到当前值项值时，生成自身的选项
          items.value = [];
          if (!isEmpty(newVal) && !isEmpty(value)) {
            items.value.push({ [c.textName]: newVal, [c.keyName]: value });
          }
        }
      },
      { immediate: true },
    );

    // 获取关联数据项值
    const refValue = computed(() => {
      if (c.valueItem && props.data) {
        const key = props.data[c.valueItem];
        if (key) {
          return key;
        }

        return '';
      }
      return curValue;
    });

    // 下拉是否打开
    const open = ref(false);

    // 加载中
    const loading: Ref<boolean> = ref(false);

    // 往外抛值
    const onACSelect = (item: IData) => {
      if (c.valueItem) {
        emit('change', item[c.keyName], c.valueItem);
      }
      emit('change', item[c.textName]);
      isShowAll.value = true;
    };

    // 值变更
    const onSelect = (select: string | Array<string>) => {
      const index = items.value.findIndex(item =>
        Object.is(item[c.keyName], select),
      );
      if (index >= 0) {
        onACSelect(items.value[index]);
      }
    };

    // 搜索
    const onSearch = async (query: string) => {
      if (c.model.appDataEntity) {
        // console.log('drop-down-query', query);
        loading.value = true;
        try {
          const res = await c.getServiceData(query, props.data!);
          loading.value = false;
          if (res) {
            items.value = res.data as IData[];
          }
        } catch (error) {
          loading.value = false;
        }
      }
    };

    // 搜索词改变时触发
    const queryChange = debounce((query: string) => {
      if (
        (query !== curValue.value || curValue.value === null) &&
        allowSearch.value
      ) {
        isShowAll.value = false;
        onSearch(query);
      }
    }, 1000);

    // 下拉打开
    const onSelectOpen = (flag: boolean) => {
      open.value = flag;
      if (open.value) {
        allowSearch.value = true;
        items.value = [];
        const query = isShowAll.value ? '' : curValue.value;
        onSearch(query as string);
      }
    };

    // 清除
    const onClear = () => {
      if (c.valueItem) {
        emit('change', null, c.valueItem);
      }
      emit('change', null);
    };
    return {
      ns,
      c,
      refValue,
      loading,
      items,
      isShowAll,
      allowSearch,
      onSearch,
      queryChange,
      onSelectOpen,
      onClear,
      onSelect,
    };
  },
  render() {
    return (
      <div class={this.ns.b()}>
        <i-select
          value={this.refValue}
          filterable
          allow-clear
          clearable
          loading={this.loading}
          placeholder={this.c.placeHolder}
          on-on-query-change={this.queryChange}
          on-on-open-change={this.onSelectOpen}
          on-on-change={this.onSelect}
          on-on-clear={this.onClear}
          disabled={this.disable}
        >
          {this.items.map((item, index) => {
            return (
              <i-option value={item[this.c.keyName]} key={index}>
                {item[this.c.textName]}
              </i-option>
            );
          })}
        </i-select>
      </div>
    );
  },
});
export default IBizPickerDropdown;
