import { createVNode as _createVNode } from "vue";
//@ts-nocheck
import { defineComponent, ref, computed, reactive, watch, onMounted } from "vue"; // import { keyBy } from 'lodash-es'

import { keyBy } from '../_util/_';
import SelectTrigger from './SelectTrigger';
import OptionList from './OptionList';
import Selector from './Selector';
import useSelectTriggerControl from './hooks/useSelectTriggerControl';
import Icon from '../icon';
import { getLabel } from './utils';
const prefixCls = 'x-select';
export default defineComponent({
  name: prefixCls,
  props: {
    value: [String, Array],
    options: Array,
    multiple: Boolean,
    disabled: Boolean,
    showArrow: {
      default: true
    },
    allowClear: Boolean,
    virtualScroll: Boolean,
    placeholder: {
      default: '请选择'
    },
    filterable: Boolean,
    filter: Function
  },
  slots: ['default', 'label'],
  emits: ['update:value', 'change', 'select', 'deselect', 'search', 'focus', 'blur'],

  setup(props, {
    emit,
    expose,
    slots
  }) {
    const containerRef = ref();
    const containerWidth = ref(0);
    const inputRef = ref();
    const popupRef = ref();
    const optionsRef = computed(() => {
      const searchVal = state.searchValue;

      if (props.filterable && searchVal) {
        var _props$options;

        const filter = props.filter || ((str, option) => getLabel(option).includes(str));

        return (_props$options = props.options) === null || _props$options === void 0 ? void 0 : _props$options.filter(opt => filter(searchVal, opt));
      }

      return props.options;
    });
    const optionsBy = computed(() => keyBy(props.options, 'value'));
    const state = reactive({
      selected: value2Selected(),
      searchValue: ''
    });
    watch(() => props.value, () => {
      state.selected = value2Selected();
    });
    const valuesSet = computed(() => new Set(state.selected));
    const labelValues = computed(() => state.selected.map(e => optionsBy.value[e]));

    function value2Selected() {
      const {
        value
      } = props;
      return Array.isArray(value) ? value : value != null ? [value] : [];
    }

    function setValue(arr) {
      const value = props.multiple ? [...arr] : arr[0];
      emit('update:value', value);
      emit('change', value);
    }

    function setSearchValue(text) {
      state.searchValue = text;
      emit('search', text);
    } // ============================= Open =============================


    const opened = ref(false);

    function onToggleOpen(boo) {
      if (props.disabled) return;

      if (boo === undefined) {
        opened.value = !opened.value;
      } else {
        opened.value = boo;
      }
    }

    useSelectTriggerControl([containerRef, popupRef], onToggleOpen); // ============================= Event =============================

    function onSelect(option) {
      const value = option.value;

      if (!props.multiple) {
        state.selected = [value];
        emit('select', option.value, option);
      } else {
        const index = state.selected.indexOf(option.value);

        if (~index) {
          state.selected.splice(index, 1);
          emit('deselect', value, option);
        } else {
          state.selected.push(value);
          emit('select', option.value, option);
        }
      }

      state.searchValue = ''; // 清空搜索

      let values = state.selected;
      values = props.multiple ? [...values] : values[0];
      emit('update:value', values);
      emit('change', value, option);

      if (!props.multiple) {
        onToggleOpen(false);
      }
    }

    function onClear() {
      setValue([]);
      setSearchValue('');
    }

    function onSearch(text) {
      setSearchValue(text);
    }

    function onMenuMousedown(e) {
      e.preventDefault();
    } // ========================== Focus / Blur ==========================


    const focusRef = ref(false);

    function onFocus(e) {
      focusRef.value = true;
      if (props.disabled) return; // onToggleOpen(true)

      setSearchValue('');
      emit('focus', e);
    }

    function onBlur(e) {
      focusRef.value = false;
      if (props.disabled) return;
      setSearchValue('');
      emit('blur', e);
    } // ========================== Expose ==========================


    function focus() {
      inputRef.value.focus();
    }

    function blur() {
      inputRef.value.blur();
    }

    expose({
      focus,
      blur
    }); //// ========================== containerWidth ==========================

    onMounted(() => {
      watch(opened, () => {
        if (!opened.value) return;
        containerWidth.value = containerRef.value.offsetWidth;
      }, {
        immediate: true
      });
    });
    return () => {
      const {
        allowClear,
        showArrow,
        disabled
      } = props;
      const values = state.selected;

      const popup = _createVNode(OptionList, {
        "prefixCls": prefixCls,
        "ref": popupRef,
        "values": valuesSet.value,
        "options": optionsRef.value,
        "virtualScroll": props.virtualScroll,
        "onSelect": onSelect,
        "onMousedown": onMenuMousedown
      }, {
        label: slots.label
      });

      const triggerProps = {
        prefixCls,
        containerWidth: containerWidth.value,
        popup,
        visible: opened.value,
        disabled: props.disabled,
        onVisibleChange: onToggleOpen
      };
      const cls = [prefixCls, {
        [`${prefixCls}-multiple`]: props.multiple,
        [`${prefixCls}-single`]: !props.multiple,
        [`${prefixCls}-filterable`]: props.filterable,
        [`${prefixCls}-focus`]: focusRef.value,
        [`${prefixCls}-disabled`]: disabled
      }];
      const clearNode = !disabled && allowClear && values.length ? _createVNode(Icon, {
        "class": `${prefixCls}-clear`,
        "onClick": onClear,
        "type": "cross"
      }, null) : undefined;
      const arrowNode = !disabled && !clearNode && showArrow ? _createVNode(Icon, {
        "class": `${prefixCls}-arrow`,
        "type": "arrow-down"
      }, null) : undefined;
      return _createVNode("div", {
        "ref": containerRef,
        "class": cls
      }, [_createVNode(SelectTrigger, triggerProps, {
        default: () => [_createVNode(Selector, {
          "prefixCls": prefixCls,
          "values": labelValues.value,
          "multiple": props.multiple,
          "searchValue": state.searchValue,
          "filterable": props.filterable,
          "showArrow": props.showArrow,
          "allowClear": props.allowClear,
          "disabled": props.disabled,
          "placeholder": props.placeholder,
          "inputRef": inputRef,
          "onSelect": onSelect,
          "onSearch": onSearch,
          "onToggleOpen": onToggleOpen,
          "onFocus": onFocus,
          "onBlur": onBlur
        }, null)]
      }), clearNode, arrowNode]);
    };
  }

});