import {
  defineComponent,
  PropType,
  computed,
  ref,
} from 'vue';
import cloneDeep from 'lodash/cloneDeep';

interface OptionsItem {
  id?: number;
  label: string;
  value: string;
  leaf?: boolean
  level?: number;
  lazy?: boolean;
  children?: OptionsItem[];
}

const CascaderItem = defineComponent({
  name: 'CascaderItem',
  props: {
    options: {
      type: Array as PropType<OptionsItem[]>,
      default: () => ([] as OptionsItem[]),
    },
    value: {
      type: Array as PropType<OptionsItem[]>,
      default: () => ([] as OptionsItem[]),
    },
    level: {
      type: Number,
      required: true,
    },
    lazy: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['change'],
  setup(props, { emit }) {
    // 记录当前选中的item
    const currentSelected = ref<OptionsItem>();

    const selectIndex = computed(() => {
      if (!props.value[props.level]) return -1;
      const { label } = props.value[props.level];
      return props.options.findIndex((item) => item.label === label);
    });

    // 根据当前选中的 计算出右边
    const lists = computed(() => {
      if (props.lazy) { // 异步加载
        if (props.value[props.level] && props.value[props.level].id) {
          const o = props.options.find((item) => item.id === props.value[props.level].id);
          return o?.children;
        }
        return [];
      }
      // 同步加载
      return props.value[props.level] && props.value[props.level].children;
    });

    // 处理点击选
    const handleSelect = (item: OptionsItem) => {
      currentSelected.value = item;
      // eslint-disable-next-line
      item.lazy = props.lazy;
      const cloneValue = cloneDeep(props.value);
      // 把当前选中项的后面+1的所有全部删除
      cloneValue.splice(props.level + 1);
      // 更新当前所选项
      cloneValue[props.level] = item;
      // 更新选中最新值
      emit('change', cloneValue);
    };

    // 右边的CascaderItem组件的change事件用来通知左边更新
    const change = (value: OptionsItem[]) => {
      emit('change', value);
    };

    // 先明确咋写 再动手写代码
    // 渲染时根据当前项数据是否有children显示右侧箭头
    // 子组件点击时要明确是不是异步的 如果时异步显示icon-loading 否则不做任何处理
    // 异步请求完成得移除icon-loading 回到原来得状态

    return () => <div class="cascader-panel-content">
      <div class="cascader-panel-left">
        <ul class="cascader-options">
          {/* 当异步加载数据的时候我在改变这个值就行 loading 不加载的 */}
          {
            props.options.map((item, index) => {
              const iconClasses = [
                'icon-container',
                {
                  'icon-right-arrow': !item.lazy && (item.leaf || item.children?.length),
                  'icon-loading': item.lazy,
                },
              ];
              return <li
                class={`cascader-options-item ${index === selectIndex.value ? 'active' : ''}`}
                title={item.label}
                onClick={() => handleSelect(item)}
              >
                { item.label }
                <i class={iconClasses}></i>
              </li>;
            })
          }
        </ul>
      </div>
      {
        lists.value && lists.value.length ? <div class="cascader-panel-right">
          <CascaderItem
            options={lists.value}
            value={props.value}
            level={props.level + 1}
            onChange={change}
            lazy={props.lazy}
          ></CascaderItem>
        </div> : null
      }
    </div>;
  },
});

export default CascaderItem;
