import './tree-select.scss';

import { defineComponent, getCurrentInstance, toRefs, Transition } from 'vue';
import type { SetupContext } from 'vue';
import { treeSelectProps, TreeSelectProps, TreeItem } from './tree-select-types';
import { nodeMap, attributeExtension, className } from './utils';
import useToggle from '../hooks/use-toggle';
import useSelect from '../hooks/use-select';
import useClear from '../hooks/use-clear';
import IconOpen from '../assets/open';
import IconClose from '../assets/close';
import Checkbox from '../../checkbox/src/checkbox';
import ClickOutside from '../../shared/devui-directive/clickoutside';
import { createI18nTranslate } from '../../locale/create';

export default defineComponent({
  name: 'DTreeSelect',
  directives: { ClickOutside },
  props: treeSelectProps,
  emits: ['toggleChange', 'valueChange', 'update:modelValue'],
  setup(props: TreeSelectProps, ctx: SetupContext) {
    const app = getCurrentInstance();
    const t = createI18nTranslate('DTree', app);

    const { treeData, placeholder, disabled, multiple, leafOnly, enableLabelization } = toRefs(props);
    const { visible, selectToggle, treeToggle } = useToggle(props);
    const { inputValue, selectValue } = useSelect(props);
    const { isClearable, handleClearAll, handleClearItem } = useClear(props, ctx, inputValue);

    const clickNode = (item: TreeItem) => {
      if (!leafOnly.value) {
        selectValue(item);
        !multiple.value && selectToggle(item);
      } else {
        if (!item.children) {
          selectValue(item);
          !multiple.value && selectToggle(item);
        }
      }
    };

    const deleteNode = (e: MouseEvent, item: string) => {
      handleClearItem(e, item);
      selectValue(nodeMap.get(item));
    };

    const treeSelectCls = className('devui-tree-select', {
      'devui-tree-select-open': visible.value,
      'devui-tree-select-disabled': disabled.value,
    });

    const treeSelectInputItem = className('devui-tree-select-value', {
      'devui-tree-select-value-enableLabelization': enableLabelization.value,
    });

    const renderNode = (item) => (
      <div class="devui-tree-select-item" style={{ paddingLeft: `${20 * (item.level - 1)}px` }} onClick={() => clickNode(item)}>
        {item.children ? (
          item.opened ? (
            <IconOpen class="mr-xs" onClick={(e: MouseEvent) => treeToggle(e, item)} />
          ) : (
            <IconClose class="mr-xs" onClick={(e: MouseEvent) => treeToggle(e, item)} />
          )
        ) : (
          <span>{'\u00A0\u00A0\u00A0'}</span>
        )}
        {ctx.slots.default ? (
          ctx.slots.default({ item })
        ) : multiple.value ? (
          item.halfchecked ? (
            <Checkbox label={item.label} halfchecked={item.halfchecked} />
          ) : (
            <Checkbox label={item.label} checked={item.checked} />
          )
        ) : (
          item.label
        )}
      </div>
    );

    const renderTree = (treeData2) => {
      return treeData2.map((item) => {
        if (item.children) {
          return (
            <>
              {renderNode(item)}
              {item.opened && renderTree(item.children)}
            </>
          );
        }
        return renderNode(item);
      });
    };

    return () => {
      return (
        <div class={treeSelectCls} v-click-outside={() => (visible.value = false)}>
          <div class={isClearable.value ? 'devui-tree-select-clearable' : 'devui-tree-select-notclearable'} onClick={() => selectToggle()}>
            {/* <input
              value={inputValue.value}
              type="text"
              class="devui-tree-select-input"
              placeholder={placeholder}
              readonly
              disabled={disabled}
            /> */}
            <div class="devui-tree-select-input" placeholder={placeholder.value || t('selectPlaceholder')}>
              {multiple.value
                ? inputValue.value.map((item) => (
                  <div class={treeSelectInputItem}>
                    {item}
                    {enableLabelization.value ? <d-icon name="close" onClick={(e: MouseEvent) => deleteNode(e, item)} /> : <span>,</span>}
                  </div>
                ))
                : !Array.isArray(inputValue.value) && (
                  <div class={treeSelectInputItem}>
                    {inputValue.value}
                    {enableLabelization.value && <d-icon name="close" onClick={(e: MouseEvent) => handleClearItem(e)} />}
                  </div>
                )}
            </div>
            <span onClick={(e: MouseEvent) => handleClearAll(e)} class="devui-tree-select-clear">
              <d-icon name="close" />
            </span>
            <span class="devui-tree-select-arrow">
              <d-icon name="select-arrow" />
            </span>
          </div>
          <Transition name="fade" ref="dropdownRef">
            <div v-show={visible.value} class="devui-tree-select-dropdown">
              <ul class="devui-tree-select-dropdown-list">{renderTree(attributeExtension(treeData.value))}</ul>
            </div>
          </Transition>
        </div>
      );
    };
  },
});