import {
  computed,
  defineComponent,
  inject,
  nextTick,
  PropType,
  ref,
  Ref,
  Transition,
  watch
} from 'vue';
import { CloseCircleOutlined } from '@ant-design/icons-vue';
import { drawerKey, drawerStyleKey, updateDrawerKey } from '../utils/key';
import { globalOptions } from '../utils/setGlobalOptions';
import type { GlobalOptions } from '../types';

import { _t } from '@kt/unity-locale';

type ButtonsPosition = 'append' | 'fixed' | 'auto';
const Drawer = defineComponent({
  props: {
    spin: {
      type: Object,
      default: () => ({ spinning: false })
    },
    title: {
      type: String,
      default: ''
    },
    buttonsPosition: {
      type: String as PropType<ButtonsPosition>,
      default: 'auto'
    },
    // ✨ 可全局配置
    // 抽屉风格
    drawerStyle: {
      type: String as PropType<GlobalOptions['drawerStyle']>,
      default: () => globalOptions.drawerStyle
    },
    // ✨ 可全局配置
    // antDrawer 透传，目前仅支持部分透传
    // https://antdv.com/components/drawer-cn#API
    antDrawer: {
      type: Object as PropType<GlobalOptions['antDrawer']>,
      default: () => globalOptions.antDrawer
    }
  },
  emits: ['close', 'after-visible-change'],
  setup(props, { slots, emit, attrs }) {
    const drawer = inject<Ref<boolean>>(drawerKey)!;
    const updateDrawer = inject<(val: boolean) => void>(updateDrawerKey)!;

    const drawerStyle =
      inject<Ref<GlobalOptions['drawerStyle']>>(drawerStyleKey)!;
    watch(
      () => props.drawerStyle,
      val => {
        drawerStyle.value = val;
      },
      { immediate: true }
    );

    const antDrawer = computed(() => ({
      ...globalOptions.antDrawer,
      ...props.antDrawer
    }));

    // handleAfterEnter，handleAfterLeave 用于抹平 a-drawer 组件的 onAfterVisibleChange
    const handleAfterEnter = () => {
      emit('after-visible-change', true);
    };
    const handleAfterLeave = () => {
      emit('after-visible-change', false);
    };

    const handleAfterVisibleChange = (visible: boolean) => {
      emit('after-visible-change', visible);
    };

    const handleCLose = () => {
      emit('close');
      updateDrawer(false);
    };

    // buttons 位置控制
    // const buttonsPosition = ref<ButtonsPosition>(props.buttonsPosition);
    const buttonsPosition = ref<ButtonsPosition>('append');
    const drawerEl = ref();
    watch(
      [drawer, () => props.buttonsPosition],
      async ([_drawer, _buttonsPosition]) => {
        if (_drawer) {
          // console.log('_drawer :>> ', _drawer);
          // console.log('_buttonsPosition :>> ', _buttonsPosition);

          // // 默认初始化 append，然后再进行精确计算
          // buttonsPosition.value = 'append';
          // await nextTick();
          setTimeout(async () => {
            // 外部控制计算方式，auto（默认）自动计算位置
            if (_buttonsPosition === 'auto') {
              // 默认初始化 append，然后再进行精确计算
              buttonsPosition.value = 'append';
              // nextTick 才可以获取到 $buttonsAppend 进行相关计算
              await nextTick();

              const $main = drawerEl.value.querySelector(
                '.table-layout__drawer-main'
              );
              // 找到 append button，进行计算
              const $buttonsAppend = drawerEl.value.querySelector(
                '.table-layout__drawer-main .table-layout__drawer-buttons'
              );
              if ($buttonsAppend) {
                // 判断出现滚动条，按钮组固定
                buttonsPosition.value =
                  $main.scrollHeight > $main.clientHeight ? 'fixed' : 'append';

                // console.log('$main.scrollHeight :>> ', $main.scrollHeight);
                // console.log('$main.clientHeight :>> ', $main.clientHeight);
                // console.log('calc-buttonsPosition :>> ', buttonsPosition.value);
              }
            } else {
              buttonsPosition.value = _buttonsPosition;
            }
            // console.log('last-buttonsPosition :>> ', buttonsPosition.value);
            // 动画执行过程获取不到高度，所以这里设置延迟，目前动画是0.2s
          }, 220);
        }
      },
      { immediate: true }
    );

    return () =>
      props.drawerStyle === 'custom' ? (
        <Transition
          name="drawer-fade"
          onAfterEnter={handleAfterEnter}
          onAfterLeave={handleAfterLeave}
        >
          <div
            v-show={drawer.value}
            class={'table-layout__drawer'}
            // TODO: 这里的 flex 可以配置动态，或者用 width 的方式控制
            style={{ flex: 2, width: 0 }}
            ref={drawerEl}
          >
            {/* delay={300} */}
            <a-spin {...props.spin}>
              <div class="table-layout__drawer-title-wrapper flex items-center">
                <div class="flex-1 flex items-center">
                  {slots.title || props.title !== '' ? (
                    <div class="table-layout__drawer-title">
                      {slots.title ? slots.title() : props.title}
                    </div>
                  ) : null}
                </div>
                <div
                  class="table-layout__drawer-close ml-[32px]"
                  onClick={handleCLose}
                >
                  <CloseCircleOutlined
                    style={{ fontSize: '16px' }}
                    class="cursor-pointer !text-[#BFC6D1] hover:!text-[#3e8dff]"
                    // 关闭
                    title={_t('KTUnity.TableLayout.close')}
                  />
                </div>
              </div>
              <div class="table-layout__drawer-main flex-1 !w-full !h-0 overflow-auto">
                {slots.default?.()}

                {/* buttons 追加 */}
                {slots.buttons && buttonsPosition.value === 'append' ? (
                  <div class="table-layout__drawer-buttons table-layout__drawer-buttons--append py-[12px] border-t border-0 border-solid border-[transparent]">
                    {slots.buttons()}
                  </div>
                ) : null}
              </div>
              {/* buttons 固定 */}
              {slots.buttons && buttonsPosition.value === 'fixed' ? (
                <div class="table-layout__drawer-buttons table-layout__drawer-buttons--fixed px-[32px] py-[12px] border-t border-0 border-solid border-[#EBEFF5]">
                  {slots.buttons()}
                </div>
              ) : null}
            </a-spin>
          </div>
        </Transition>
      ) : (
        <a-drawer
          class="table-layout__drawer--ant"
          title={
            slots.title || props.title !== ''
              ? slots.title
                ? slots.title()
                : props.title
              : null
          }
          closeIcon={
            <CloseCircleOutlined
              style={{ fontSize: '16px' }}
              class="cursor-pointer !text-[#BFC6D1] hover:!text-[#3e8dff]"
              // 关闭
              title={_t('KTUnity.TableLayout.close')}
            />
          }
          visible={drawer.value}
          {...antDrawer.value}
          // keyboard={props.antDrawer!.keyboard}
          // mask={props.antDrawer!.mask}
          // maskClosable={props.antDrawer!.maskClosable}
          // width={props.antDrawer!.width}
          // placement={props.antDrawer!.placement}
          onAfterVisibleChange={handleAfterVisibleChange}
          onClose={handleCLose}
        >
          <div ref={drawerEl} class="table-layout__drawer">
            <a-spin {...props.spin}>
              <div class="table-layout__drawer-main flex-1 !w-full !h-0 overflow-auto">
                {slots.default?.()}

                {/* buttons 追加 */}
                {slots.buttons && buttonsPosition.value === 'append' ? (
                  <div class="table-layout__drawer-buttons table-layout__drawer-buttons--append py-[12px] border-t border-0 border-solid border-[transparent]">
                    {slots.buttons()}
                  </div>
                ) : null}
              </div>
              {/* buttons 固定 */}
              {slots.buttons && buttonsPosition.value === 'fixed' ? (
                <div class="table-layout__drawer-buttons table-layout__drawer-buttons--fixed px-[32px] py-[12px] border-t border-0 border-solid border-[#EBEFF5]">
                  {slots.buttons()}
                </div>
              ) : null}
            </a-spin>
          </div>
        </a-drawer>
      );
  }
});

export { Drawer, ButtonsPosition };
