<template>
  <el-dialog
    :visible.sync="visible"
    :title="title"
    :width="width"
    destroy-on-close
  >
    <template #title>
      <div class="dialog-header" v-if="tagContent">
        <span>{{ title }}</span>
        <div class="dialog-header-extra">
          <el-tag :type="tagType">{{ tagContent }}</el-tag>
        </div>
      </div>
      <template v-else>{{ title }}</template>
    </template>
    <component
      v-if="dynamicComponent"
      :is="dynamicComponent"
      ref="dynamicComponentRef"
      v-bind="componentProps"
    />
    <slot></slot>
    <template #footer>
      <div class="dialog-footer" :class="footerClass">
        <el-button class="button" size="large" type="primary" @click="onConfirm"> {{ onConfirmName || '保存' }} </el-button>
        <el-button class="button" size="large" :type="onCancelType" @click="onCancel"> {{ onCancelName || '取消' }} </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { computed, ref, markRaw } from "vue";
const dynamicComponentRef = ref(null);
defineExpose({
  dynamicComponentRef // 暴露给父组件
});

const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  width: {
    type: String,
    default: "50%",
  },
  title: {
    type: String,
    default: "",
  },
  dynamicComponent: {
    type: [Object, Function],
    default: null,
  },
  componentProps: {
    type: Object,
    default: () => ({}),
  },
  onConfirm: {
    type: Function,
    default: () => {},
  },
  onCancel: {
    type: Function,
    default: () => {},
  },
  onConfirmName: {
    type: String,
    default: "保存",
    validator: (value) => value === null || typeof value === 'string'
  },
  onCancelName: {
    type: String,
    default: "取消",
    validator: (value) => value === null || typeof value === 'string'
  },
  onCancelType: {
    type: String,
    default: null,
  },
  tagContent: {
    type: String,
    default: ""
  },
  tagType: {
    type: String,
    default: ""
  },
  footerPosition: {
    type: String,
    default: "center",
    validator: (value) => value === null || ['center', 'flex-end', 'flex-start'].includes(value)
  }
});

const normalizedComponent = computed(() =>
  props.dynamicComponent ? markRaw(props.dynamicComponent) : null
);

const footerClass = computed(() => {
  if (!props.footerPosition) {
    return 'footer-center';
  }
  return `footer-${props.footerPosition}`;
});
</script>

<style lang="scss" scoped>
.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;

  .dialog-header-extra {
    margin-left: auto;
  }
}

.dialog-footer {
  display: flex;

  &.footer-center {
    justify-content: center;
  }
  
  &.footer-flex-end {
    justify-content: flex-end;
  }
  
  &.footer-flex-start {
    justify-content: flex-start;
  }

  .button {
    width: 150px;
  }
}
</style>