<template>
  <!--
    地图标记点提示框组件

    用于在地图上以屏幕坐标锚定显示的轻量级信息提示框。
    父组件负责：
    - 将地图实体的经纬度转换为屏幕坐标 (x, y)
    - 通过 visible prop 控制显示/隐藏

    本组件专注于：
    - 提供视觉外壳（背景、四角装饰、标题区、关闭按钮）
    - 淡入淡出动画效果
    - 通过插槽支持灵活的内容定制
  -->
  <transition name="tooltip-fade">
    <div
      v-if="visible"
      class="map-tooltip"
      :style="wrapperStyle"
      role="dialog"
      :aria-label="title || '地图标记提示框'"
    >
      <div class="map-tooltip__panel">
        <!-- 四个角的装饰图片 -->
        <img
          class="map-tooltip__corner map-tooltip__corner--top-left"
          :src="topLeftImg"
          alt=""
          aria-hidden="true"
        />
        <img
          class="map-tooltip__corner map-tooltip__corner--top-right"
          :src="topRightImg"
          alt=""
          aria-hidden="true"
        />
        <img
          class="map-tooltip__corner map-tooltip__corner--bottom-left"
          :src="bottomLeftImg"
          alt=""
          aria-hidden="true"
        />
        <img
          class="map-tooltip__corner map-tooltip__corner--bottom-right"
          :src="bottomRightImg"
          alt=""
          aria-hidden="true"
        />

        <!-- 主体背景和内容区域 -->
        <div class="map-tooltip__background">
          <!-- 标题区域 -->
          <div class="map-tooltip__header">
            <div class="map-tooltip__header-main">
              <!--
                标题插槽优先级高于 props
                默认展示：icon + title
                可通过具名插槽 #title 完全自定义
              -->
              <slot name="title">
                <div class="map-tooltip__title-inner">
                  <span
                    v-if="title"
                    class="map-tooltip__title-text"
                  >
                    {{ title }}
                  </span>
                  <!-- 视频图标按钮 -->
                  <button
                    v-if="showVideoIcon && videoIconSrc"
                    type="button"
                    class="map-tooltip__video-btn"
                    :aria-label="videoIconAriaLabel"
                    @click.stop="emit('video-icon-click')"
                  >
                    <img
                      :src="videoIconSrc"
                      alt=""
                      class="map-tooltip__video-icon"
                    />
                  </button>
                </div>
              </slot>
            </div>

            <!-- 关闭按钮 -->
            <button
              v-if="closable"
              type="button"
              class="map-tooltip__close-btn"
              aria-label="关闭提示框"
              @click="handleClose"
            >
              <span class="map-tooltip__close-icon" />
            </button>
          </div>

          <!-- 标题下方的分割线 -->
          <div class="map-tooltip__title-divider">
            <img
              :src="titleSpliteImg"
              alt=""
              aria-hidden="true"
            />
          </div>

          <!-- 内容区域：完全由插槽控制 -->
          <div class="map-tooltip__content">
            <slot />
          </div>

          <!-- 操作按钮区域 -->
          <div v-if="$slots.actions" class="map-tooltip__actions">
            <slot name="actions" />
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script setup>
import { computed } from 'vue'

// 导入装饰图片资源
import topLeftImg from '../../assets/images/Tooltip/topLeft.png'
import topRightImg from '../../assets/images/Tooltip/topRight.png'
import bottomLeftImg from '../../assets/images/Tooltip/bottomLeft.png'
import bottomRightImg from '../../assets/images/Tooltip/bottomRight.png'
import titleSpliteImg from '../../assets/images/Tooltip/titleSplite.png'

/**
 * Props 定义
 */
const props = defineProps({
  /**
   * 控制提示框的显示/隐藏
   * 支持 v-model:visible 双向绑定
   */
  visible: {
    type: Boolean,
    default: false
  },

  /**
   * 屏幕 X 坐标（像素），相对于地图容器左上角
   * 提示框将以底部中心点锚定到此坐标
   */
  x: {
    type: Number,
    default: 0
  },

  /**
   * 屏幕 Y 坐标（像素），相对于地图容器左上角
   * 提示框将以底部中心点锚定到此坐标
   */
  y: {
    type: Number,
    default: 0
  },

  /**
   * X 轴偏移量（像素）
   * 用于微调提示框相对于标记点的位置
   */
  offsetX: {
    type: Number,
    default: 0
  },

  /**
   * Y 轴偏移量（像素）
   * 默认向上偏移 16px，使提示框稍微悬浮在标记点上方
   */
  offsetY: {
    type: Number,
    default: -16
  },

  /**
   * 标题文本
   * 当使用 #title 插槽时，此 prop 会被忽略
   */
  title: {
    type: String,
    default: ''
  },

  /**
   * 标题左侧图标的图片路径
   * 通常由父组件通过 import 引入后传递
   */
  icon: {
    type: String,
    default: ''
  },

  /**
   * 提示框的 z-index 值
   * 确保提示框显示在地图图层之上，但低于全屏弹窗
   */
  zIndex: {
    type: Number,
    default: 20
  },

  /**
   * 是否显示关闭按钮
   */
  closable: {
    type: Boolean,
    default: true
  },

  /**
   * 是否在标题右侧显示视频图标
   */
  showVideoIcon: {
    type: Boolean,
    default: false
  },

  /**
   * 视频图标的图片路径
   */
  videoIconSrc: {
    type: String,
    default: ''
  },

  /**
   * 视频图标的无障碍标签
   */
  videoIconAriaLabel: {
    type: String,
    default: '打开视频监控'
  }
})

/**
 * Events 定义
 */
const emit = defineEmits([
  /**
   * 用户点击关闭按钮时触发
   */
  'close',
  /**
   * 支持 v-model:visible 双向绑定
   */
  'update:visible',
  /**
   * 用户点击视频图标时触发
   */
  'video-icon-click'
])

/**
 * 计算提示框的定位样式
 * 使用 transform: translate(-50%, -100%) 实现底部中心点锚定
 */
const wrapperStyle = computed(() => {
  const left = props.x + props.offsetX
  const top = props.y + props.offsetY

  return {
    left: `${left}px`,
    top: `${top}px`,
    zIndex: props.zIndex
  }
})

/**
 * 处理关闭操作
 * 同时触发 close 事件和 update:visible 事件
 */
const handleClose = () => {
  emit('close')
  emit('update:visible', false)
}
</script>

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

/**
 * 提示框根容器
 * 使用绝对定位 + transform 实现锚定效果
 */
.map-tooltip {
  position: absolute;
  // 底部中心点对齐到 (x, y) 坐标
  transform: translate(-50%, -100%);
  // 确保提示框可交互（覆盖父容器可能的 pointer-events: none）
  pointer-events: auto;
}

/**
 * 内部面板容器
 * 用于控制提示框宽度和缩放动画
 */
.map-tooltip__panel {
  position: relative;
  width: vw(320);
  // 确保四角装饰不会被裁剪
  // padding: vw(10);
}

/**
 * 主体背景区域
 * 使用设计提供的背景图
 */
.map-tooltip__background {
  position: relative;
  padding: vh(14) vw(18);
  background: url('../../assets/images/Tooltip/弹窗bg.png') no-repeat;
  background-size: 100% 100%;
  border-radius: vw(8);
  box-shadow: 0 vw(8) vw(24) rgba(0, 0, 0, 0.5);
}

/**
 * 四角装饰图片
 * 使用绝对定位 + transform 贴在主体背景的四个角
 */
.map-tooltip__corner {
  position: absolute;
  // width: vw(20);
  // height: vw(20); // 使用 vw 保持正方形
  pointer-events: none; // 装饰元素不响应鼠标事件
  z-index: 1; // 确保显示在背景之上

  &--top-left {
    top: 0;
    left: 0;
    // transform: translate(-30%, -30%);
  }

  &--top-right {
    top: 0;
    right: 0;
    // transform: translate(30%, -30%);
  }

  &--bottom-left {
    bottom: 0;
    left: 0;
    // transform: translate(-30%, 30%);
  }

  &--bottom-right {
    bottom: 0;
    right: 0;
    // transform: translate(30%, 30%);
  }
}

/**
 * 标题区域
 * 包含标题内容和关闭按钮
 */
.map-tooltip__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: vw(12);
  min-height: vh(24); // 确保即使没有标题也有最小高度
}

.map-tooltip__header-main {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0; // 允许文本溢出处理
}

.map-tooltip__title-inner {
  display: flex;
  align-items: center;
  gap: vw(10);
}

.map-tooltip__icon {
  width: vw(20);
  height: vw(20); // 使用 vw 保持正方形
  flex-shrink: 0;
}

.map-tooltip__title-text {
  color: var(--text-white);
  font-size: fs(16);
  font-family: SourceHanSansCN-Bold, sans-serif;
  font-weight: 700;
  line-height: 1.4;
}

/**
 * 视频图标按钮
 * 显示在标题右侧，用于打开视频监控
 */
.map-tooltip__video-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: vw(24);
  height: vw(24);
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  flex-shrink: 0;
  transition: all 0.3s ease;

  &:hover {
    transform: scale(1.15);
    filter: brightness(1.2);
  }

  &:active {
    transform: scale(1.05);
  }

  &:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
    border-radius: 2px;
  }
}

.map-tooltip__video-icon {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  pointer-events: none;
}

/**
 * 关闭按钮
 * 使用纯 CSS 实现 X 图标，避免额外的图片资源
 */
.map-tooltip__close-btn {
  width: vw(24);
  height: vw(24); // 使用 vw 保持正方形
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 0.25s ease, opacity 0.25s ease;

  &:hover {
    transform: rotate(90deg);
    opacity: 0.8;
  }

  &:active {
    transform: scale(0.9) rotate(90deg);
  }
}

/**
 * 关闭按钮的 X 图标
 * 使用伪元素实现两条交叉的线
 */
.map-tooltip__close-icon {
  position: relative;
  width: 60%;
  height: 60%;
}

.map-tooltip__close-icon::before,
.map-tooltip__close-icon::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: vw(2);
  background-color: var(--text-white);
  transform-origin: center;
  border-radius: vw(1);
}

.map-tooltip__close-icon::before {
  transform: translate(-50%, -50%) rotate(45deg);
}

.map-tooltip__close-icon::after {
  transform: translate(-50%, -50%) rotate(-45deg);
}

/**
 * 标题下方的分割线
 */
.map-tooltip__title-divider {
  margin: vh(8) 0 vh(12);

  img {
    display: block;
    width: 100%;
    height: vh(2);
    object-fit: cover;
  }
}

/**
 * 内容区域
 * 完全由插槽控制，这里只提供基础布局
 */
.map-tooltip__content {
  display: flex;
  flex-direction: column;
  gap: vh(6);
}

/**
 * 操作按钮区域
 * 用于显示"连线"、"联动"等交互按钮
 */
.map-tooltip__actions {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: vh(16);
  padding-top: vh(12);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/**
 * 淡入淡出动画
 * 结合缩放效果，提升视觉体验
 */
.tooltip-fade-enter-active,
.tooltip-fade-leave-active {
  transition: opacity 0.25s ease;

  .map-tooltip__panel {
    transition: transform 0.25s ease;
  }
}

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

  .map-tooltip__panel {
    transform: scale(0.92);
  }
}
</style>
