<template>
  <el-dialog v-bind="megeProps" :fullscreen="fullscreen" :class="['com-dialog',customClass]">
    <template #header v-if="props.header !== false">
      <el-row>
        <div class="el-dialog__title zt-dialog__title">
          <slot name="title">{{ props.title }}</slot>
          <BasicHelp
            class="dialog-title-help`"
            v-if="props.helpMessage"
            :text="helpMessage"
            placement="top"
          />
        </div>
        <el-space size="default">
          <button
            type="button"
            class="el-dialog__headerbtn"
            @click="fullscreen = !fullscreen"
            v-if="props.showFullscreen"
          >
            <el-icon class="el-dialog__close"><FullScreen /></el-icon>
          </button>
          <button
            type="button"
            class="el-dialog__headerbtn"
            @click="dialogVisible = false"
            v-if="props.showClose"
          >
            <el-icon class="el-dialog__close"><Close /></el-icon>
          </button>
        </el-space>
      </el-row>
    </template>

    <ElScrollbar v-if="props.scroll" :style="dialogStyle">
      <slot></slot>
    </ElScrollbar>
    <slot v-else></slot>

    <template v-if="props.footer" #footer>
      <slot name="footer">
        <template v-if="typeof props.footer === 'boolean'">
          <el-button v-bind="props.cancelButtonProps" @click="handleCancel">{{
            props.cancelText
          }}</el-button>
          <el-button
            type="primary"
            v-bind="props.okButtonProps"
            :loading="okLoading"
            @click="handleOk"
            >{{ props.okText }}</el-button
          >
        </template>
        <template v-else-if="typeof props.footer === 'function'">
          <component :is="props.footer()" />
        </template>
      </slot>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import {
  defineProps,
  defineSlots,
  computed,
  ref,
  type VNode,
  useAttrs,
  watch,
  nextTick,
  unref
} from 'vue';
import type { ButtonProps } from 'element-plus';
import { DialogModalProps } from './props';
import { Close, FullScreen } from '@element-plus/icons-vue';
import { BasicHelp } from '@/components/helpMessage';
import { isNumber } from '@/utils/is';

defineOptions({
  name: 'Dialog',
});

interface Props extends DialogModalProps {
  footer?: boolean | (() => VNode);
  okText?: string;
  cancelText?: string;
  okButtonProps?: Partial<ButtonProps>;
  cancelButtonProps?: Partial<ButtonProps>;
  onOk?: () => void;
  onBeforeOk?: () => Promise<boolean>;
  onCancel?: () => void;
  lockScroll?: boolean;
  closeOnClickModal?: boolean;
  closeOnPressEscape?: boolean;
  modal?: boolean;
  showFullscreen?: boolean;
  customClass?: string;
}

const props = withDefaults(defineProps<Props>(), {
  footer: true,
  okText: '确认',
  showClose: false,
  cancelText: '取消',
  lockScroll: true,
  closeOnClickModal: true,
  closeOnPressEscape: true,
  modal: true,
  showFullscreen: true,
  customClass: '', // 默认为空
});

setTimeout(() => {
  console.log(props.modalClass);
}, 1000);

const attrs = useAttrs();

const megeProps = computed(() => {
  return {
    ...props,
    ...attrs,
  };
});

defineSlots<{
  title: () => VNode;
  footer: () => VNode;
  default: () => VNode;
}>();

const okLoading = ref(false);
const fullscreen = ref(false);

const dialogHeight = ref(
  isNumber(props.maxHeight) ? `${props.maxHeight}px` : props.maxHeight,
);

watch(
  () => fullscreen.value,
  async (val: boolean) => {
    await nextTick();
    if (val) {
      const windowHeight = document.documentElement.offsetHeight;
      dialogHeight.value = `${windowHeight - 55 - 60 - (props.footer ? 63 : 0)}px`;
    } else {
      dialogHeight.value = isNumber(props.maxHeight)
        ? `${props.maxHeight}px`
        : props.maxHeight;
    }
  },
  {
    immediate: true,
  },
);

const dialogStyle = computed(() => {
  return {
    height: unref(dialogHeight),
  };
});

const emit = defineEmits(['update:modelValue']);

const dialogVisible = defineModel('modelValue', {
  type: Boolean,
  default: false,
});

const handleOk = async () => {
  if (props.onBeforeOk) {
    try {
      okLoading.value = true;
      const flag = await props.onBeforeOk();
      if (flag) {
        okLoading.value = false;
        dialogVisible.value = false;
      }
    } catch (error) {
      okLoading.value = false;
    }
  } else {
    props.onOk?.();
    dialogVisible.value = false;
  }
};

const handleCancel = () => {
  props.onCancel?.();
  dialogVisible.value = false;
};
</script>
<style lang="scss" scoped>
:deep(.el-dialog__headerbtn) {
  position: static;
  width: auto;
  height: auto;
}

.com-dialog {
  
  .#{$elNamespace}-overlay-dialog {
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .#{$elNamespace}-dialog {
    margin: 0 !important;

    &__header {
      height: 54px;
      padding: 0;
      margin-right: 0 !important;
      border-bottom: 1px solid var(--el-border-color);
    }

    &__body {
      padding: 15px !important;
    }

    &__footer {
      border-top: 1px solid var(--el-border-color);
    }

    &__headerbtn {
      top: 0;
    }
  }
}

.zt-dialog__title {
  flex: 1;
}
</style>
