import {
  App,
  computed,
  defineComponent,
  nextTick,
  provide,
  ref,
  toRef,
  watch
} from 'vue';

// @ts-ignore
import style from './style/index.module.less';
import {
  drawerKey,
  filterCustomSwitchKey,
  filterLeftMountedKey,
  filterSecondMountedKey,
  filterSecondOpenKey,
  mainMountedKey,
  updateDrawerKey
} from './utils/key';

import scrollTo from 'ant-design-vue/es/_util/scrollTo';

const Tl = defineComponent({
  name: 'Tl',
  props: {
    fixed: { type: Boolean, default: true },
    drawer: { type: Boolean, default: false }
  },
  emits: ['update:drawer'],
  setup(props, { attrs, slots, emit }) {
    // 动画为 @animation-duration-fast: 0.2s;这里需要预留时间
    const DELAY = 300;

    const mainMounted = ref(false);
    const filterSecondMounted = ref(false);
    const filterSecondOpen = ref(false);
    const filterLeftMounted = ref(false);
    const customSwitch = ref(false);

    provide(mainMountedKey, mainMounted);
    provide(filterSecondMountedKey, filterSecondMounted);
    provide(filterSecondOpenKey, filterSecondOpen);
    provide(filterLeftMountedKey, filterLeftMounted);
    provide(filterCustomSwitchKey, customSwitch);

    provide(drawerKey, toRef(props, 'drawer'));
    provide(updateDrawerKey, (val: boolean) => {
      emit('update:drawer', val);
    });

    // const clsFixed = computed(() => (props.fixed ? style['fixed'] : ''));
    const clsFixed = computed(() => (props.fixed ? 'table-layout--fixed' : ''));

    /**
     * main 被挂载，样式要做出改变
     */
    const clsMainMounted = computed(
      () =>
        `${
          mainMounted.value
            ? 'flex' // main被挂载，默认采用 flex，承载 main 和 drawer
            : 'flex flex-col px-[32px] py-[24px] !bg-[#fff]'
        }`
    );

    // const clsHasDrawer = ref('');
    // // 做延迟
    // watch(
    //   () => props.drawer,
    //   (val: boolean) => {
    //     if (val) {
    //       clsHasDrawer.value = 'table-layout--has-drawer';
    //     } else {
    //       setTimeout(() => {
    //         clsHasDrawer.value = '';
    //       }, DELAY);
    //     }
    //   }
    // );

    const clsHasDrawer = computed(() => {
      return `${props.drawer ? 'table-layout--has-drawer' : ''}`;
    });

    const cls = computed(() => {
      return `${style['table-layout']} table-layout h-full bg-[#f5f6f9] ${clsHasDrawer.value} ${clsFixed.value} ${clsMainMounted.value}`;
    });

    // #region 滚动条控制相关
    const tl = ref<HTMLElement>();
    const cacheScroll = { scrollLeft: 0, scrollTop: 0 };
    watch(
      () => props.drawer,
      async (val: boolean) => {
        const $tableBody = tl.value?.querySelector(
          '.ant-table-body'
        ) as HTMLElement;
        // 有 $tableBody 这个元素的 是因为 table :scroll 对象赋值了 x或者y
        if ($tableBody) {
          if (val) {
            const { scrollLeft, scrollTop } = $tableBody;
            Object.assign(cacheScroll, { scrollLeft, scrollTop });

            await nextTick();

            setTimeout(() => {
              // 滚动到合适位置
              const $row = $tableBody.querySelector(
                '.ant-table-row[ant-table-row-selected-custom="true"]'
              ) as HTMLElement;
              if ($row) {
                // $tableBody.scrollTop =
                //   $row.offsetTop -
                //   ($tableBody.offsetHeight - $row.offsetHeight) / 2;

                scrollTo(
                  $row.offsetTop -
                    ($tableBody.offsetHeight - $row.offsetHeight) / 2,
                  {
                    getContainer: () => $tableBody,
                    duration: 50
                  }
                );
              }
            }, DELAY);
          } else {
            await nextTick();
            setTimeout(() => {
              const { scrollLeft, scrollTop } = cacheScroll;
              Object.assign($tableBody, { scrollLeft, scrollTop });
            }, DELAY);
          }
        }
      }
    );
    // #endregion

    return () => (
      <div ref={tl} class={cls.value}>
        {slots.default?.()}
      </div>
    );
  }
});
export default Tl as typeof Tl & {
  install: (app: App, ...options: any[]) => any;
};
