import { defineComponent, ref, watch, nextTick, computed, createVNode, Teleport, Transition, withDirectives, vShow, Fragment } from 'vue';
import { isNumber } from 'lodash-es';
import FButton from '../button';
import FScrollbar from '../scrollbar';
import { CloseOutlined } from '../icon';
import PopupManager from '../_util/popupManager';
import useLockScreen from '../_util/use/useLockScreen';
import { useConfig } from '../config-provider';
import { useTheme } from '../_theme/useTheme';
import { pxfy } from '../_util/utils';
import useEsc from '../_util/use/useEsc';
import { useLocale } from '../config-provider/useLocale';
import { useResizable } from './useResizable';
import { COMPONENT_NAME, prefixCls } from './const';
import { drawerProps, UPDATE_SHOW_EVENT, OK_EVENT, CANCEL_EVENT, AFTER_ENTER_EVENT, AFTER_LEAVE_EVENT } from './props';
import { useDrawerDimension } from './useDimension';

const Drawer = defineComponent({
  name: COMPONENT_NAME,
  props: drawerProps,
  emits: [UPDATE_SHOW_EVENT, OK_EVENT, CANCEL_EVENT, AFTER_ENTER_EVENT, AFTER_LEAVE_EVENT],
  setup(props, ctx) {
    useTheme();
    const zIndex = ref(PopupManager.nextZIndex());
    const visible = ref(false);
    useLockScreen(visible);
    watch(() => props.show, () => {
      if (props.show) {
        zIndex.value = PopupManager.nextZIndex();
      }
      nextTick(() => {
        visible.value = props.show;
      });
    }, {
      immediate: true
    });
    const config = useConfig();
    const getContainer = computed(() => {
      var _config$getContainer;
      return props.getContainer || ((_config$getContainer = config.getContainer) === null || _config$getContainer === void 0 ? void 0 : _config$getContainer.value);
    });
    const {
      t
    } = useLocale();
    function handleCancel(event) {
      ctx.emit(UPDATE_SHOW_EVENT, false);
      ctx.emit(CANCEL_EVENT, event);
    }
    const escClosable = computed(() => props.escClosable);
    useEsc(handleCancel, escClosable);
    function handleOk(event) {
      ctx.emit(OK_EVENT, event);
    }
    function handleTransitionAfterEnter(el) {
      ctx.emit(AFTER_ENTER_EVENT, el);
    }
    function handleTransitionAfterLeave(el) {
      ctx.emit(AFTER_LEAVE_EVENT, el);
    }
    const hasHeader = () => ctx.slots.title || props.title;
    function getHeader() {
      var _ctx$slots$title, _ctx$slots;
      const closeJsx = props.closable && createVNode("div", {
        "class": `${prefixCls}-close`,
        "onClick": handleCancel
      }, [createVNode(CloseOutlined, null, null)]);
      if (!hasHeader()) {
        return closeJsx;
      }
      const header = ((_ctx$slots$title = (_ctx$slots = ctx.slots).title) === null || _ctx$slots$title === void 0 ? void 0 : _ctx$slots$title.call(_ctx$slots)) || props.title;
      return createVNode("div", {
        "class": `${prefixCls}-header`
      }, [header, closeJsx]);
    }
    function getFooter() {
      if (!props.footer) {
        return null;
      }
      let footer;
      if (ctx.slots.footer) {
        footer = ctx.slots.footer();
      } else {
        footer = createVNode(Fragment, null, [createVNode(FButton, {
          "type": "primary",
          "class": "btn-margin",
          "size": "middle",
          "onClick": handleOk,
          "loading": props.okLoading
        }, {
          default: () => [props.okText || t('drawer.okText')]
        }), props.showCancel && createVNode(FButton, {
          "size": "middle",
          "onClick": handleCancel
        }, {
          default: () => [props.cancelText || t('drawer.cancelText')]
        })]);
      }
      return createVNode("div", {
        "class": {
          [`${prefixCls}-footer`]: true,
          [`${prefixCls}-footer-has-border`]: props.footerBorder
        }
      }, [footer]);
    }
    const drawerDimension = useDrawerDimension(props);
    const styles = computed(() => {
      const sizeStyle = {
        width: '100%',
        height: '100%'
      };
      const dimensionKey = ['top', 'bottom'].includes(props.placement) ? 'height' : 'width';
      sizeStyle[dimensionKey] = isNumber(drawerDimension.value) ? pxfy(drawerDimension.value) : drawerDimension.value;
      return sizeStyle;
    });
    const {
      onMousedown,
      drawerRef,
      dragClass
    } = useResizable({
      props,
      drawerDimension
    });
    const showDom = computed(() => props.displayDirective === 'if' && visible.value || props.displayDirective === 'show');
    const wrapperClass = computed(() => {
      return [`${prefixCls}-wrapper`, props.contentClass].filter(Boolean);
    });
    const rootClass = computed(() => {
      return [prefixCls, `${prefixCls}-${props.placement}`, props.wrapperClass].filter(Boolean);
    });
    return () => {
      var _getContainer$value, _getContainer$value2, _ctx$slots$default, _ctx$slots2;
      return createVNode(Teleport, {
        "disabled": !((_getContainer$value = getContainer.value) !== null && _getContainer$value !== void 0 && _getContainer$value.call(getContainer)),
        "to": (_getContainer$value2 = getContainer.value) === null || _getContainer$value2 === void 0 ? void 0 : _getContainer$value2.call(getContainer)
      }, {
        default: () => [createVNode("div", {
          "class": rootClass.value
        }, [createVNode(Transition, {
          "name": `${prefixCls}-mask-fade`
        }, {
          default: () => [props.mask && showDom.value && withDirectives(createVNode("div", {
            "class": `${prefixCls}-mask`,
            "style": {
              zIndex: zIndex.value
            }
          }, null), [[vShow, visible.value]])]
        }), createVNode(Transition, {
          "name": `${prefixCls}-fade`,
          "onAfterEnter": handleTransitionAfterEnter,
          "onAfterLeave": handleTransitionAfterLeave
        }, {
          default: () => [showDom.value && withDirectives(createVNode("div", {
            "class": {
              [`${prefixCls}-container`]: true,
              // 没有蒙层时，该属性才生效
              [`${prefixCls}-operable`]: !props.mask && props.operable,
              [`${prefixCls}-mask-closable`]: props.mask && props.maskClosable,
              [`${prefixCls}-no-header`]: !hasHeader(),
              [`${prefixCls}-no-footer`]: !props.footer
            },
            "style": {
              zIndex: zIndex.value
            },
            "onClick": event => props.maskClosable && props.mask && handleCancel(event)
          }, [createVNode("div", {
            "class": wrapperClass.value,
            "ref": drawerRef,
            "style": styles.value,
            "onClick": event => event.stopPropagation()
          }, [props.resizable && createVNode("div", {
            "class": dragClass.value,
            "onMousedown": onMousedown
          }, [createVNode("div", {
            "class": `${prefixCls}-drag-icon`
          }, null)]), getHeader(), createVNode(FScrollbar, {
            "class": `${prefixCls}-body-wrapper`,
            "containerClass": `${prefixCls}-body-container`,
            "always": true
          }, {
            default: () => [(_ctx$slots$default = (_ctx$slots2 = ctx.slots).default) === null || _ctx$slots$default === void 0 ? void 0 : _ctx$slots$default.call(_ctx$slots2)]
          }), getFooter()])]), [[vShow, visible.value]])]
        })])]
      });
    };
  }
});

export { Drawer as default };
