<template>
  <div class="strategy-layer" :class="`layer-${layerKey}`" :style="{ borderColor: color }">
    <div class="layer-header" :style="{ background: color }">
      <span class="layer-icon">{{ icon }}</span>
      <span class="layer-name">{{ label }}</span>
      <span class="layer-objective-count">{{ objectives.length }} 个目标</span>
      <el-dropdown trigger="click" @command="onLayerAction">
        <el-button class="layer-more-btn" size="small" text>
          <el-icon><MoreFilled /></el-icon>
        </el-button>
        <template #dropdown>
          <el-dropdown-item command="rename">重命名</el-dropdown-item>
          <el-dropdown-item command="color">更换颜色</el-dropdown-item>
          <el-dropdown-item command="icon">更换图标</el-dropdown-item>
        </template>
      </el-dropdown>
    </div>
    <div class="layer-body" ref="bodyRef">
      <MapNode
        v-for="(obj, oi) in objectives" :key="`${layerKey}-${oi}`"
        :ref="el => setNodeRef(`${layerKey}-${oi}`, el)"
        :objective="obj"
        :node-key="`${layerKey}-${oi}`"
        :index="oi"
        :level="getNodeLevel(`${layerKey}-${oi}`)"
        :progress-data="getNodeProgress(`${layerKey}-${oi}`)"
        :draggable="true"
        :is-linking-source="linkingFromKey === `${layerKey}-${oi}`"
        :is-linking-target="!!linkingFromKey && linkingFromKey !== `${layerKey}-${oi}`"
        :is-drag-connect-target="dragConnectTarget === `${layerKey}-${oi}`"
        :is-drag-over="dragOverNodeKey === `${layerKey}-${oi}`"
        :icon-map="iconMap"
        :kpi-name-map="kpiNameMap"
        :all-kpis="allKpis"
        @drag-start="(p: any) => onNodeDragStart(layerKey, oi, p.event)"
        @drag-over="onNodeDragOver(layerKey, oi)"
        @drag-leave="onNodeDragLeave"
        @drop="onNodeDrop(layerKey, oi)"
        @click="onNodeClick(layerKey, oi, obj)"
        @edit="$emit('edit-objective', { dimKey: layerKey, idx: oi, obj })"
        @delete="$emit('delete-objective', { dimKey: layerKey, idx: oi })"
        @link-click="$emit('start-link', { key: `${layerKey}-${oi}`, obj })"
        @link-drag-start="(e: MouseEvent) => $emit('link-drag-start', e, layerKey, oi, obj)"
        @kpi-click="(code: string) => $emit('kpi-click', code)"
        @plan-click="$emit('show-plan-list', { dimKey: layerKey, idx: oi, obj })"
      />
      <el-button text type="primary" size="small" style="margin-top:8px;width:100%;" @click="$emit('add-objective', layerKey)">
        + 添加目标
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { MoreFilled } from '@element-plus/icons-vue'
import MapNode from './MapNode.vue'

const props = defineProps<{
  layerKey: string
  label: string
  icon: string
  color: string
  objectives: any[]
  linkingFromKey?: string | null
  dragConnectTarget?: string | null
  dragOverNodeKey?: string | null
  iconMap?: Record<string, string>
  kpiNameMap?: Record<string, string>
  allKpis?: any[]
  getNodeLevel: (key: string) => string
  getNodeProgress: (key: string) => any
}>()

const emit = defineEmits<{
  (e: 'add-objective', dimKey: string): void
  (e: 'edit-objective', payload: { dimKey: string; idx: number; obj: any }): void
  (e: 'delete-objective', payload: { dimKey: string; idx: number }): void
  (e: 'start-link', payload: { key: string; obj: any }): void
  (e: 'link-drag-start', event: MouseEvent, dimKey: string, oi: number, obj: any): void
  (e: 'kpi-click', code: string): void
  (e: 'show-plan-list', payload: { dimKey: string; idx: number; obj: any }): void
  (e: 'node-click', dimKey: string, oi: number, obj: any): void
  (e: 'drag-start', dimKey: string, oi: number, event: DragEvent): void
  (e: 'drag-over', dimKey: string, oi: number): void
  (e: 'drag-leave'): void
  (e: 'drop', dimKey: string, oi: number): void
  (e: 'layer-action', cmd: string): void
  (e: 'update:label', val: string): void
  (e: 'update:color', val: string): void
  (e: 'update:icon', val: string): void
}>()

const bodyRef = ref<HTMLElement | null>(null)

// Node DOM refs for line calculation (reactive so parent can aggregate)
const nodeRefs = reactive<Record<string, any>>({})
function setNodeRef(key: string, el: any) {
  if (el) nodeRefs[key] = el
}

// Expose nodeRefs to parent for connection line calculation
defineExpose({ nodeRefs, bodyRef })

function onLayerAction(cmd: string) {
  emit('layer-action', cmd)
}

function onNodeDragStart(dimKey: string, oi: number, event: DragEvent) {
  emit('drag-start', dimKey, oi, event)
}
function onNodeDragOver(dimKey: string, oi: number) {
  emit('drag-over', dimKey, oi)
}
function onNodeDragLeave() {
  emit('drag-leave')
}
function onNodeDrop(dimKey: string, oi: number) {
  emit('drop', dimKey, oi)
}
function onNodeClick(dimKey: string, oi: number, obj: any) {
  emit('node-click', dimKey, oi, obj)
}
</script>

<style scoped>
.strategy-layer {
  border: 2px solid #e8e8e8;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  background: #fafafa;
  min-height: 120px;
  transition: border-color 0.2s;
  overflow: hidden;
  width: 100%;
}

.layer-header {
  padding: 10px 14px;
  color: #fff;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  flex-shrink: 0;
  user-select: none;
}

.layer-icon {
  font-size: 18px;
}

.layer-name {
  flex: 1;
}

.layer-objective-count {
  font-size: 11px;
  opacity: 0.8;
  font-weight: 400;
}

.layer-more-btn {
  color: rgba(255,255,255,0.7) !important;
  padding: 2px !important;
}
.layer-more-btn:hover {
  color: #fff !important;
}

.layer-body {
  padding: 10px 14px;
  flex: 1;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 8px;
  align-content: flex-start;
  overflow-y: auto;
}

/* Each MapNode in a layer gets flex basis */
.layer-body > .map-node-wrapper {
  flex: 0 0 auto;
}

/* Adjust for the direct MapNode child */
.layer-body :deep(.map-node) {
  margin-bottom: 0;
  flex: 1 1 220px;
  max-width: 280px;
}

/* Add objective button full width row */
.layer-body > .el-button {
  width: 100% !important;
  flex-shrink: 0;
}
</style>
