<template>
  <Teleport to="body">
    <Transition name="popup-fade">
      <div
        v-if="visible"
        class="stretchable-modal__overlay"
        @click="handleOverlayClick"
      >
        <div
          class="stretchable-modal__container"
          :style="containerStyle"
          @click.stop
        >
          <!-- 头部：大弹窗top切图.png -->
          <div class="stretchable-modal__header">
            <slot name="header">
              <h3 class="stretchable-modal__title">{{ title }}</h3>
            </slot>
            <button
              v-if="showClose"
              class="stretchable-modal__close"
              @click="handleClose"
              aria-label="关闭弹窗"
            >
              <img
                src="../../assets/images/modal/closeIcon.png"
                alt="关闭"
                class="close-icon"
              />
            </button>
          </div>

          <!-- 中间：大弹窗mid切图.png -->
          <div class="stretchable-modal__body">
            <slot></slot>
          </div>

          <!-- 底部：大弹窗bottom切图.png -->
          <div v-if="$slots.footer" class="stretchable-modal__footer">
            <slot name="footer"></slot>
          </div>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script setup>
import { computed, watch, onMounted, onUnmounted } from 'vue';

/**
 * StretchableModal - 三段式可拉伸弹窗组件
 *
 * 特性:
 * - 使用三张切图实现可拉伸的弹窗背景（头部、中间、底部）
 * - 头部和底部仅支持横向拉伸，中间部分支持全方向拉伸
 * - 标题居中显示
 * - 支持多种交互方式关闭（点击遮罩、ESC键、关闭按钮）
 * - 支持插槽自定义内容
 */

const props = defineProps({
  /**
   * 控制弹窗显示/隐藏
   */
  visible: {
    type: Boolean,
    default: false
  },
  /**
   * 弹窗标题
   */
  title: {
    type: String,
    default: ''
  },
  /**
   * 弹窗宽度，支持 CSS 单位或响应式值
   * @example '800px' | 'clamp(778px, 90vw, 1200px)'
   */
  width: {
    type: String,
    default: 'clamp(900px, 85vw, 1400px)'
  },
  /**
   * 弹窗高度，支持 CSS 单位或响应式值
   * @example '600px' | 'clamp(500px, 80vh, 800px)'
   */
  height: {
    type: String,
    default: 'clamp(600px, 85vh, 900px)'
  },
  /**
   * 点击遮罩层是否关闭弹窗
   */
  closeOnClickModal: {
    type: Boolean,
    default: true
  },
  /**
   * 按 ESC 键是否关闭弹窗
   */
  closeOnPressEscape: {
    type: Boolean,
    default: true
  },
  /**
   * 是否显示关闭按钮
   */
  showClose: {
    type: Boolean,
    default: true
  }
});

const emit = defineEmits(['update:visible', 'close', 'open']);

/**
 * 计算弹窗容器的样式
 */
const containerStyle = computed(() => ({
  width: props.width,
  height: props.height
}));

/**
 * 处理遮罩层点击事件
 */
const handleOverlayClick = () => {
  if (props.closeOnClickModal) {
    handleClose();
  }
};

/**
 * 关闭弹窗
 */
const handleClose = () => {
  emit('update:visible', false);
  emit('close');
};

/**
 * 处理 ESC 键按下事件
 */
const handleKeydown = (event) => {
  if (props.visible && props.closeOnPressEscape && event.key === 'Escape') {
    handleClose();
  }
};

// 监听 visible 变化，触发相应事件
watch(() => props.visible, (newVal) => {
  if (newVal) {
    emit('open');
  }
});

// 挂载和卸载时添加/移除键盘事件监听
onMounted(() => {
  document.addEventListener('keydown', handleKeydown);
});

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown);
});
</script>

<style scoped lang="scss">
@use "@/styles/mixins.scss" as *;

.stretchable-modal {
  &__overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(vw(5));
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: vw(20);
  }

  &__container {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  &__header {
    position: relative;
    height: vh(66);
    min-height: vh(66);
    background: url(../../assets/images/modal/大弹窗top切图.png) repeat-x;
    background-size: 100% vh(66);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 vw(60);
  }

  &__title {
    color: var(--text-white);
    font-size: fs(20);
    font-family: SourceHanSansCN-Bold, sans-serif;
    font-weight: bold;
    text-align: center;
    margin: 0;
  }

  &__close {
    position: absolute;
    top: 34px;
    right: 34px;
    transform: translateY(-50%);
    width: vw(32);
    height: vw(32);
    background: transparent;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
    z-index: 10;
    padding: 0;

    &:hover {
      opacity: 0.8;
      transform: translateY(-50%) scale(1.1);
    }

    &:active {
      transform: translateY(-50%) scale(0.95);
    }

    .close-icon {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }

  &__body {
    flex: 1;
    background: url(../../assets/images/modal/大弹窗mid切图.png) repeat;
    background-size: 100% vh(66);
    overflow-y: auto;
    overflow-x: hidden;
    padding: vw(20) vw(30);

    // 自定义滚动条样式
    &::-webkit-scrollbar {
      width: vw(6);
    }

    &::-webkit-scrollbar-track {
      background: rgba(255, 255, 255, 0.1);
      border-radius: vw(3);
    }

    &::-webkit-scrollbar-thumb {
      background: var(--primary-color);
      border-radius: vw(3);

      &:hover {
        background: var(--primary-light);
      }
    }
  }

  &__footer {
    height: vh(66);
    min-height: vh(66);
    background: url(../../assets/images/modal/大弹窗bottom切图.png) repeat-x;
    background-size: 100% vh(66);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 vw(30);
  }
}

// 弹窗淡入淡出动画
.popup-fade-enter-active,
.popup-fade-leave-active {
  transition: opacity 0.3s ease;

  .stretchable-modal__container {
    transition: transform 0.3s ease, opacity 0.3s ease;
  }
}

.popup-fade-enter-from,
.popup-fade-leave-to {
  opacity: 0;

  .stretchable-modal__container {
    transform: scale(0.9);
    opacity: 0;
  }
}
</style>
