<!--
  字段映射选择器
  从上游节点的 outputSchema 选择字段，生成表达式
-->
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { Modal, Tree, Input, Button, Empty, Tag } from 'ant-design-vue'
import { SearchOutlined, NodeIndexOutlined } from '@ant-design/icons-vue'
import type { TreeProps } from 'ant-design-vue'
import { useWorkflowStore } from '../stores/useWorkflowStore'
import { buildOutputFieldTree } from '../utils/fieldTree'
import { generateNodeFieldExpression } from '../utils/expression'
import type { FieldPathNode } from '#/types/workflow'

interface Props {
  /** 当前节点 ID（用于排除自身） */
  currentNodeId: string
  /** 是否显示 */
  visible: boolean
}

interface Emits {
  (e: 'update:visible', value: boolean): void
  /** 选择字段后触发 */
  (e: 'select', expression: string, fieldPath: string): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const workflowStore = useWorkflowStore()

/** 搜索关键词 */
const searchKeyword = ref('')

/** 选中的节点 ID */
const selectedNodeId = ref<string>()

/** 展开的树节点 */
const expandedKeys = ref<string[]>([])

/**
 * 获取上游节点列表
 */
const upstreamNodes = computed(() => {
  return workflowStore.vueFlowNodes
    .filter((node) => node.id !== props.currentNodeId)
    .map((node) => ({
      id: node.id,
      name: node.data.name,
      type: node.type,
      metadata: node.data.metadata,
    }))
})

/**
 * 当前选中节点的字段树
 */
const fieldTree = computed(() => {
  if (!selectedNodeId.value) return []

  const node = upstreamNodes.value.find((n) => n.id === selectedNodeId.value)
  if (!node || !node.metadata?.outputSchema) return []

  const tree = buildOutputFieldTree(
    node.id,
    node.name,
    node.metadata.outputSchema,
    3, // 最大深度
  )

  return convertToAntdTree([tree])
})

/**
 * 过滤后的字段树
 */
const filteredFieldTree = computed(() => {
  if (!searchKeyword.value) return fieldTree.value

  const keyword = searchKeyword.value.toLowerCase()
  return filterTree(fieldTree.value, keyword)
})

/**
 * 转换为 Ant Design Tree 格式
 */
function convertToAntdTree(nodes: FieldPathNode[]): TreeProps['treeData'] {
  return nodes.map((node) => ({
    key: node.path,
    title: node.name,
    type: node.type,
    description: node.description,
    isLeaf: !node.children || node.children.length === 0,
    children:
      node.children && node.children.length > 0
        ? convertToAntdTree(node.children)
        : undefined,
  }))
}

/**
 * 过滤树节点
 */
function filterTree(
  tree: TreeProps['treeData'],
  keyword: string,
): TreeProps['treeData'] {
  if (!tree) return []

  return tree
    .map((node) => {
      const matchTitle = node.title?.toString().toLowerCase().includes(keyword)
      const matchDescription = node.description?.toLowerCase().includes(keyword)
      const matchPath = node.key?.toString().toLowerCase().includes(keyword)

      // 递归过滤子节点
      const filteredChildren = node.children ? filterTree(node.children, keyword) : []

      // 如果节点本身匹配或有子节点匹配，则保留
      if (matchTitle || matchDescription || matchPath || filteredChildren.length > 0) {
        return {
          ...node,
          children: filteredChildren.length > 0 ? filteredChildren : node.children,
        }
      }

      return null
    })
    .filter(Boolean) as TreeProps['treeData']
}

/**
 * 选择节点
 */
function handleNodeSelect(nodeId: string) {
  selectedNodeId.value = nodeId
  expandedKeys.value = []
}

/**
 * 选择字段
 */
function handleFieldSelect(selectedKeys: string[], info: any) {
  if (selectedKeys.length === 0) return

  const fieldPath = selectedKeys[0]
  const node = info.node

  // 只允许选择叶子节点
  if (!node.isLeaf) {
    return
  }

  if (!selectedNodeId.value) return

  // 生成表达式
  const expression = generateNodeFieldExpression(selectedNodeId.value, fieldPath)

  // 触发选择事件
  emit('select', expression, fieldPath)
  handleClose()
}

/**
 * 关闭对话框
 */
function handleClose() {
  emit('update:visible', false)
  selectedNodeId.value = undefined
  searchKeyword.value = ''
  expandedKeys.value = []
}

/**
 * 自动选择第一个节点
 */
watch(
  () => props.visible,
  (visible) => {
    if (visible && upstreamNodes.value.length > 0 && !selectedNodeId.value) {
      selectedNodeId.value = upstreamNodes.value[0].id
    }
  },
)
</script>

<template>
  <Modal
    :open="visible"
    title="选择字段"
    width="700px"
    :footer="null"
    @cancel="handleClose"
  >
    <div class="field-mapping-selector">
      <!-- 左侧：节点列表 -->
      <div class="node-list-panel">
        <div class="panel-header">
          <NodeIndexOutlined />
          <span>上游节点</span>
        </div>
        <div class="node-list">
          <div
            v-for="node in upstreamNodes"
            :key="node.id"
            class="node-item"
            :class="{ active: selectedNodeId === node.id }"
            @click="handleNodeSelect(node.id)"
          >
            <div class="node-name">{{ node.name }}</div>
            <div class="node-id">{{ node.id }}</div>
          </div>

          <Empty
            v-if="upstreamNodes.length === 0"
            description="暂无上游节点"
            :image="Empty.PRESENTED_IMAGE_SIMPLE"
          />
        </div>
      </div>

      <!-- 右侧：字段树 -->
      <div class="field-tree-panel">
        <div class="panel-header">
          <Input
            v-model:value="searchKeyword"
            placeholder="搜索字段..."
            allow-clear
          >
            <template #prefix>
              <SearchOutlined />
            </template>
          </Input>
        </div>

        <div class="field-tree">
          <Tree
            v-if="filteredFieldTree.length > 0"
            v-model:expandedKeys="expandedKeys"
            :tree-data="filteredFieldTree"
            :show-icon="false"
            :selectable="true"
            block-node
            @select="handleFieldSelect"
          >
            <template #title="{ title, type, description, isLeaf }">
              <div class="tree-node-title">
                <span class="field-name">{{ title }}</span>
                <Tag v-if="type" :color="getTypeColor(type)" size="small">
                  {{ type }}
                </Tag>
                <span v-if="description" class="field-description">
                  {{ description }}
                </span>
                <Tag v-if="isLeaf" color="green" size="small">可选</Tag>
              </div>
            </template>
          </Tree>

          <Empty
            v-else
            description="暂无可用字段"
            :image="Empty.PRESENTED_IMAGE_SIMPLE"
          />
        </div>
      </div>
    </div>

    <div class="selector-footer">
      <Button @click="handleClose">取消</Button>
    </div>
  </Modal>
</template>

<script lang="ts">
export default {
  name: 'FieldMappingSelector',
  methods: {
    getTypeColor(type: string): string {
      const colorMap: Record<string, string> = {
        string: 'blue',
        number: 'green',
        boolean: 'orange',
        object: 'purple',
        array: 'cyan',
      }
      return colorMap[type] || 'default'
    },
  },
}
</script>

<style scoped lang="less">
.field-mapping-selector {
  display: flex;
  gap: 16px;
  min-height: 400px;
  max-height: 600px;

  .node-list-panel,
  .field-tree-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    border: 1px solid #e8e8e8;
    border-radius: 6px;
    overflow: hidden;
  }

  .node-list-panel {
    max-width: 250px;
  }

  .panel-header {
    padding: 12px 16px;
    background: #fafafa;
    border-bottom: 1px solid #e8e8e8;
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .node-list {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
  }

  .node-item {
    padding: 10px 12px;
    margin-bottom: 6px;
    background: #fff;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s;

    &:hover {
      background: #f0f7ff;
      border-color: #1890ff;
    }

    &.active {
      background: #e6f7ff;
      border-color: #1890ff;
      box-shadow: 0 2px 4px rgba(24, 144, 255, 0.2);
    }

    .node-name {
      font-size: 14px;
      font-weight: 500;
      color: #333;
      margin-bottom: 4px;
    }

    .node-id {
      font-size: 12px;
      color: #999;
      font-family: monospace;
    }
  }

  .field-tree {
    flex: 1;
    overflow-y: auto;
    padding: 12px;

    :deep(.ant-tree) {
      .ant-tree-node-content-wrapper {
        width: 100%;
      }

      .tree-node-title {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 4px 0;

        .field-name {
          font-weight: 500;
          color: #333;
        }

        .field-description {
          font-size: 12px;
          color: #999;
          margin-left: auto;
        }
      }

      .ant-tree-node-selected {
        .tree-node-title {
          .field-name {
            color: #1890ff;
          }
        }
      }
    }
  }
}

.selector-footer {
  margin-top: 16px;
  text-align: right;
}
</style>

