<template>
  <main class="block-canvas">
    <el-empty v-if="!blocks.length" description="拖入左侧业务块开始配置页面" :image-size="80" />
    <article
      v-for="(block, index) in blocks"
      v-else
      :key="block.id"
      class="canvas-block"
      :class="{ active: block.id === selectedId }"
      :style="{ gridColumn: `span ${block.span || 12}` }"
      role="button"
      tabindex="0"
      draggable="true"
      @click="emit('select-block', block.id)"
      @keydown.enter.prevent="emit('select-block', block.id)"
      @keydown.space.prevent="emit('select-block', block.id)"
      @dragstart="dragIndex = index"
      @dragover.prevent
      @drop="dropBlock(index)"
    >
      <div class="canvas-block-toolbar">
        <span class="drag-handle">::</span>
        <strong class="block-title">{{ block.name || block.blockCode }}</strong>
        <small class="block-code">{{ block.blockCode }}</small>
        <button type="button" class="remove" @click.stop="emit('remove-block', block.id)">删除</button>
      </div>
      <ChartBlockPreview
        v-if="definitionFor(block)?.kind === 'chart'"
        :definition="definitionFor(block)"
        :block="block"
      />
    </article>
  </main>
</template>

<script setup>
import { ref } from 'vue'
import ChartBlockPreview from './ChartBlockPreview.vue'

const props = defineProps({
  blocks: { type: Array, default: () => [] },
  definitions: { type: Array, default: () => [] },
  selectedId: { type: String, default: '' }
})

const emit = defineEmits(['select-block', 'reorder-block', 'remove-block'])
const dragIndex = ref(-1)

function dropBlock(toIndex) {
  if (dragIndex.value < 0 || dragIndex.value === toIndex) return
  emit('reorder-block', { fromIndex: dragIndex.value, toIndex })
  dragIndex.value = -1
}

function definitionFor(block) {
  return props.definitions.find((definition) => definition?.code === block?.blockCode) || null
}
</script>

<style scoped lang="scss">
.block-canvas {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  align-content: start;
  gap: 12px;
  min-height: 320px;
  padding: 16px;
  border: 1px dashed #cbd5e1;
  border-radius: 8px;
  background: #fbfdff;
}

.canvas-block {
  display: block;
  width: 100%;
  min-width: 0;
  min-height: 52px;
  padding: 10px 12px;
  border: 1px solid #e7ecf3;
  border-radius: 8px;
  background: #fff;
  color: #303133;
  text-align: left;
  cursor: pointer;
}

.canvas-block.active {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.08);
}

.canvas-block-toolbar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 10px;
}

.drag-handle,
.canvas-block small,
.remove {
  color: #98a2b3;
  font-size: 12px;
}

.block-title,
.block-code {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.remove {
  padding: 0;
  border: 0;
  background: transparent;
  white-space: nowrap;
  cursor: pointer;
}

.remove:hover {
  color: #f56c6c;
}

@media (max-width: 900px) {
  .canvas-block {
    grid-column: 1 / -1 !important;
  }
}
</style>
