import {
  filterCustomSwitchKey,
  filterLeftMountedKey,
  filterSecondMountedKey,
  filterSecondOpenKey
} from '../utils/key';
import {
  computed,
  defineComponent,
  inject,
  nextTick,
  PropType,
  reactive,
  Ref,
  toRef,
  toRefs,
  watch
} from 'vue';
import { getGuid, mountComponent } from '@kt/unity-utils';
import { CaretDownOutlined } from '@ant-design/icons-vue';

/**
 * 判断当前是否有挂载 filter-second 组件的行为
 */
const Filter = defineComponent({
  inheritAttrs: false,
  props: {
    role: {
      type: String as PropType<'' | 'tabs'>,
      default: ''
    }
  },
  setup(props, { slots, attrs }) {
    const filterLeftMounted = inject<Ref<boolean>>(filterLeftMountedKey)!;
    const renderDefault = () => {
      /* 如果是左右布局的场景就直接渲染默认的 slots */
      return filterLeftMounted.value ? (
        slots.default?.()
      ) : (
        // 不是左右布局，直接渲染过滤核心
        <FilterCore {...attrs} v-slots={slots} />
      );
    };

    const render = () => {
      let dom = null;
      switch (props.role) {
        case 'tabs':
          // dom = <a-form layout="inline">{slots.default?.()}</a-form>;
          // tabs，现在的”更多条件“按钮位置也是接在最后一个 a-form-item 后面，所以这里直接复用 FilterCore 组件逻辑
          dom = <FilterCore {...attrs} v-slots={slots} />;
          break;
        default:
          dom = renderDefault();
          break;
      }
      return dom;
    };

    return () => (
      <div
        class={`table-layout__filter flex w-full ${
          props.role !== ''
            ? `table-layout__filter-render-custom ${props.role}`
            : ''
        }`}
      >
        {render()}
      </div>
    );
  }
});

/**
 * MoreButton component
 */
const MoreButton = defineComponent({
  props: {
    filterSecondOpen: { type: Boolean, default: false },
    visible: { type: Boolean, default: false }
  },
  emits: ['change'],
  setup(props, { emit }) {
    const filterSecondOpen = toRef(props, 'filterSecondOpen');
    const handleToggle = () => {
      emit('change', !filterSecondOpen.value);
    };

    // 取消旋转效果，为了和目前的 antd 效果达成一致（antd 一些 select 相关展开时并没有旋转）
    // const clsOpen = computed(() => '');

    const clsOpen = computed(() => (filterSecondOpen.value ? 'open' : ''));
    return () => (
      <span
        class="table-layout__filter-button block h-[32px] leading-[32px] cursor-pointer mb-[8px] mr-[16px] select-none"
        onClick={handleToggle}
        v-show={props.visible}
      >
        更多条件
        <CaretDownOutlined
          class={`table-layout__filter-button-icon !text-[#B7BBC2] ml-[2px] ${clsOpen.value}`}
        />
      </span>
    );
  }
});

/**
 * 动态挂载“更多按钮”（指定位置）
 * @param node 需要挂载的节点
 * @param inject 需要注入的参数
 */
const createMoreButtonInstance = (
  node: HTMLElement,
  inject: Record<string, any>
) => {
  const { instance, unmount } = mountComponent(
    {
      setup(_, ctx) {
        const { filterSecondOpen } = inject;
        // https://v3.cn.vuejs.org/api/basic-reactivity.html#reactive
        // ref 赋值给 reactive 将会自动解包
        const state = reactive({
          visible: false,
          filterSecondOpen
        });
        const emit = {
          onChange(val: boolean) {
            state.filterSecondOpen = val;
          }
        };
        const show = () => {
          state.visible = true;
        };
        const hide = () => {
          state.visible = false;
        };
        const destroy = () => {
          unmount();
        };
        ctx.expose({
          ...toRefs(state),
          show,
          hide,
          destroy
        });
        return () => <MoreButton {...state} {...emit} />;
      }
    },

    // extra
    {
      parent: node,
      createRoot() {
        const root = document.createElement('span');
        return root;
      },
      insert(target) {
        const len = node.querySelectorAll('.ant-form-item').length;
        const $antFormItemLastEL =
          node.querySelectorAll('.ant-form-item')[len - 1];
        $antFormItemLastEL?.after(target);
      },
      remove(target) {
        node.removeChild(target);
      }
    }
  );
  return instance;
};

/**
 * 搜索栏核心
 */
const FilterCore = defineComponent({
  setup(props, { slots }) {
    const filterSecondMounted = inject<Ref<boolean>>(filterSecondMountedKey)!;
    const filterSecondOpen = inject<Ref<boolean>>(filterSecondOpenKey)!;
    const filterCustomSwitch = inject<Ref<boolean>>(filterCustomSwitchKey)!;

    // 动态挂载按钮
    const formId = `form-extend-${getGuid()}`;
    let moreButtonInstance: any = null;
    watch(
      filterSecondMounted,
      async (val: boolean) => {
        await nextTick();
        if (val) {
          const formEL = document.getElementById(formId);
          if (formEL && !filterCustomSwitch.value) {
            // 初始化”更多按钮“实例
            moreButtonInstance = createMoreButtonInstance(formEL!, {
              filterSecondOpen
            });
            moreButtonInstance.show();
          }
        } else {
          moreButtonInstance?.hide();
        }
      },
      { immediate: true }
    );
    return () => (
      <a-form layout="inline" id={formId}>
        {slots.default?.()}
      </a-form>
    );
  }
});

/**
 * 搜索栏左
 */
const FilterLeft = defineComponent({
  inheritAttrs: false,
  setup(props, { slots, attrs }) {
    const filterLeftMounted = inject<Ref<boolean>>(filterLeftMountedKey)!;
    filterLeftMounted.value = true;
    return () => (
      <div class="table-layout__filter-left flex-1">
        <FilterCore {...attrs} v-slots={slots} />
      </div>
    );
  }
});

/**
 * 搜索栏右，一般放置一些按钮如：导出
 */
const FilterRight = defineComponent({
  setup(props, { slots }) {
    return () => (
      <div class="table-layout__filter-right ml-[32px]">
        {slots.default?.()}
      </div>
    );
  }
});

export { Filter, FilterLeft, FilterRight };
