import {
  CreateElement,
  defineComponent,
  getCurrentInstance,
  PropType,
  reactive,
  ref,
  VNode,
} from 'vue';
import { useNamespace } from '@ibiz-template/vue-util';
import { isNumber } from 'lodash-es';
import { IModalOptions, IOverlayContainer } from '@ibiz-template/runtime';
import { useUIStore } from '@/store';
import '@ibiz-template/theme/style/components/util/modal/modal.scss';
import { OverlayContainer } from '../overlay-container/overlay-container';

export const AppModalComponent = defineComponent({
  props: {
    opts: {
      type: Object as PropType<IModalOptions>,
      default: () => ({}),
    },
  },
  setup(props, ctx) {
    const ns = useNamespace('modal');
    const { proxy } = getCurrentInstance()!;

    const isShow = ref(false);

    const { zIndex } = useUIStore();
    const modalZIndex = zIndex.increment();

    // 处理自定义样式,添加z-index变量
    const customStyle = reactive<IData>({});
    const { width, height } = props.opts;
    if (width) {
      customStyle.width = isNumber(width) ? `${width}px` : width;
    }
    if (height) {
      customStyle.height = isNumber(height) ? `${height}px` : height;
    }

    // 合并options
    const options = ref<IModalOptions>({ footerHide: true, modalClass: '' });
    if (props.opts) {
      Object.assign(options.value, props.opts);
    }

    // 所有关闭方式最终都走这个
    const onVisibleChange = (state: boolean) => {
      if (!state) {
        zIndex.decrement();
        ctx.emit('dismiss');
        document.body.removeChild(proxy.$el);
      }
    };

    const dismiss = () => {
      isShow.value = false;
    };

    const present = () => {
      isShow.value = true;
    };

    return {
      ns,
      isShow,
      options,
      modalZIndex,
      customStyle,
      present,
      dismiss,
      onVisibleChange,
    };
  },
  render() {
    return (
      <i-modal
        value={this.isShow}
        on-input={(val: boolean) => {
          this.isShow = val;
        }}
        class={[
          this.ns.b(),
          this.options.placement && this.ns.m(this.options.placement),
          this.options.modalClass,
        ]}
        style={{ [this.ns.cssVarBlockName('z-index')]: this.modalZIndex }}
        styles={this.customStyle}
        footer-hide={this.options.footerHide}
        on-on-visible-change={this.onVisibleChange}
      >
        {this.$slots.default}
      </i-modal>
    );
  },
});

/**
 * 创建模态框
 *
 * @author lxm
 * @date 2022-11-09 18:11:57
 * @export
 * @param {(_h: CreateElement) => VNode} render
 * @param {(IModalOptions | undefined)} [opts]
 * @returns {*}  {IOverlayContainer}
 */
export function createModal(
  render: (_h: CreateElement) => VNode,
  opts?: IModalOptions | undefined,
): IOverlayContainer {
  return new OverlayContainer(AppModalComponent, render, opts);
}
