<template>
  <div v-show="visible" class="smart-dialog" :style="dialogStyle" @mousedown="bringToFront" @dblclick="handleDoubleClick">
    <div class="dialog-header" :class="{ 'is-draggable': draggable }" @mousedown="startDrag" v-if="title">
      <div class="title-content">
        <slot name="header">
          <span class="title">{{ title }}</span>
        </slot>
      </div>
      <span v-if="showClose" class="close-btn" @click.stop="close">✕</span>
    </div>
    <div v-else class="dialog-header not-title" :class="{ 'is-draggable': draggable }" @mousedown="startDrag"></div>

    <div v-if="title && false" class="dialog-divider"></div>

    <div class="dialog-body" :class="{ 'no-padding': noPadding }">
      <slot></slot>
    </div>

    <div v-if="resizable" class="resize-handle" @mousedown.prevent="startResize"></div>
  </div>
</template>

<script>

let globalZIndex = 2000;

// 在这里定义你的大屏设计稿基准宽度 (通常是 1920)
const DESIGN_WIDTH = 1920; 

export default {
  name: 'SmartDialog',
  props: {
    id: { type: [String, Number], required: true },
    visible: { type: Boolean, default: false },
    title: { type: String, default: '提示' },
    
    center: { type: Boolean, default: true },
    position: { type: Object, default: () => ({ x: 0, y: 0 }) }, 
    
    showClose: { type: Boolean, default: true },
    draggable: { type: Boolean, default: true }, 
    resizable: { type: Boolean, default: true }, 
    noPadding: { type: Boolean, default: false }, 

    defaultWidth: { type: [Number, String], default: 350 },
    defaultHeight: { type: [Number, String], default: 250 },
    minWidth: { type: Number, default: 200 },
    minHeight: { type: Number, default: 150 },
    enableDblclickExpand: { type: Boolean, default: false }, 
  },
  data() {
    return {
      x: 0,
      y: 0,
      w: 0,
      h: 0,
      currentScale: 1, 
      zIndex: globalZIndex,
      isDragging: false,
      isResizing: false,
      dragOffset: { x: 0, y: 0 },
      resizeStart: { x: 0, y: 0, w: 0, h: 0 }
    };
  },
  computed: {
    dialogStyle() {
      return {
        left: `${this.x}px`,
        top: `${this.y}px`,
        width: `${this.w}px`,
        height: `${this.h}px`,
        zIndex: this.zIndex,
        cursor: this.enableDblclickExpand ? 'pointer' : 'default'
      };
    }
  },
  created() {
    // 初始化时获取真实的缩放比例
    this.currentScale = this.getRealScale();
    this.w = this._parseSize(this.defaultWidth, window.innerWidth);
    this.h = this._parseSize(this.defaultHeight, window.innerHeight);
  },
  mounted() {
    window.addEventListener('resize', this._onWindowResize);
    if (this.visible) {
      this.bringToFront();
      this.calculatePosition();
    }
  },
  watch: {
    visible(newVal) {
      if (newVal) {
        this.bringToFront();
        this.calculatePosition();
      }
    },
    position: {
      deep: true,
      handler() {
        if (this.visible && !this.center) {
          this.calculatePosition();
        }
      }
    }
  },
  methods: {
    // 处理整个弹窗的双击事件
    handleDoubleClick(e) {
      // 1. 如果没开启这个功能，直接无视
      if (!this.enableDblclickExpand) return;
      
      // 2. 防误触：如果双击的是关闭按钮或者拉伸把手，不要触发
      if (e.target.classList.contains('close-btn') || e.target.classList.contains('resize-handle')) {
        return; 
      }

      // 3. 告诉外层父组件：“我被双击了，请处理下一步”
      this.$emit('expand', this.id); 
    },
    // 弹窗自己实时计算当前屏幕相当于设计稿的缩放比例
    getRealScale() {
      return window.innerWidth / DESIGN_WIDTH;
    },

    _parseSize(value, base) {
      if (typeof value === 'string' && value.endsWith('%')) {
        return Math.round((parseFloat(value) / 100) * base);
      }
      // 使用内部实时计算的 scale，绝不出错
      const scale = this.getRealScale();
      return Number(value) * scale;
    },
    
    _onWindowResize() {
      setTimeout(() => {
        // 重新获取当前最新比例
        const newScale = this.getRealScale();
        const scaleRatio = newScale / this.currentScale;
        
        // 重新按比例计算宽高
        this.w = this._parseSize(this.defaultWidth, window.innerWidth);
        this.h = this._parseSize(this.defaultHeight, window.innerHeight);

        if (this.visible) {
          // 保持相对位置等比缩放
          this.x = this.x * scaleRatio;
          this.y = this.y * scaleRatio;

          if (this.x + this.w > window.innerWidth) this.x = window.innerWidth - this.w;
          if (this.y + this.h > window.innerHeight) this.y = window.innerHeight - this.h;
          if (this.x < 0) this.x = 0;
          if (this.y < 0) this.y = 0;
        }
        
        this.currentScale = newScale;
      }, 50); 
    },
    
    close() {
      this.$emit('update:visible', false);
      this.$emit('close');
    },
    
    bringToFront() {
      globalZIndex++;
      this.zIndex = globalZIndex;
    },
    
    calculatePosition() {
      this.$nextTick(() => {
        const winWidth = window.innerWidth;
        const winHeight = window.innerHeight;
        const scale = this.getRealScale();
        
        let targetX = 0;
        let targetY = 0;

        if (this.center) {
          targetX = Math.max(0, (winWidth - this.w) / 2);
          targetY = Math.max(0, (winHeight - this.h) / 2);
        } else {
          targetX = (this.position.x || 0) * scale;
          targetY = (this.position.y || 0) * scale;
        }

        const offsetStep = 20 * scale; 
        let collision = true;
        let attempts = 0; 

        const existingDialogs = document.querySelectorAll('.smart-dialog');

        while (collision && attempts < 15) {
          collision = false;
          for (let i = 0; i < existingDialogs.length; i++) {
            const el = existingDialogs[i];
            if (el === this.$el || el.style.display === 'none') continue; 

            const rect = el.getBoundingClientRect();
            if (Math.abs(rect.left - targetX) < 2 && Math.abs(rect.top - targetY) < 2) {
              collision = true;
              break; 
            }
          }
          if (collision) {
            targetX += offsetStep;
            targetY += offsetStep;
            attempts++;
          }
        }

        if (targetX + this.w > winWidth) targetX = winWidth - this.w - 10;
        if (targetY + this.h > winHeight) targetY = winHeight - this.h - 10;

        this.x = Math.max(0, targetX);
        this.y = Math.max(0, targetY);
      });
    },

    startDrag(e) {
      if (!this.draggable || e.target.classList.contains('close-btn')) return;
      this.isDragging = true;
      this.dragOffset.x = e.clientX - this.x;
      this.dragOffset.y = e.clientY - this.y;
      document.addEventListener('mousemove', this.onDrag);
      document.addEventListener('mouseup', this.stopDrag);
    },
    onDrag(e) {
      if (!this.isDragging) return;
      let newX = e.clientX - this.dragOffset.x;
      let newY = e.clientY - this.dragOffset.y;
      
      const scale = this.getRealScale();
      const safeHeaderHeight = 40 * scale;
      
      this.x = Math.max(0, Math.min(newX, window.innerWidth - this.w));
      this.y = Math.max(0, Math.min(newY, window.innerHeight - safeHeaderHeight)); 
    },
    stopDrag() {
      this.isDragging = false;
      document.removeEventListener('mousemove', this.onDrag);
      document.removeEventListener('mouseup', this.stopDrag);
    },

    startResize(e) {
      if (!this.resizable) return;
      this.isResizing = true;
      this.resizeStart = { x: e.clientX, y: e.clientY, w: this.w, h: this.h };
      document.addEventListener('mousemove', this.onResize);
      document.addEventListener('mouseup', this.stopResize);
    },
    onResize(e) {
      if (!this.isResizing) return;
      const deltaX = e.clientX - this.resizeStart.x;
      const deltaY = e.clientY - this.resizeStart.y;
      
      const scale = this.getRealScale();
      const currentMinWidth = this.minWidth * scale;
      const currentMinHeight = this.minHeight * scale;
      
      this.w = Math.max(currentMinWidth, this.resizeStart.w + deltaX);
      this.h = Math.max(currentMinHeight, this.resizeStart.h + deltaY);
    },
    stopResize() {
      this.isResizing = false;
      document.removeEventListener('mousemove', this.onResize);
      document.removeEventListener('mouseup', this.stopResize);
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this._onWindowResize);
    document.removeEventListener('mousemove', this.onDrag);
    document.removeEventListener('mouseup', this.stopDrag);
    document.removeEventListener('mousemove', this.onResize);
    document.removeEventListener('mouseup', this.stopResize);
  }
};
</script>

<style scoped>
/* =========== CSS 保持不变 =========== */
.smart-dialog {
  position: fixed;
  background: radial-gradient(circle at 20% 0%, rgba(40,120,200,0.2) 0%, rgba(20,60,130,0.4) 70%);
  box-shadow: inset 0px 0px 0.625rem 0px rgba(88, 146, 255, 0.4), inset 1.25rem 0px 1.875rem -0.625rem rgba(88, 146, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  user-select: none;
}

.dialog-header {
  height: auto;
  background: transparent;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 10px 0px 10px;
}

.dialog-header.not-title {
  padding: 0;
}

.dialog-header.is-draggable {
  cursor: move;
  height: 10px;
}

.title-content {
  flex: 1;
  min-width: 0;
}

.title {
  color: #ffffff;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 1px;
}

.close-btn {
  cursor: pointer;
  color: #ffffff;
  font-size: 16px;
  line-height: 1;
  font-weight: 300;
  opacity: 0.8;
  transition: all 0.2s;
}

.close-btn:hover {
  opacity: 1;
  transform: scale(1.1);
}

.dialog-divider {
  height: 1px;
  background-color: rgba(255, 255, 255, 0.3);
  margin: 0 20px;
}

.dialog-body {
  flex: 1;
  min-height: 0;
  padding: 20px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.dialog-body.no-padding {
  padding: 0;
  color: #e2e8f0;
  overflow: hidden;
  cursor: default;
}

.resize-handle {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 16px;
  height: 16px;
  cursor: se-resize;
  background: linear-gradient(135deg, transparent 50%, rgba(255, 255, 255, 0.2) 50%);
}
</style>