<template>
  <div class="palette">
    <div class="hint">拖到画布添加积木（过滤/打分可指定源或宿）</div>
    <el-radio-group v-model="dropSide" size="small" class="side">
      <el-radio-button value="source">源侧</el-radio-button>
      <el-radio-button value="target">宿侧</el-radio-button>
    </el-radio-group>
    <div v-for="group in grouped" :key="group.category" class="group">
      <div class="group-title">
        <span class="gdot" :style="{ background: group.color }" />
        {{ group.category }}
      </div>
      <div
        v-for="item in group.items"
        :key="item.type"
        class="item"
        draggable="true"
        @dragstart="onDragStart($event, item.type)"
      >
        <span class="idot" :style="{ background: item.color }" />
        <div>
          <div class="ilab">{{ item.label }}</div>
          <div class="idesc">{{ item.description }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { WCS_CATEGORY_ORDER, WCS_NODE_CATALOG, type WcsNodeType } from './nodeCatalog'

const dropSide = ref<'source' | 'target'>('source')
const emit = defineEmits<{ 'update:side': [side: 'source' | 'target'] }>()
watch(dropSide, (v) => emit('update:side', v), { immediate: true })

const CATEGORY_COLORS: Record<string, string> = {
  触发与参数: '#409eff',
  库位策略: '#e6a23c',
  任务与策略: '#13c2c2',
  流程: '#909399'
}

const grouped = computed(() => {
  const by = new Map<string, typeof WCS_NODE_CATALOG>()
  for (const item of WCS_NODE_CATALOG) {
    const list = by.get(item.category) ?? []
    list.push(item)
    by.set(item.category, list)
  }
  return WCS_CATEGORY_ORDER.filter((c) => by.has(c)).map((category) => ({
    category,
    color: CATEGORY_COLORS[category] ?? '#909399',
    items: by.get(category) ?? []
  }))
})

function onDragStart(e: DragEvent, type: WcsNodeType) {
  if (!e.dataTransfer) return
  e.dataTransfer.setData('application/wcs-node', type)
  e.dataTransfer.setData('application/wcs-side', dropSide.value)
  e.dataTransfer.effectAllowed = 'copyMove'
}
</script>

<style scoped>
.palette {
  padding: 8px 10px 16px;
  overflow: auto;
  height: 100%;
  box-sizing: border-box;
}
.hint {
  font-size: 12px;
  color: var(--el-text-color-secondary);
  margin-bottom: 8px;
  line-height: 1.4;
}
.side {
  margin-bottom: 12px;
  width: 100%;
}
.side :deep(.el-radio-button) {
  flex: 1;
}
.side :deep(.el-radio-button__inner) {
  width: 100%;
}
.group {
  margin-bottom: 12px;
}
.group-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--el-text-color-regular);
  margin-bottom: 6px;
}
.gdot,
.idot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.item {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  padding: 8px;
  margin-bottom: 6px;
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: grab;
  background: var(--el-fill-color-blank);
}
.item:hover {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}
.ilab {
  font-size: 13px;
  font-weight: 600;
}
.idesc {
  font-size: 11px;
  color: var(--el-text-color-secondary);
  margin-top: 2px;
}
</style>
