import { defineComponent, Transition, SetupContext, provide, Teleport, ref, computed } from 'vue';
import { cloneDeep } from 'lodash';
import { useNamespace } from '../../shared/hooks/use-namespace';
import DCascaderList from '../components/cascader-list';
import DMultipleBox from '../components/cascader-multiple/index';
import { cascaderProps, CascaderProps } from './cascader-types';
import { useCascader } from '../hooks/use-cascader';
import { FlexibleOverlay, Placement } from '../../overlay';
import { PopperTrigger } from '../../shared/components/popper-trigger';
import { POPPER_TRIGGER_TOKEN } from '../../shared/components/popper-trigger/src/popper-trigger-types';
import DInput from '../../input/src/input';
import { SelectArrowIcon, InputClearIcon } from '../../svg-icons';
import './cascader.scss';

export default defineComponent({
  name: 'DCascader',
  components: { DInput },
  props: cascaderProps,
  emits: ['update:modelValue', 'change', 'focus', 'blur'],
  setup(props: CascaderProps, ctx: SetupContext) {
    const ns = useNamespace('cascader');
    const {
      origin,
      overlayRef,
      menuShow,
      cascaderItemNeedProps,
      rootClasses,
      menuOpenClass,
      inputValue,
      rootStyle,
      showClearable,
      position,
      cascaderOptions,
      tagList,
      showClear,
      hideClear,
      clearData,
      handleInput,
      multiple,
      suggestionsList,
      isSearching,
      chooseSuggestion,
      onFocus,
      onBlur,
    } = useCascader(props, ctx);
    provide(POPPER_TRIGGER_TOKEN, origin);

    const currentPosition = ref('bottom');
    const styles = computed(() => ({
      transformOrigin: currentPosition.value === 'top' ? '0% 100%' : '0% 0%',
      'z-index': 'var(--devui-z-index-dropdown, 1052)',
    }));
    const handlePositionChange = (pos: string) => {
      currentPosition.value = pos.split('-')[0] === 'top' ? 'top' : 'bottom';
    };

    return () => (
      <div style={rootStyle.inputWidth}>
        <PopperTrigger>
          {ctx.slots.host ? (
            ctx.slots.host()
          ) : (
            <div class={rootClasses.value} {...ctx.attrs} onMouseenter={showClear} onMouseleave={hideClear}>
              {multiple.value ? (
                <DMultipleBox placeholder={props.placeholder} activeOptions={tagList.value}></DMultipleBox>
              ) : (
                <DInput
                  disabled={props.disabled}
                  placeholder={props.placeholder}
                  modelValue={inputValue.value}
                  size={props.size}
                  show-glow-style={props.showGlowStyle}
                  onInput={handleInput}
                  onFocus={onFocus}
                  onBlur={onBlur}
                />
              )}
              {!showClearable.value && (
                <div class={`${ns.e('icon')} ${ns.m('drop-icon-animation')}`}>
                  <SelectArrowIcon />
                </div>
              )}
              {showClearable.value && props.clearable && (
                <div class={`${ns.e('icon')} ${ns.e('close')}`} onClick={clearData}>
                  <div class="close-icon-container">
                    <InputClearIcon />
                  </div>
                </div>
              )}
            </div>
          )}
        </PopperTrigger>
        <Teleport to="body">
          <Transition name={ns.m(`fade-${currentPosition.value}`)}>
            <FlexibleOverlay
              origin={origin.value}
              ref={overlayRef}
              v-model={menuShow.value}
              position={position.value as Placement[]}
              style={styles.value}
              onPositionChange={handlePositionChange}>
              <div class={ns.e('drop-menu-animation')}>
                {!isSearching.value && (
                  <div class={`${menuOpenClass.value} ${ns.e('dropdown-menu')}`}>
                    {cascaderOptions.map((item, index) => {
                      return (
                        <DCascaderList
                          cascaderItems={item}
                          ul-index={index}
                          cascaderItemNeedProps={cascaderItemNeedProps}
                          cascaderOptions={cascaderOptions}
                          {...props}></DCascaderList>
                      );
                    })}
                  </div>
                )}
                {props.filterable && isSearching.value && (
                  <div class={ns.e('panel')}>
                    {suggestionsList.value.length === 0 ? (
                      <label style="font-weight: bold;">没有数据</label>
                    ) : (
                      suggestionsList.value.map((item) => {
                        return (
                          <div class={ns.e('suggest-list')} onClick={() => chooseSuggestion(cloneDeep(item))}>
                            {item.labelsString}
                          </div>
                        );
                      })
                    )}
                  </div>
                )}
              </div>
            </FlexibleOverlay>
          </Transition>
        </Teleport>
      </div>
    );
  },
});