<template>
  <div class="panel bg-white overflow-hidden" 
       :style="{ width: '100%', height: '100%' }"
       :data-panel-id="id">
    <div class="flex flex-col h-full">
      <!-- 标题栏 -->
      <div class="title-bar h-6 bg-[#435d9c] text-white px-2 flex items-center justify-between select-none cursor-move"
           @mousedown="onDragStart">
        <div class="flex items-center">
          <span class="text-xs">{{ title }}</span>
        </div>
        <div class="title-bar-buttons flex items-center gap-0.5">
          <button class="button-icon p-[2px] rounded hover:opacity-100 opacity-80" 
                  @click.stop="onToggleCollapse" 
                  @mousedown.stop
                  aria-label="折叠/展开">
            <!-- 向下小三角，使用内联SVG避免样式作用域问题 -->
            <svg width="11" height="11" viewBox="0 0 11 11" aria-hidden="true">
              <polygon points="5.5,8 2,3.5 9,3.5" fill="#cbd6ff" />
            </svg>
          </button>
          <button class="button-icon p-[2px] rounded hover:opacity-100 opacity-80" 
                  @click.stop="onMaximize" 
                  @mousedown.stop
                  :aria-label="maximized ? '还原' : '最大化'">
            <!-- 最大化图标 -->
            <template v-if="!maximized">
              <!-- 最大化图标：外框 + 内部线条 -->
              <svg class="icon-square-svg" width="11" height="11" viewBox="0 0 11 11" aria-hidden="true">
              <rect x="0.5" y="0.5" width="10" height="10" fill="#cbd6ff" stroke="#8ea3d8" stroke-width="1" />
              <rect x="3" y="3" width="5" height="1" fill="#b8c6ff" />
              <rect x="1" y="3" width="8.5" height="6.5" fill="#435d9c" />
            </svg>
            </template>
            <!-- 还原图标 -->
            <template v-else>
              <svg class="icon-square-svg" width="11" height="11" viewBox="0 0 11 11" aria-hidden="true">
                  <path
                    fill="#CED4DD"
                    fill-rule="evenodd"
                    clip-rule="evenodd"
                    d="M1 4 L4 4 L4 1 L11 1 L11 8 L8 8 L8 11 L1 11 Z
                    M5 4 L5 3 L10 3 L10 7 L8 7 L8 4 Z
                    M2 6 L12.6 5 L7 6 L7 10 L2 10 Z" />
              </svg>
            </template>
          </button>
          <button class="button-icon p-[2px] rounded hover:opacity-100 opacity-80" 
                  @click.stop="onClose" 
                  @mousedown.stop
                  aria-label="关闭">
            <!-- 关闭图标（X），内联SVG确保1px线条 -->
            <svg width="11" height="11" viewBox="0 0 11 11" aria-hidden="true">
              <line x1="2" y1="2" x2="9" y2="9" stroke="#e6efff" stroke-width="1" />
              <line x1="2" y1="9" x2="9" y2="2" stroke="#e6efff" stroke-width="1" />
            </svg>
          </button>
        </div>
      </div>

      <!-- 工具栏：位于标题栏下方，右侧扩展钮 -->
      <div class="toolbar h-6 bg-[#d5e2f6] text-[#2c3e7a] px-2 flex items-center justify-between border-b border-[#c7d2ea]">
        <div class="toolbar-left flex items-center gap-2">
          <span class="text-xs">工具栏</span>
          <button v-if="toolbarExpanded" class="toolbar-button px-2 py-0.5 text-xs bg-white/60 rounded hover:bg-white">示例按钮</button>
        </div>
        <button class="toolbar-toggle px-2 py-0.5 text-xs rounded hover:bg-white/40" 
                @click="onToggleToolbar" 
                aria-label="展开工具栏">
          <i class="fa-solid" :class="toolbarExpanded ? 'fa-angles-left' : 'fa-angles-right'"></i>
        </button>
      </div>

      <!-- 内容区：可折叠，添加滚动条 -->
      <div class="content-area bg-[#f5f7fb] flex-1 p-4 overflow-auto min-h-0" v-show="!collapsed">
        <div v-if="content" class="panel-content">
          <div class="mb-4">
            <h3 class="text-lg font-bold mb-2" :style="{ color: content.color }">
              {{ content.title }}
            </h3>
            <p class="text-sm text-gray-600 mb-3">
              类型：{{ content.type }} | 创建时间：{{ content.timestamp }}
            </p>
          </div>
          
          <div class="grid grid-cols-1 gap-3">
            <div 
              v-for="(item, index) in content.data" 
              :key="item.id"
              class="data-item p-3 border rounded-lg shadow-sm"
              :style="{ 
                borderLeftColor: content.color,
                borderLeftWidth: '4px'
              }"
            >
              <div class="flex justify-between items-center">
                <span class="font-medium">{{ item.label }}</span>
                <span class="text-sm font-bold" :style="{ color: content.color }">
                  {{ item.value }}
                </span>
              </div>
            </div>
          </div>
        </div>
        <div v-else class="text-gray-500 text-center">
          <p>暂无内容</p>
          <div class="mt-2 text-xs">面板ID: {{ id }} - 标题: {{ title }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { defineProps, onMounted, onUnmounted } from 'vue';
import {
  eventBus, 
  EVENT_TYPES, 
  emitEvent, 
  onEvent
} from './eventBus';

// 定义组件属性
const props = defineProps({
  id: {
    type: String,
    required: true
  },
  title: {
    type: String,
    default: ''
  },
  x: {
    type: Number,
    default: 0
  },
  y: {
    type: Number,
    default: 0
  },
  width: {
    type: Number,
    default: 300
  },
  height: {
    type: Number,
    default: 180
  },
  collapsed: {
    type: Boolean,
    default: false
  },
  toolbarExpanded: {
    type: Boolean,
    default: false
  },
  maximized: {
    type: Boolean,
    default: false
  },
  content: {
    type: Object,
    default: null
  },
  // 移除areaId属性，因为面板会被拖拽到不同区域
  // 改为通过DOM动态获取当前所在区域
});

// 事件订阅管理 - 使用Set避免key冲突，并添加唯一标识符
const subscriptions = new Set();
const subscriptionRegistry = new Map(); // 用于追踪订阅详细信息

// 动态获取当前面板所在的Area ID
const getCurrentAreaId = () => {
  // 通过DOM向上查找最近的Area容器
  const panelElement = document.querySelector(`[data-panel-id="${props.id}"]`);
  if (panelElement) {
    const areaElement = panelElement.closest('[data-area-id]');
    if (areaElement) {
      return areaElement.getAttribute('data-area-id');
    }
  }
  
  // 备用方法：通过父组件查找
  // 向上查找vs-area容器
  const parentElement = document.querySelector(`[data-panel-id="${props.id}"]`)?.parentElement;
  if (parentElement) {
    const areaElement = parentElement.closest('.vs-area');
    if (areaElement) {
      return areaElement.getAttribute('data-area-id');
    }
  }
  
  console.warn(`[Panel:${props.id}] 无法找到当前所在的Area，Panel可能未正确挂载`);
  return null;
};

// 事件处理函数 - 使用事件总线
const onToggleCollapse = () => {
  console.log(`[Panel:${props.id}] 触发折叠/展开事件`)
  emitEvent(EVENT_TYPES.PANEL_TOGGLE_COLLAPSE, {
    panelId: props.id,
    areaId: getCurrentAreaId(),
    currentState: props.collapsed
  }, {
    source: { component: 'Panel', panelId: props.id }
  })
};

const onMaximize = () => {
  console.log(`[Panel:${props.id}] 触发最大化事件`)
  emitEvent(EVENT_TYPES.PANEL_MAXIMIZE, {
    panelId: props.id,
    areaId: getCurrentAreaId(),
    currentState: props.maximized
  }, {
    source: { component: 'Panel', panelId: props.id }
  })
};

const onClose = () => {
  // console.log(`[Panel:${props.id}] 触发关闭请求事件`)
  // 首先发送关闭请求，让父组件可以处理确认逻辑
  emitEvent(EVENT_TYPES.PANEL_CLOSE_REQUEST, {
    panelId: props.id,
    areaId: getCurrentAreaId(),
    panelTitle: props.title,
    requestTime: Date.now()
  }, {
    source: { component: 'Panel', panelId: props.id }
  })
};

const onToggleToolbar = () => {
  console.log(`[Panel:${props.id}] 触发工具栏切换事件`)
  emitEvent(EVENT_TYPES.PANEL_TOGGLE_TOOLBAR, {
    panelId: props.id,
    areaId: getCurrentAreaId(),
    currentState: props.toolbarExpanded
  }, {
    source: { component: 'Panel', panelId: props.id }
  })
};

// 拖拽相关状态
let isDragging = false
let currentDragId = null

// 全局内存泄漏保护机制
if (!window.__panelMemoryProtection) {
  window.__panelMemoryProtection = {
    // 存储所有面板组件实例追踪信息
    panelInstances: new Map(),
    
    // 定时检测内存泄漏（开发环境）
    startLeakDetection() {
      if (import.meta.env.DEV) {
        setInterval(() => {
          this.detectMemoryLeaks()
        }, 30000) // 每30秒检测一次
      }
    },
    
    // 检测内存泄漏
    detectMemoryLeaks() {
      const activePanels = window.__panelDragHandlers ? window.__panelDragHandlers.size : 0
      const registeredPanels = this.panelInstances.size
      
      if (activePanels !== registeredPanels) {
        console.warn(`[内存泄漏检测] 发现面板内存不一致 - 活动拖拽: ${activePanels}, 注册实例: ${registeredPanels}`)
        
        // 清理 orphaned handlers
        if (window.__panelDragHandlers && activePanels > 0) {
          window.__panelDragHandlers.forEach((handlers, panelId) => {
            if (!this.panelInstances.has(panelId)) {
              console.warn(`[内存泄漏检测] 清理orphaned handler: ${panelId}`)
              document.removeEventListener('mousemove', handlers.dragMoveHandler, false)
              document.removeEventListener('mouseup', handlers.dragEndHandler, false)
              document.removeEventListener('mouseleave', handlers.dragEndHandler, false)
              window.__panelDragHandlers.delete(panelId)
            }
          })
        }
      }
    },
    
    // 注册面板实例
    registerPanel(panelId) {
      this.panelInstances.set(panelId, {
        createdAt: Date.now(),
        lastActivity: Date.now()
      })
    },
    
    // 注销面板实例
    unregisterPanel(panelId) {
      this.panelInstances.delete(panelId)
    },
    
    // 更新活动状态
    updateActivity(panelId) {
      const panel = this.panelInstances.get(panelId)
      if (panel) {
        panel.lastActivity = Date.now()
      }
    }
  }
  
  // 启动内存泄漏检测
  window.__panelMemoryProtection.startLeakDetection()
}

/**
 * 添加Document拖拽事件监听器
 */
const addDocumentDragListeners = () => {
  // 移除可能存在的旧监听器
  cleanupDragEventListeners()
  
  // 使用组件实例标识符确保清理正确性
  const componentId = `panel_${props.id}`
  const dragMoveHandler = (e) => onDragMove(e)
  const dragEndHandler = (e) => onDragEnd(e)
  
  // 将处理函数绑定到组件作用域，避免匿名函数导致的清理问题
  if (!window.__panelDragHandlers) {
    window.__panelDragHandlers = new Map()
  }
  
  window.__panelDragHandlers.set(componentId, {
    dragMoveHandler,
    dragEndHandler
  })
  
  document.addEventListener('mousemove', dragMoveHandler, false)
  document.addEventListener('mouseup', dragEndHandler, false)
  document.addEventListener('mouseleave', dragEndHandler, false)
  
  if (import.meta.env.DEV) {
    console.log(`[Panel:${props.id}] Document拖拽事件监听器已添加: ${componentId}`)
  }
}

/**
 * 清理Document拖拽事件监听器
 */
const cleanupDragEventListeners = () => {
  try {
    const componentId = `panel_${props.id}`
    
    // 从全局拖拽处理函数映射中获取处理函数
    const handlers = window.__panelDragHandlers?.get(componentId)
    
    if (handlers) {
      // 使用正确的处理函数引用进行清理
      document.removeEventListener('mousemove', handlers.dragMoveHandler, false)
      document.removeEventListener('mouseup', handlers.dragEndHandler, false)
      document.removeEventListener('mouseleave', handlers.dragEndHandler, false)
      
      // 从映射中移除
      window.__panelDragHandlers.delete(componentId)
      
      // 清理映射，如果为空则删除整个映射
      if (window.__panelDragHandlers.size === 0) {
        delete window.__panelDragHandlers
      }
      
      if (import.meta.env.DEV) {
        console.log(`[Panel:${props.id}] Document拖拽事件监听器已清理: ${componentId}`)
      }
    }
    
    // 立即重置拖拽状态，确保清理完整性
    isDragging = false
    
  } catch (error) {
    console.warn(`[Panel:${props.id}] 清理拖拽事件监听器时出错:`, error)
    
    // 发生错误时仍然重置状态
    isDragging = false
  }
}

// 拖拽开始
const onDragStart = (e) => {
  // 只有当点击的是标题栏区域（不是按钮）时才触发拖拽
  if (!e.target.closest('.title-bar-buttons') && !e.target.closest('button')) {
    // 1. 立即重置之前的拖拽状态
    isDragging = false
    currentDragId = null
    cleanupDragEventListeners()
    
    isDragging = true
    
    // 生成统一的 dragId
    currentDragId = `panel_${props.id}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`
    
    console.log(`[Panel:${props.id}] 开始拖拽, dragId: ${currentDragId}`)
    
    // 2. 使用事件总线触发拖拽开始事件，包含统一的 dragId 和标准化数据格式
    emitEvent(EVENT_TYPES.PANEL_DRAG_START, {
      dragId: currentDragId,
      panelId: props.id,
      areaId: getCurrentAreaId(),
      position: { x: e.clientX, y: e.clientY },
      timestamp: Date.now()
    }, {
      source: { component: 'Panel', panelId: props.id, dragId: currentDragId }
    })
    
    // 3. 防止文本选择和默认行为
    e.preventDefault()
    e.stopPropagation()
    
    // 4. 添加Document事件监听器，使用一次性变量避免内存泄漏
    addDocumentDragListeners()
  }
};

// 拖拽移动
const onDragMove = (e) => {
  if (isDragging && currentDragId) {
    // 防止文本选择和默认行为
    e.preventDefault();
    e.stopPropagation();
    
    // 使用事件总线触发拖拽移动事件，包含 dragId
    emitEvent(EVENT_TYPES.PANEL_DRAG_MOVE, {
      dragId: currentDragId,
      panelId: props.id,
      areaId: getCurrentAreaId(),
      position: { x: e.clientX, y: e.clientY },
      timestamp: Date.now()
    }, {
      source: { component: 'Panel', panelId: props.id, dragId: currentDragId }
    })
  }
};

// 拖拽结束
const onDragEnd = () => {
  if (isDragging && currentDragId) {
    isDragging = false;
    
    console.log(`[Panel:${props.id}] 结束拖拽, dragId: ${currentDragId}`)
    
    // 使用事件总线触发拖拽结束事件，包含 dragId
    emitEvent(EVENT_TYPES.PANEL_DRAG_END, {
      dragId: currentDragId,
      panelId: props.id,
      areaId: getCurrentAreaId(),
      timestamp: Date.now()
    }, {
      source: { component: 'Panel', panelId: props.id, dragId: currentDragId }
    })
    
    // 使用统一的清理方法，确保一致性和完整性
    cleanupDragEventListeners()
    
    // 重置 dragId
    currentDragId = null
  }
};

/**
 * 监听面板关闭事件，更新组件状态（可选）
 */
const setupEventListeners = () => {
  try {
    // 监听面板最大化同步事件
    const unsubscribeMaximizeSync = onEvent(EVENT_TYPES.PANEL_MAXIMIZE_SYNC, (data) => {
      if (data.panelId === props.id) {
        console.log(`[Panel:${props.id}] 收到最大化同步事件`)
      }
    }, { componentId: `panel-${props.id}` })
    
    const subscriptionId = `maximizeSync_${props.id}_${Date.now()}`
    subscriptions.add(unsubscribeMaximizeSync)
    subscriptionRegistry.set(subscriptionId, {
      unsubscribe: unsubscribeMaximizeSync,
      name: 'maximizeSync',
      createdAt: Date.now()
    })
    
    console.log(`[Panel:${props.id}] 事件监听器注册完成，ID: ${subscriptionId}`)
    
  } catch (error) {
    console.error(`[Panel:${props.id}] 注册事件监听器失败:`, error)
  }
}

/**
 * 增强版清理事件监听器，返回清理结果统计
 */
const cleanupEventListeners = () => {
  const cleanupResult = {
    eventSubscriptions: 0,
    documentListeners: 0,
    errors: []
  }
  
  try {
    if (import.meta.env.DEV) {
      console.log(`[Panel:${props.id}] 开始清理所有事件监听器...`)
    }
    
    // 1. 清理事件订阅
    let unsubscribeCount = 0
    const subscriptionsToCleanup = Array.from(subscriptions)
    
    subscriptionsToCleanup.forEach((subscription, index) => {
      try {
        if (subscription && typeof subscription === 'function') {
          subscription() // 执行取消订阅函数
          unsubscribeCount++
        } else {
          console.warn(`[Panel:${props.id}] 发现无效的订阅函数，索引: ${index}`)
        }
      } catch (error) {
        console.warn(`[Panel:${props.id}] 取消订阅时出错，索引: ${index}:`, error)
        cleanupResult.errors.push(`取消订阅错误 (${index}): ${error.message}`)
      }
    })
    
    // 清空订阅集合和注册表
    subscriptions.clear()
    subscriptionRegistry.clear()
    
    cleanupResult.eventSubscriptions = unsubscribeCount
    if (import.meta.env.DEV) {
      console.log(`[Panel:${props.id}] 已清理 ${unsubscribeCount} 个事件订阅`)
    }
    
  } catch (error) {
    console.error(`[Panel:${props.id}] 清理事件订阅时发生严重错误:`, error)
    cleanupResult.errors.push(`事件订阅清理错误: ${error.message}`)
  }
  
  try {
    // 2. 清理Document事件监听器
    cleanupDragEventListeners()
    cleanupResult.documentListeners = 3 // mousemove, mouseup, mouseleave
    
  } catch (error) {
    console.error(`[Panel:${props.id}] 清理Document事件监听器时发生错误:`, error)
    cleanupResult.errors.push(`Document事件清理错误: ${error.message}`)
  }
  
  // 3. 重置状态
  try {
    isDragging = false
    if (import.meta.env.DEV) {
      console.log(`[Panel:${props.id}] 拖拽状态已重置`)
    }
  } catch (error) {
    cleanupResult.errors.push(`状态重置错误: ${error.message}`)
  }
  
  // 4. 输出清理结果摘要
  if (import.meta.env.DEV) {
    const totalErrors = cleanupResult.errors.length
    if (totalErrors > 0) {
      console.warn(`[Panel:${props.id}] 清理完成，存在 ${totalErrors} 个错误:`, cleanupResult.errors)
    } else {
      console.log(`[Panel:${props.id}] 清理完全成功，无错误`)
    }
  }
  
  return cleanupResult
}

// 生命周期钩子
onMounted(() => {
  console.log(`[Panel:${props.id}] 组件已挂载`)
  
  // 注册到全局内存保护机制
  if (window.__panelMemoryProtection) {
    window.__panelMemoryProtection.registerPanel(`panel_${props.id}`)
  }
  
  // 启用调试模式（开发环境）
  if (import.meta.env.DEV) {
    eventBus.setDebugMode(true)
  }
  
  // 设置事件监听器
  setupEventListeners()
  
  // 更新活动状态
  if (window.__panelMemoryProtection) {
    window.__panelMemoryProtection.updateActivity(`panel_${props.id}`)
  }
  
  if (import.meta.env.DEV) {
    console.log(`[Panel:${props.id}] 所有监听器设置完成`)
  }
})

onUnmounted(() => {
  console.log(`[Panel:${props.id}] 组件即将卸载`)
  
  // 立即注销全局内存保护机制
  if (window.__panelMemoryProtection) {
    window.__panelMemoryProtection.unregisterPanel(`panel_${props.id}`)
  }
  
  try {
    // 1. 立即设置标志位，防止新的异步操作
    isDragging = false
    
    // 2. 同步清理所有可以直接清理的资源
    const cleanupResult = cleanupEventListeners()
    
    // 3. 记录清理结果
    if (import.meta.env.DEV) {
      console.log(`[Panel:${props.id}] 组件清理结果:`, cleanupResult)
    }
    
    // 4. 清理超时保护 - 简化版本，防止无限等待
    const cleanupTimeout = setTimeout(() => {
      console.warn(`[Panel:${props.id}] 清理超时，但继续卸载`)
    }, 200) // 缩短超时时间
    
    // 5. 清理超时定时器，确保不会泄露
    setTimeout(() => {
      clearTimeout(cleanupTimeout)
    }, 250)
    
  } catch (error) {
    console.error(`[Panel:${props.id}] 清理过程中出现异常:`, error)
    
    // 即使出现异常，也要尝试强制清理
    try {
      isDragging = false
      // 强制清理事件监听器
      cleanupEventListeners()
    } catch (forceError) {
      console.error(`[Panel:${props.id}] 强制清理也失败:`, forceError)
    }
  }
})
</script>

<style scoped>
/* 面板基础样式 */
.panel {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}

/* 图标样式优化 */
.icon-square-svg {
  /* 优化SVG渲染，避免1px边框显示过粗的问题 */
  shape-rendering: crispEdges;
}

/* 内容区域滚动条样式 */
.content-area {
  /* 确保滚动条正确显示 */
  scrollbar-width: thin;
  scrollbar-color: #c7d2ea #f5f7fb;
}

/* Webkit浏览器滚动条样式 */
.content-area::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

.content-area::-webkit-scrollbar-track {
  background: #f5f7fb;
  border-radius: 6px;
}

.content-area::-webkit-scrollbar-thumb {
  background: linear-gradient(to bottom, #d0d6ea, #c0c7e0);
  border: 1px solid #b0b6d6;
  border-radius: 6px;
}

.content-area::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(to bottom, #c1c7e2, #b2b8d9);
}

.content-area::-webkit-scrollbar-corner {
  background: #f5f7fb;
}

/* 禁用可能存在的旧伪元素样式 */
:deep(.icon-square::before),
:deep(.icon-square::after) {
  content: none !important;
  display: none !important;
  border: 0 !important;
}
</style>