<template>
  <div class="drag-resize-container" ref="containerRef">
    <!-- 可拖拽调整的元素 -->
    <div
      class="draggable-element"
      ref="elementRef"
      :style="{
        left: `${position.x}px`,
        top: `${position.y}px`,
        width: `${size.width}px`,
        height: `${size.height}px`
      }"
      @mousedown="startDrag"
    >
      <!-- 元素内容区 -->
      <div class="element-content">
        <slot>可拖拽调整的元素</slot>
      </div>
      <!-- 右下角调整大小的控制点 -->
      <div class="resize-handle" @mousedown="startResize"></div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DragResizeBox',
  props: {
    // 初始位置
    initPosition: {
      type: Object,
      default: () => ({ x: 100, y: 100 })
    },
    // 初始尺寸
    initSize: {
      type: Object,
      default: () => ({ width: 200, height: 150 })
    },
    // 移除容器尺寸限制（保留prop但默认值改为屏幕尺寸）
    containerSize: {
      type: Object,
      default: () => ({ 
        width: window.innerWidth, 
        height: window.innerHeight 
      })
    },
    // 元素最小尺寸
    minSize: {
      type: Object,
      default: () => ({ width: 100, height: 80 })
    },
    // 用于localStorage存储的唯一标识
    storageKey: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      // 当前位置
      position: { x: 0, y: 0 },
      // 当前尺寸
      size: { width: 0, height: 0 },
      // 拖拽状态
      isDragging: false,
      // 调整大小状态
      isResizing: false,
      // 鼠标初始位置
      startMouse: { x: 0, y: 0 },
      // 元素初始状态
      startState: { x: 0, y: 0, width: 0, height: 0 }
    };
  },
  mounted() {
    // 初始化位置和尺寸（优先从localStorage读取）
    this.initFromStorage();
    // 监听全局鼠标移动和松开事件
    document.addEventListener('mousemove', this.handleMouseMove);
    document.addEventListener('mouseup', this.handleMouseUp);
    // 监听窗口大小变化，更新屏幕尺寸
    window.addEventListener('resize', this.updateScreenSize);
  },
  beforeDestroy() {
    // 移除全局事件监听，防止内存泄漏
    document.removeEventListener('mousemove', this.handleMouseMove);
    document.removeEventListener('mouseup', this.handleMouseUp);
    window.removeEventListener('resize', this.updateScreenSize);
  },
  methods: {
    /**
     * 从localStorage初始化位置和尺寸
     * 有key时优先读取存储值，无则使用props传入的初始值
     */
    initFromStorage() {
      if (this.storageKey) {
        try {
          const storageKey = `dnd-ps-${this.storageKey}`;
          const storedData = localStorage.getItem(storageKey);
          
          if (storedData) {
            const { position, size } = JSON.parse(storedData);
            // 验证存储的数据是否合法，防止异常值
            const isValidPosition = position && typeof position.x === 'number' && typeof position.y === 'number';
            const isValidSize = size && typeof size.width === 'number' && typeof size.height === 'number';
            
            if (isValidPosition && isValidSize) {
              // 使用存储的位置和尺寸（确保不小于最小尺寸）
              this.position = {
                x: Math.max(0, position.x),
                y: Math.max(0, position.y)
              };
              this.size = {
                width: Math.max(this.minSize.width, size.width),
                height: Math.max(this.minSize.height, size.height)
              };
              return;
            }
          }
        } catch (error) {
          console.warn('读取拖拽元素存储数据失败，使用默认值:', error);
        }
      }
      
      // 无存储数据或存储异常时，使用props初始值
      this.position = { ...this.initPosition };
      this.size = { ...this.initSize };
    },

    /**
     * 将当前位置和尺寸保存到localStorage
     */
    saveToStorage() {
      if (this.storageKey) {
        try {
          const storageKey = `dnd-ps-${this.storageKey}`;
          const saveData = {
            position: { ...this.position },
            size: { ...this.size },
            updateTime: new Date().getTime()
          };
          console.log('saveData', saveData);
          localStorage.setItem(storageKey, JSON.stringify(saveData));
          // 触发存储成功事件
          this.$emit('save-success', saveData);
        } catch (error) {
          console.error('保存拖拽元素数据失败:', error);
          this.$emit('save-fail', error);
        }
      }
    },

    /**
     * 更新屏幕尺寸（窗口大小变化时）
     */
    updateScreenSize() {
      this.containerSize = {
        width: window.innerWidth,
        height: window.innerHeight
      };
    },

    /**
     * 开始拖拽（移动位置）
     */
    startDrag(e) {
      // 阻止事件冒泡，避免和调整大小冲突
      if (e.target.classList.contains('resize-handle')) return;
      
      this.isDragging = true;
      // 记录鼠标初始位置
      this.startMouse = { x: e.clientX, y: e.clientY };
      // 记录元素初始位置
      this.startState = {
        x: this.position.x,
        y: this.position.y,
        width: this.size.width,
        height: this.size.height
      };
      // 更改鼠标样式
      document.body.style.cursor = 'move';
    },

    /**
     * 开始调整大小
     */
    startResize(e) {
      e.stopPropagation(); // 阻止事件冒泡
      this.isResizing = true;
      // 记录鼠标初始位置
      this.startMouse = { x: e.clientX, y: e.clientY };
      // 记录元素初始尺寸
      this.startState = {
        x: this.position.x,
        y: this.position.y,
        width: this.size.width,
        height: this.size.height
      };
      // 更改鼠标样式
      document.body.style.cursor = 'se-resize';
    },

    /**
     * 处理鼠标移动
     */
    handleMouseMove(e) {
      if (this.isDragging) {
        // 计算鼠标移动的偏移量
        const dx = e.clientX - this.startMouse.x;
        const dy = e.clientY - this.startMouse.y;
        
        // 核心修改：移除容器边界限制，仅限制不超出屏幕左侧/顶部（右侧/底部可任意移动）
        this.position.x = Math.max(0, this.startState.x + dx);
        this.position.y = Math.max(0, this.startState.y + dy);
        
        // 触发位置变化事件
        this.$emit('position-change', { ...this.position });
      }

      if (this.isResizing) {
        // 计算鼠标移动的偏移量
        const dx = e.clientX - this.startMouse.x;
        const dy = e.clientY - this.startMouse.y;
        
        // 调整大小仅限制最小尺寸，不限制屏幕边界
        this.size.width = Math.max(this.minSize.width, this.startState.width + dx);
        this.size.height = Math.max(this.minSize.height, this.startState.height + dy);
        
        // 触发尺寸变化事件
        this.$emit('size-change', { ...this.size });
      }
    },

    /**
     * 处理鼠标松开
     */
    handleMouseUp() {
      // 重置状态
      this.isDragging = false;
      this.isResizing = false;
      // 恢复鼠标样式
      document.body.style.cursor = 'default';
      
      // 保存当前状态到localStorage（有key时）
      this.saveToStorage();
      
      // 触发结束事件
      this.$emit('drag-end', { position: { ...this.position }, size: { ...this.size } });
    }
  }
};
</script>

<style scoped>
/* 容器样式：改为全屏且无视觉样式 */
.drag-resize-container {
  position: fixed; /* 固定定位覆盖整个屏幕 */
  top: 0; 
  left: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none; /* 容器不拦截鼠标事件，不影响页面其他元素 */
  box-sizing: border-box;
}

/* 可拖拽元素样式：fixed定位确保基于屏幕移动 */
.draggable-element {
  position: fixed;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  user-select: none; /* 禁止文本选中 */
  box-sizing: border-box;
  overflow: hidden;
  pointer-events: auto; /* 元素本身响应鼠标事件 */
  z-index: 99999; /* 确保元素在最上层 */
  background-color: #ffffff; /* 添加背景色，提升可视性 */
}

/* 元素内容区 */
.element-content {
  height: calc(100% - 20px);
  padding: 10px;
  cursor: move;
}

/* 调整大小控制点 */
.resize-handle {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 20px;
  height: 20px;
  background-color: #1e88e5;
  cursor: se-resize;
  border-top-left-radius: 4px;
}

/* 控制点hover效果 */
.resize-handle:hover {
  background-color: #1976d2;
}
</style>