import {
  defineComponent,
  getCurrentInstance,
  onMounted,
  PropType,
  reactive,
  ref,
} from 'vue';
import { useNamespace } from '@ibiz-template/vue-util';
import { ViewNeuron } from '@ibiz-template/controller';
import { isNumber } from 'lodash-es';
import { IModal, IModalData, ViewMode } from '@ibiz-template/runtime';
import { AppModalOptions } from '@/interface';
import { useUIStore } from '@/store';
import '@ibiz-template/theme/style/components/util/modal/modal.scss';

export const AppModalComponent = defineComponent({
  props: {
    componentName: String,
    componentProps: Object as PropType<IData>,
    opts: {
      type: Object as PropType<AppModalOptions>,
      default: () => ({}),
    },
    resolve: { type: Function, required: true },
    reject: { type: Function, required: true },
  },
  setup(props) {
    const ns = useNamespace('modal');

    const isShow = ref(false);
    const { proxy } = getCurrentInstance()!;

    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({ footerHide: true });
    if (props.opts) {
      Object.assign(options.value, props.opts);
    }

    // 执行模态关闭操作
    const doModalClose = () => {
      setTimeout(() => {
        zIndex.decrement();
        proxy.$destroy();
        document.body.removeChild(proxy.$el);
      }, 300);
    };

    // 模态自身的操作触发的关闭(如点右上角的×)
    const onVisibleChange = (state: boolean) => {
      if (!state) {
        props.resolve({ ok: false, data: {} });
        doModalClose();
      }
    };

    // 模态对象
    const modal: IModal = { mode: ViewMode.MODAL };

    const modalCaption = ref('');

    const onNeuronInit = (neuron: ViewNeuron) => {
      neuron.evt.on('setTitle', title => {
        modalCaption.value = title;
      });
      neuron.evt.on('closeView', (res: IModalData) => {
        props.resolve(res);
        doModalClose();
      });
    };

    const closeSelect = (res: IModalData) => {
      props.resolve(res);
      doModalClose();
    };

    onMounted(() => {
      isShow.value = true;
    });

    return {
      ns,
      modal,
      isShow,
      options,
      modalZIndex,
      customStyle,
      modalCaption,
      onNeuronInit,
      onVisibleChange,
      closeSelect,
    };
  },
  render(h) {
    return (
      <i-modal
        value={this.isShow}
        on-input={(val: boolean) => {
          this.isShow = val;
        }}
        class={[this.ns.b()]}
        style={{ [this.ns.cssVarBlockName('z-index')]: this.modalZIndex }}
        styles={this.customStyle}
        footer-hide={this.options.footerHide}
        on-on-visible-change={this.onVisibleChange}
      >
        {h(this.componentName, {
          props: {
            ...this.componentProps,
            modal: this.modal,
          },
          on: {
            neuronInit: this.onNeuronInit,
            closeSelect: this.closeSelect,
          },
        })}
      </i-modal>
    );
  },
});
