<template>
  <div v-if="visible" class="pd-mask" @click="handleMaskClick">
    <div class="pd-confirm" @click.stop>
      <h2 class="pd-title">{{ dynamicTitle || title }}</h2>

      <div class="pd-input-container" v-if="dynamicShowInput || showInput">
        <input ref="inputRef" v-model="inputModel" class="pd-input" :placeholder="dynamicInputPlaceholder || inputPlaceholder" @keyup.enter="handleConfirm" />
      </div>

      <p class="pd-message" v-else>{{ dynamicMessage || message }}</p>

      <div class="pd-buttons">
        <button v-if="dynamicShowConfirm || showConfirm" class="pd-button pd-confirm-btn" @click="handleConfirm">
          {{ dynamicConfirmText || confirmText }}
        </button>

        <button v-if="dynamicShowCancel || showCancel" class="pd-button pd-cancel" @click="handleCancel">
          {{ dynamicCancelText || cancelText }}
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, nextTick, onMounted, onUnmounted } from 'vue'

// 响应式数据用于动态更新 Modal 内容

const dynamicTitle = ref('')

const dynamicMessage = ref('')

const dynamicConfirmText = ref('确认')

const dynamicCancelText = ref('取消')

const dynamicShowConfirm = ref(true)

const dynamicShowCancel = ref(true)

const dynamicMaskClosable = ref(false)

const dynamicShowInput = ref(false)

const dynamicInputPlaceholder = ref('请输入文字')

const props = defineProps({
  title: {
    type: String,
    default: '',
  },
  message: {
    type: String,
    default: '',
  },
  confirmText: {
    type: String,
    default: '确认',
  },
  cancelText: {
    type: String,
    default: '取消',
  },
  showConfirm: {
    type: Boolean,
    default: true,
  },
  showCancel: {
    type: Boolean,
    default: true,
  },
  maskClosable: {
    type: Boolean,
    default: false,
  },
  showInput: {
    type: Boolean,
    default: false,
  },
  inputPlaceholder: {
    type: String,
    default: '请输入文字',
  },
  inputValue: {
    type: String,
    default: '',
  },
})

const emit = defineEmits(['confirm', 'cancel', 'update:visible'])
const visible = defineModel('visible', { type: Boolean, default: false })
const inputModel = defineModel('inputValue', { type: String, default: '' })

const inputRef = ref()

// Promise 控制变量

let resolvePromise, rejectPromise

// 返回 Promise 的方法，模拟原生 confirm 行为

const show = (options = {}) => {
  // 更新动态数据

  if (options.title !== undefined) dynamicTitle.value = options.title

  if (options.message !== undefined) dynamicMessage.value = options.message

  if (options.confirmText !== undefined) dynamicConfirmText.value = options.confirmText

  if (options.cancelText !== undefined) dynamicCancelText.value = options.cancelText

  if (options.showConfirm !== undefined) dynamicShowConfirm.value = options.showConfirm

  if (options.showCancel !== undefined) dynamicShowCancel.value = options.showCancel

  if (options.maskClosable !== undefined) dynamicMaskClosable.value = options.maskClosable

  if (options.showInput !== undefined) dynamicShowInput.value = options.showInput

  if (options.inputPlaceholder !== undefined) dynamicInputPlaceholder.value = options.inputPlaceholder

  if (options.inputValue !== undefined) inputModel.value = options.inputValue

  // 显示对话框

  visible.value = true

  emit('update:visible', true)

  // 返回 Promise

  return new Promise((resolve, reject) => {
    resolvePromise = resolve

    rejectPromise = reject
  })
}

const handleConfirm = () => {
  emit('confirm')
  visible.value = false
  emit('update:visible', false)

  // 解决 Promise，传递输入框的值
  if (resolvePromise) {
    resolvePromise(inputModel.value)
    resolvePromise = null
    rejectPromise = null
  }
}

const handleCancel = () => {
  emit('cancel')
  visible.value = false
  emit('update:visible', false)

  // 拒绝 Promise
  if (rejectPromise) {
    rejectPromise()
    resolvePromise = null
    rejectPromise = null
  }
}

const handleMaskClick = () => {
  if (props.maskClosable) {
    handleCancel() // 点击遮罩相当于取消
  }
}

// 添加/移除 body 滚动锁定
const lockBodyScroll = () => {
  document.body.style.overflow = 'hidden'
}

const unlockBodyScroll = () => {
  document.body.style.overflow = ''
}

onMounted(() => {
  if (visible.value) {
    lockBodyScroll()
  }
})

onUnmounted(() => {
  unlockBodyScroll()
})

// 监听 visible 变化
watch(visible, (newVal, oldVal) => {
  if (newVal) {
    lockBodyScroll()
    // 如果模态框包含输入框，则自动获取焦点
    if (dynamicShowInput.value || props.showInput) {
      // 使用 nextTick 确保在 DOM 更新后聚焦
      nextTick(() => {
        // 添加更长的延迟确保动画完成
        setTimeout(() => {
          // 确保 inputRef 存在并且可见
          if (inputRef.value && inputRef.value.offsetParent !== null) {
            inputRef.value.focus()
            inputRef.value.select() // 选中所有文本，提升用户体验
          }
        }, 100)
      })
    }
  } else {
    unlockBodyScroll()
    // 重置输入框引用，确保下次打开时能正确获取焦点
    if (inputRef.value) {
      inputRef.value.blur()
    }
  }
})

// 暴露 show 方法给父组件使用
defineExpose({ show })
</script>

<style scoped>
.pd-mask {
  position: fixed;
  inset: 0;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999999999;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: inherit;
  background: var(--confirmBg, inherit);
}

.pd-confirm {
  background: inherit;
  background: var(--confirmTheme, #fff);
  text-align: center;
  color: var(--confirmColor, #636363);
  font-size: var(--confirmFontSize, 1rem);
  max-width: 75vw;
  min-width: 20em;
  box-shadow: 0px 35px 35px -10px rgba(0, 0, 0, 0.33);
  border-radius: 10px;
  position: relative;
  white-space: break-spaces;
  word-break: break-all;
  overflow: hidden;
}

.pd-title {
  position: relative;
  font-size: 1.3em;
  min-height: 1em;
  background: var(--confirmBtnBg, #fafafa);
  color: var(--confirmBtnColor, #636363);
  margin: 0;
  padding: 0.5em 0;
}

.pd-message {
  position: relative;
  border-top: 1px solid var(--confirmBtnBorder, #f1f1f1);
  width: 100%;
  max-height: 70vh;
  border-bottom: 1px solid var(--confirmBtnBorder, #f1f1f1);
  margin: 0 auto;
  box-sizing: border-box;
  padding: 2em 10%;
  line-height: 1.4;
  overflow: auto;
}

.pd-input-container {
  margin-block: 1.5em;
  padding: 0 10% 1em;
  position: relative;
  z-index: 2;
}

.pd-input {
  width: 100%;
  padding: 0.8em;
  font-size: 1em;
  border: 1px solid var(--confirmBtnBorder, #f1f1f1);
  border-radius: 4px;
  box-sizing: border-box;
  outline: none;
  background: var(--confirmTheme, #fff);
  color: var(--confirmColor, #636363);
  box-shadow: 0px 0px 4px inset rgba(0, 0, 0, 0.12);
}

.pd-input::placeholder {
  color: var(--black-20);
}

.pd-input:focus {
  border-color: #4d90fe;
}

.pd-input::selection {
  background-color: #4d90fe; /* 选中时的背景颜色 */
  color: #ffffff; /* 选中时的文字颜色 */
}

.pd-buttons {
  display: flex;
}

.pd-button {
  position: relative;
  width: 100%;
  font-size: 1em;
  appearance: none;
  background: var(--confirmBtnBg, #fafafa);
  color: var(--confirmBtnColor, #636363);
  border: none;
  border-right: 1px solid var(--confirmBtnBorder, #f1f1f1);
  padding: 1em 0;
  cursor: pointer;
  outline: none;
}

/* 当同时显示确认和取消按钮时，每个按钮占50%宽度 */
.pd-button:first-child:nth-last-child(2),
.pd-button:first-child:nth-last-child(2) ~ .pd-button {
  width: 50%;
}

/* 当只显示一个按钮时，该按钮占100%宽度 */
.pd-button:first-child:nth-last-child(1) {
  width: 100%;
  border-right: none;
}

/* 只有最后一个按钮没有右边框 */
.pd-button:last-child {
  border-right: none;
}
</style>
