<template>
  <div class="designer-container">
    <!-- 流程信息栏（新增/编辑模式显示） -->
    <div v-if="flowInfoVisible" class="flow-info-bar">
      <el-tag v-if="mode === 'create'" type="primary">新增流程</el-tag>
      <el-tag v-else-if="mode === 'edit'" type="warning">编辑流程</el-tag>
      <span class="flow-info-item"><strong>编码：</strong>{{ flowCode }}</span>
      <span class="flow-info-item"><strong>名称：</strong>{{ flowName }}</span>
      <span v-if="flowCategory" class="flow-info-item"><strong>分类：</strong>{{ flowCategory }}</span>
    </div>

    <div class="node-panel">
      <div class="panel-title">节点类型</div>
      <div
        v-for="node in nodeTypes"
        :key="node.type"
        class="node-item"
        draggable="true"
        @dragstart="handleDragStart($event, node)"
      >
        <div class="node-icon" :style="{ backgroundColor: node.color }">
          <el-icon><component :is="node.icon" /></el-icon>
        </div>
        <div class="node-name">{{ node.label }}</div>
      </div>
    </div>

    <div class="canvas-area" @drop="handleDrop" @dragover.prevent>
      <div ref="lfContainer" class="lf-container" />
      <div class="toolbar">
        <el-button type="primary" size="small" @click="handleSave">保存</el-button>
        <el-button size="small" @click="handleClear">清空</el-button>
        <el-button size="small" @click="goBack">返回</el-button>
      </div>
    </div>

    <div class="property-panel" v-if="selectedNode">
      <div class="panel-title">节点属性</div>
      <el-form label-width="80px" size="small">
        <el-form-item label="节点ID">
          <el-input v-model="selectedNode.id" disabled />
        </el-form-item>
        <el-form-item label="节点名称">
          <el-input v-model="nodeName" @blur="updateNodeName" />
        </el-form-item>
        <template v-if="selectedNode.type === 'approval-node'">
          <el-form-item label="审批员工">
            <el-select
              v-model="nodeProps.assigneeValue"
              filterable
              clearable
              placeholder="请选择员工管理中的成员"
              style="width: 100%"
            >
              <el-option
                v-for="role in roleList"
                :key="role.id"
                :label="role.roleName"
                :value="role.roleCode"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="审批方式">
            <el-select v-model="nodeProps.approveMode" placeholder="请选择" style="width: 100%">
              <el-option label="或签（一人通过即可）" value="or" />
              <el-option label="会签（全部通过）" value="and" />
            </el-select>
          </el-form-item>
          <el-form-item label="审批时限">
            <el-input-number
              v-model="nodeProps.timeoutHours"
              :min="1"
              :max="720"
              :precision="0"
              placeholder="不填表示无限制"
              controls-position="right"
              style="width: 100%"
            />
            <div class="form-tip">单位：小时，为空则不计算超时</div>
          </el-form-item>
          <el-form-item label="超时动作">
            <el-select v-model="nodeProps.timeoutAction" placeholder="请选择" style="width: 100%">
              <el-option label="提醒" value="remind" />
              <el-option label="自动通过" value="pass" />
              <el-option label="自动驳回" value="reject" />
            </el-select>
            <div class="form-tip">目前仅实现「提醒」，自动通过/驳回预留</div>
          </el-form-item>
        </template>
        <template v-if="selectedNode.type === 'condition-node'">
          <el-form-item label="条件表达式">
            <el-input v-model="nodeProps.condition" type="textarea" placeholder="输入条件表达式" />
          </el-form-item>
        </template>
        <template v-if="selectedNode.type === 'cc-node'">
          <el-form-item label="抄送人">
            <el-select
              v-model="nodeProps.ccUsers"
              filterable
              clearable
              placeholder="请选择抄送人"
              style="width: 100%"
            >
              <el-option
                v-for="role in roleList"
                :key="role.id"
                :label="role.roleName"
                :value="role.roleCode"
              />
            </el-select>
          </el-form-item>
        </template>
      </el-form>
    </div>
    <div class="property-panel empty" v-else>
      <div class="panel-title">节点属性</div>
      <el-empty description="请选择节点" />
    </div>

    <!-- 保存确认弹窗（无模式时） -->
    <el-dialog v-model="saveDialogVisible" title="保存流程" width="600px">
      <el-form ref="saveFormRef" :model="saveForm" :rules="saveFormRules" label-width="100px">
        <el-form-item label="流程编码" prop="code">
          <el-input v-model="saveForm.code" />
        </el-form-item>
        <el-form-item label="流程名称" prop="name">
          <el-input v-model="saveForm.name" />
        </el-form-item>
        <el-form-item label="分类">
          <el-input v-model="saveForm.category" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="saveForm.description" type="textarea" />
        </el-form-item>
      </el-form>

      <div class="form-fields-section">
        <div class="form-fields-header">
          <span class="form-fields-title">流程表单字段</span>
          <el-button type="primary" size="small" :icon="Delete" @click="addFormField">添加字段</el-button>
        </div>
        <el-table :data="formFields" size="small" border style="width: 100%">
          <el-table-column label="字段名" min-width="120">
            <template #default="{ $index }">
              <el-input v-model="formFields[$index].name" placeholder="英文标识" size="small" />
            </template>
          </el-table-column>
          <el-table-column label="显示名" min-width="120">
            <template #default="{ $index }">
              <el-input v-model="formFields[$index].label" placeholder="中文显示名" size="small" />
            </template>
          </el-table-column>
          <el-table-column label="类型" width="120">
            <template #default="{ $index }">
              <el-select v-model="formFields[$index].type" placeholder="类型" size="small" style="width: 100%">
                <el-option v-for="opt in fieldTypeOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column label="必填" width="70" align="center">
            <template #default="{ $index }">
              <el-checkbox v-model="formFields[$index].required" />
            </template>
          </el-table-column>
          <el-table-column label="多选" width="70" align="center">
            <template #default="{ $index }">
              <el-checkbox
                v-model="formFields[$index].multiple"
                :disabled="formFields[$index].type !== 'select'"
              />
            </template>
          </el-table-column>
          <el-table-column label="选项" width="90" align="center">
            <template #default="{ $index }">
              <el-button
                link
                type="primary"
                size="small"
                :disabled="formFields[$index].type !== 'select'"
                @click="openOptionDialog($index)"
              >
                配置选项
              </el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="70" align="center">
            <template #default="{ $index }">
              <el-button link type="danger" size="small" @click="removeFormField($index)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-empty v-if="formFields.length === 0" description="暂无字段，点击上方按钮添加" :image-size="60" style="padding: 10px 0;" />
      </div>

      <template #footer>
        <el-button @click="saveDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitSave">确认保存</el-button>
      </template>
    </el-dialog>

    <!-- 下拉选项配置弹窗 -->
    <el-dialog v-model="optionDialogVisible" title="配置下拉选项" width="500px">
      <div v-if="optionEditingField" class="option-edit-tip">
        字段：{{ optionEditingField.label || optionEditingField.name }}
        <el-checkbox v-model="optionEditingField.multiple" style="margin-left: 16px;">允许多选</el-checkbox>
      </div>
      <el-table :data="optionList" size="small" border>
        <el-table-column label="显示文本" min-width="140">
          <template #default="{ $index }">
            <el-input v-model="optionList[$index].label" placeholder="显示文本" size="small" />
          </template>
        </el-table-column>
        <el-table-column label="选项值" min-width="140">
          <template #default="{ $index }">
            <el-input v-model="optionList[$index].value" placeholder="选项值" size="small" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="70" align="center">
          <template #default="{ $index }">
            <el-button link type="danger" size="small" @click="removeOption($index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-button type="primary" size="small" style="margin-top: 12px;" @click="addOption">添加选项</el-button>
      <template #footer>
        <el-button @click="optionDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="saveOptions">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick, reactive, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import LogicFlow, { RectNode, RectNodeModel, CircleNode, CircleNodeModel, PolygonNode, PolygonNodeModel } from '@logicflow/core'
import { Menu, Snapshot } from '@logicflow/extension'
import '@logicflow/core/dist/style/index.css'
import '@logicflow/extension/lib/style/index.css'
import { VideoPlay, User, Message, Operation, CircleCheck } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { listRole } from '@/api/system/role'
import { addDefinition, updateDefinition, getDefinition } from '@/api/flow/definition'
import type { Role } from '@/types/system'
import type { FlowDefinition, FormField, FormFieldOption } from '@/types/flow'
import { Delete } from '@element-plus/icons-vue'

const route = useRoute()
const router = useRouter()

const lfContainer = ref<HTMLDivElement>()
let lf: LogicFlow | null = null

const mode = computed(() => (route.query.mode as string) || '')
const flowId = computed(() => (route.query.id as string) || '')
const flowCode = computed(() => (route.query.code as string) || '')
const flowName = computed(() => (route.query.name as string) || '')
const flowCategory = computed(() => (route.query.category as string) || '')
const flowDescription = computed(() => (route.query.description as string) || '')
const flowInfoVisible = computed(() => mode.value === 'create' || mode.value === 'edit')

const selectedNode = ref<any>(null)
const roleList = ref<Role[]>([])
const nodeProps = reactive<Record<string, any>>({
  assigneeType: 'ROLE',
  assigneeValue: '',
  approveMode: 'or',
  timeoutHours: undefined as number | undefined,
  timeoutAction: 'remind',
  condition: '',
  ccUsers: ''
})

const nodeName = computed({
  get: () => selectedNode.value?.text?.value || '',
  set: (val: string) => {
    if (selectedNode.value) {
      selectedNode.value.text = { ...selectedNode.value.text, value: val }
    }
  }
})

const nodeTypes = [
  { type: 'start-node', label: '开始', icon: VideoPlay, color: '#67C23A' },
  { type: 'approval-node', label: '审批', icon: User, color: '#409EFF' },
  { type: 'cc-node', label: '抄送', icon: Message, color: '#E6A23C' },
  { type: 'condition-node', label: '条件', icon: Operation, color: '#909399' },
  { type: 'end-node', label: '结束', icon: CircleCheck, color: '#F56C6C' }
]

function getDefaultProps(type: string) {
  if (type === 'approval-node') return { assigneeType: 'ROLE', assigneeValue: '', approveMode: 'or', timeoutHours: undefined, timeoutAction: 'remind' }
  if (type === 'condition-node') return { condition: '' }
  if (type === 'cc-node') return { ccUsers: '' }
  return {}
}

function saveCurrentNodeProps() {
  if (selectedNode.value && lf) {
    const type = selectedNode.value.type
    const defaultProps = getDefaultProps(type)
    // 只保存当前节点类型相关的属性，避免不同类型节点属性互相污染
    const props: Record<string, any> = JSON.parse(JSON.stringify(defaultProps))
    if (type === 'approval-node') {
      props.assigneeType = 'ROLE'
      props.assigneeValue = nodeProps.assigneeValue ?? ''
      props.approveMode = nodeProps.approveMode ?? 'or'
      props.timeoutHours = nodeProps.timeoutHours
      props.timeoutAction = nodeProps.timeoutAction ?? 'remind'
    } else if (type === 'condition-node') {
      props.condition = nodeProps.condition ?? ''
    } else if (type === 'cc-node') {
      props.ccUsers = nodeProps.ccUsers ?? ''
    }
    lf.setProperties(selectedNode.value.id, props)
  }
}

function loadNodeProps(data: any) {
  const props = data.properties || getDefaultProps(data.type)
  const cloned = JSON.parse(JSON.stringify(props))
  // 先重置为默认值，避免上一个节点的属性残留
  Object.assign(nodeProps, getDefaultProps(data.type))
  // 兼容旧格式：approver + approveType -> 新格式
  if (data.type === 'approval-node') {
    let assigneeType = 'ROLE'
    let assigneeValue = cloned.assigneeValue ?? ''
    let approveMode = cloned.approveMode ?? cloned.approveType ?? 'or'
    if (!cloned.assigneeValue && cloned.approver) {
      assigneeValue = cloned.approver
    }
    // 旧数据中的 USER/SELF/LEADER 不再支持，统一清空让用户重新选择员工角色
    if (cloned.assigneeType && cloned.assigneeType !== 'ROLE') {
      assigneeValue = ''
    }
    nodeProps.assigneeType = assigneeType
    nodeProps.assigneeValue = assigneeValue
    nodeProps.approveMode = approveMode
    nodeProps.timeoutHours = cloned.timeoutHours ?? undefined
    nodeProps.timeoutAction = cloned.timeoutAction ?? 'remind'
  } else if (data.type === 'condition-node') {
    nodeProps.condition = cloned.condition ?? ''
  } else if (data.type === 'cc-node') {
    nodeProps.ccUsers = cloned.ccUsers ?? ''
  }
}

function registerNodes() {
  if (!lf) return

  class StartNodeModel extends CircleNodeModel {
    setAttributes() {
      this.r = 30
      this.text.value = '开始'
    }
    getNodeStyle() {
      const style = super.getNodeStyle()
      style.fill = '#67C23A'
      style.stroke = '#67C23A'
      return style
    }
    getTextStyle() {
      const style = super.getTextStyle()
      style.color = '#fff'
      return style
    }
  }
  lf.register({ type: 'start-node', view: CircleNode, model: StartNodeModel })

  class ApprovalNodeModel extends RectNodeModel {
    setAttributes() {
      this.width = 160
      this.height = 60
      this.radius = 8
      this.text.value = '审批节点'
    }
    getNodeStyle() {
      const style = super.getNodeStyle()
      style.fill = '#fff'
      style.stroke = '#409EFF'
      style.strokeWidth = 1
      return style
    }
  }
  lf.register({ type: 'approval-node', view: RectNode, model: ApprovalNodeModel })

  class CcNodeModel extends RectNodeModel {
    setAttributes() {
      this.width = 160
      this.height = 60
      this.radius = 8
      this.text.value = '抄送节点'
    }
    getNodeStyle() {
      const style = super.getNodeStyle()
      style.fill = '#fff'
      style.stroke = '#E6A23C'
      style.strokeWidth = 1
      return style
    }
  }
  lf.register({ type: 'cc-node', view: RectNode, model: CcNodeModel })

  class ConditionNodeModel extends PolygonNodeModel {
    setAttributes() {
      this.points = [[60, 0], [120, 40], [60, 80], [0, 40]]
      this.text.value = '条件'
    }
    getNodeStyle() {
      const style = super.getNodeStyle()
      style.fill = '#fff'
      style.stroke = '#909399'
      return style
    }
  }
  lf.register({ type: 'condition-node', view: PolygonNode, model: ConditionNodeModel })

  class EndNodeModel extends CircleNodeModel {
    setAttributes() {
      this.r = 30
      this.text.value = '结束'
    }
    getNodeStyle() {
      const style = super.getNodeStyle()
      style.fill = '#F56C6C'
      style.stroke = '#F56C6C'
      return style
    }
    getTextStyle() {
      const style = super.getTextStyle()
      style.color = '#fff'
      return style
    }
  }
  lf.register({ type: 'end-node', view: CircleNode, model: EndNodeModel })
}

function initLogicFlow() {
  if (!lfContainer.value) return

  lf = new LogicFlow({
    container: lfContainer.value,
    grid: true,
    plugins: [Menu, Snapshot],
    pluginsOptions: {
      menu: {
        nodeMenu: [{
          text: '删除',
          callback(node: any) { lf?.deleteNode(node.id) }
        }]
      }
    } as any
  })

  registerNodes()

  lf.on('node:click', ({ data }: any) => {
    saveCurrentNodeProps()
    selectedNode.value = data
    loadNodeProps(data)
  })

  lf.on('blank:click', () => {
    saveCurrentNodeProps()
    selectedNode.value = null
  })

  // 编辑模式：加载已有流程图
  if (mode.value === 'edit' && flowId.value) {
    getDefinition(Number(flowId.value)).then((def: FlowDefinition) => {
      parseFormSchema(def.formSchema)
      if (def.flowJson) {
        try {
          const graphData = convertToFrontendFormat(JSON.parse(def.flowJson))
          lf?.render(graphData)
        } catch {
          lf?.render({ nodes: defaultNodes(), edges: [] })
        }
      } else {
        lf?.render({ nodes: defaultNodes(), edges: [] })
      }
    }).catch(() => {
      lf?.render({ nodes: defaultNodes(), edges: [] })
    })
  } else {
    lf.render({ nodes: defaultNodes(), edges: [] })
  }
}

function defaultNodes() {
  return [
    { id: 'start-1', type: 'start-node', x: 200, y: 100, text: '开始' },
    { id: 'end-1', type: 'end-node', x: 200, y: 500, text: '结束' }
  ]
}

// 节点类型映射：LogicFlow <-> 后端
const typeToBackend: Record<string, string> = {
  'start-node': 'start',
  'approval-node': 'approval',
  'cc-node': 'cc',
  'condition-node': 'condition',
  'end-node': 'end'
}
const typeToFrontend: Record<string, string> = {
  'start': 'start-node',
  'approval': 'approval-node',
  'cc': 'cc-node',
  'condition': 'condition-node',
  'end': 'end-node'
}

// 将 LogicFlow 的 graphData 转换为后端格式
function convertToBackendFormat(graphData: any) {
  const data = JSON.parse(JSON.stringify(graphData))
  if (data.nodes) {
    data.nodes = data.nodes.map((node: any) => {
      const n = { ...node }
      if (n.type && typeToBackend[n.type]) {
        n.type = typeToBackend[n.type]
      }
      // text -> name
      if (n.text !== undefined) {
        n.name = typeof n.text === 'object' ? n.text.value : n.text
        delete n.text
      }
      return n
    })
  }
  // edges 保持原样，properties 中的 condition 会在后端解析
  return data
}

// 将后端的 graphData 转换为 LogicFlow 格式
function convertToFrontendFormat(graphData: any) {
  const data = JSON.parse(JSON.stringify(graphData))
  if (data.nodes) {
    data.nodes = data.nodes.map((node: any) => {
      const n = { ...node }
      if (n.type && typeToFrontend[n.type]) {
        n.type = typeToFrontend[n.type]
      }
      // name -> text
      if (n.name !== undefined) {
        n.text = n.name
        delete n.name
      }
      return n
    })
  }
  return data
}

function handleDragStart(e: DragEvent, node: any) {
  const serializable = { type: node.type, label: node.label }
  e.dataTransfer?.setData('application/json', JSON.stringify(serializable))
}

function handleDrop(e: DragEvent) {
  e.preventDefault()
  const dataStr = e.dataTransfer?.getData('application/json')
  if (!dataStr || !lf) return
  const nodeData = JSON.parse(dataStr)
  const rect = lfContainer.value!.getBoundingClientRect()
  lf.addNode({
    type: nodeData.type,
    x: e.clientX - rect.left,
    y: e.clientY - rect.top,
    text: nodeData.label
  })
}

function updateNodeName() {
  if (!lf || !selectedNode.value) return
  lf.setNodeText(selectedNode.value.id, nodeName.value)
}

// 保存流程
const saveDialogVisible = ref(false)
const saveFormRef = ref<FormInstance>()
const saveForm = reactive({
  code: '',
  name: '',
  category: '',
  description: ''
})
const saveFormRules: FormRules = {
  code: [{ required: true, message: '请输入流程编码', trigger: 'blur' }],
  name: [{ required: true, message: '请输入流程名称', trigger: 'blur' }]
}

const formFields = ref<FormField[]>([])
const fieldTypeOptions = [
  { label: '文本', value: 'text' },
  { label: '多行文本', value: 'textarea' },
  { label: '数字', value: 'number' },
  { label: '日期', value: 'date' },
  { label: '下拉选择', value: 'select' }
]

function addFormField() {
  formFields.value.push({ name: '', label: '', type: 'text', required: false })
}

function removeFormField(index: number) {
  formFields.value.splice(index, 1)
}

function getFormSchema(): string {
  const validFields = formFields.value.filter(f => f.name.trim() && f.label.trim())
  return validFields.length > 0 ? JSON.stringify(validFields) : ''
}

function parseFormSchema(schema?: string) {
  if (!schema) return
  try {
    const parsed = JSON.parse(schema)
    if (Array.isArray(parsed)) {
      formFields.value = parsed
    }
  } catch {
    formFields.value = []
  }
}

// 下拉选项编辑
const optionDialogVisible = ref(false)
const optionEditingIndex = ref<number | null>(null)
const optionEditingField = ref<FormField | null>(null)
const optionList = ref<FormFieldOption[]>([])

function openOptionDialog(index: number) {
  optionEditingIndex.value = index
  optionEditingField.value = formFields.value[index]
  const rawOptions = optionEditingField.value.options || []
  optionList.value = rawOptions.map((opt: any) => {
    if (typeof opt === 'string') {
      return { label: opt, value: opt }
    }
    return { label: String(opt.label ?? opt.value), value: opt.value }
  })
  optionDialogVisible.value = true
}

function addOption() {
  optionList.value.push({ label: '', value: '' })
}

function removeOption(index: number) {
  optionList.value.splice(index, 1)
}

function saveOptions() {
  if (optionEditingIndex.value === null || !optionEditingField.value) return
  const validOptions = optionList.value.filter(opt => String(opt.label).trim() !== '' && String(opt.value).trim() !== '')
  formFields.value[optionEditingIndex.value].options = validOptions
  formFields.value[optionEditingIndex.value].multiple = optionEditingField.value.multiple
  optionDialogVisible.value = false
}

function validateFlow(graphData: any): string | null {
  const nodes = graphData.nodes || []
  const edges = graphData.edges || []
  if (nodes.length === 0) return '流程图不能为空'
  const startNodes = nodes.filter((n: any) => n.type === 'start-node' || n.type === 'start')
  const endNodes = nodes.filter((n: any) => n.type === 'end-node' || n.type === 'end')
  if (startNodes.length === 0) return '流程图缺少开始节点'
  if (endNodes.length === 0) return '流程图缺少结束节点'
  if (startNodes.length > 1) return '流程图只能有一个开始节点'
  if (endNodes.length > 1) return '流程图只能有一个结束节点'
  // 检查审批节点是否选择了员工管理中的成员（角色账号）
  for (const node of nodes) {
    if (node.type === 'approval-node' || node.type === 'approval') {
      const props = node.properties || {}
      const assigneeValue = props.assigneeValue || props.approver
      if (!assigneeValue) {
        return `审批节点 "${node.text || node.name}" 未选择员工管理中的审批成员`
      }
    }
  }
  // 检查孤立节点
  const connectedNodeIds = new Set<string>()
  for (const edge of edges) {
    connectedNodeIds.add(edge.sourceNodeId)
    connectedNodeIds.add(edge.targetNodeId)
  }
  for (const node of nodes) {
    if (!connectedNodeIds.has(node.id) && node.type !== 'start-node' && node.type !== 'start' && node.type !== 'end-node' && node.type !== 'end') {
      return `节点 "${node.text || node.name}" 是孤立节点，请删除或连接`
    }
  }
  // 检查条件分支是否有默认分支
  const sourceMap: Record<string, any[]> = {}
  for (const edge of edges) {
    if (!sourceMap[edge.sourceNodeId]) sourceMap[edge.sourceNodeId] = []
    sourceMap[edge.sourceNodeId].push(edge)
  }
  for (const node of nodes) {
    if (node.type === 'condition-node' || node.type === 'condition') {
      const outEdges = sourceMap[node.id] || []
      if (outEdges.length > 1) {
        const hasDefault = outEdges.some((e: any) => !e.properties?.condition && !e.condition)
        if (!hasDefault) {
          return `条件节点 "${node.text || node.name}" 需要至少一条无条件的默认分支`
        }
      }
    }
  }
  return null
}

async function handleSave() {
  if (!lf) return
  saveCurrentNodeProps()
  const rawGraphData = lf.getGraphData()
  const error = validateFlow(rawGraphData)
  if (error) {
    ElMessage.warning(error)
    return
  }

  // 统一弹出保存弹窗，方便配置流程表单字段
  if (mode.value === 'create') {
    saveForm.code = flowCode.value
    saveForm.name = flowName.value
    saveForm.category = flowCategory.value
    saveForm.description = flowDescription.value
    formFields.value = []
  } else if (mode.value === 'edit' && flowId.value) {
    saveForm.code = flowCode.value
    saveForm.name = flowName.value
    saveForm.category = flowCategory.value
    saveForm.description = flowDescription.value
    // formFields 在编辑模式加载流程时已通过 parseFormSchema 填充
  } else {
    saveForm.code = ''
    saveForm.name = ''
    saveForm.category = ''
    saveForm.description = ''
    formFields.value = []
  }
  saveDialogVisible.value = true
}

async function submitSave() {
  const valid = await saveFormRef.value?.validate().catch(() => false)
  if (!valid) return
  if (!lf) return
  saveCurrentNodeProps()
  const rawGraphData = lf.getGraphData()
  const error = validateFlow(rawGraphData)
  if (error) {
    ElMessage.warning(error)
    return
  }
  const graphData = convertToBackendFormat(rawGraphData)

  if (mode.value === 'create') {
    const data: Partial<FlowDefinition> = {
      code: saveForm.code,
      name: saveForm.name,
      category: saveForm.category,
      description: saveForm.description,
      formSchema: getFormSchema(),
      flowJson: JSON.stringify(graphData),
      status: 0
    }
    await addDefinition(data)
    ElMessage.success('流程新增成功')
    saveDialogVisible.value = false
    router.push('/flow/definition')
  } else if (mode.value === 'edit' && flowId.value) {
    const data: Partial<FlowDefinition> = {
      id: Number(flowId.value),
      code: saveForm.code,
      name: saveForm.name,
      category: saveForm.category,
      description: saveForm.description,
      formSchema: getFormSchema(),
      flowJson: JSON.stringify(graphData)
    }
    const newId = await updateDefinition(data)
    if (newId !== Number(flowId.value)) {
      ElMessage.success('流程已创建为新版本，请重新发布')
    } else {
      ElMessage.success('流程修改成功')
    }
    saveDialogVisible.value = false
    router.push('/flow/definition')
  } else {
    const data: Partial<FlowDefinition> = {
      code: saveForm.code,
      name: saveForm.name,
      category: saveForm.category,
      description: saveForm.description,
      formSchema: getFormSchema(),
      flowJson: JSON.stringify(graphData),
      status: 0
    }
    await addDefinition(data)
    ElMessage.success('流程保存成功')
    saveDialogVisible.value = false
    router.push('/flow/definition')
  }
}

function handleClear() {
  if (!lf) return
  lf.clearData()
  selectedNode.value = null
}

function goBack() {
  router.push('/flow/definition')
}

async function loadRoles() {
  try {
    const res = await listRole({ pageNum: 1, pageSize: 100 })
    roleList.value = res.list
  } catch { /* ignore */ }
}

onMounted(() => {
  // 防止快速进入/离开设计器时重复创建 LogicFlow 实例
  if (lf) {
    lf.destroy()
    lf = null
  }
  nextTick(initLogicFlow)
  loadRoles()
})

onUnmounted(() => {
  lf?.destroy()
  lf = null
  selectedNode.value = null
})
</script>

<style scoped>
.designer-container {
  display: flex;
  height: calc(100vh - 100px);
  background: #fff;
}
.flow-info-bar {
  position: absolute;
  top: 60px;
  left: 220px;
  right: 0;
  height: 40px;
  background: #f0f9ff;
  border-bottom: 1px solid #d9ecff;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 16px;
  z-index: 100;
}
.flow-info-item {
  font-size: 13px;
  color: #303133;
}
.node-panel {
  width: 200px;
  border-right: 1px solid #dcdfe6;
  padding: 16px;
  background: #fafafa;
}
.panel-title {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 16px;
  color: #303133;
}
.node-item {
  display: flex;
  align-items: center;
  padding: 12px;
  margin-bottom: 8px;
  border-radius: 6px;
  cursor: move;
  background: #fff;
  border: 1px solid #ebeef5;
  transition: all 0.2s;
}
.node-item:hover {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  border-color: #c6e2ff;
}
.node-icon {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  margin-right: 12px;
}
.node-name {
  font-size: 14px;
  color: #606266;
}
.canvas-area {
  flex: 1;
  position: relative;
  background: #f5f7fa;
}
.lf-container {
  width: 100%;
  height: 100%;
}
.toolbar {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 10;
}
.property-panel {
  width: 300px;
  border-left: 1px solid #dcdfe6;
  padding: 16px;
  background: #fafafa;
  overflow-y: auto;
}
.property-panel.empty {
  display: flex;
  flex-direction: column;
}
.form-fields-section {
  margin-top: 16px;
  border-top: 1px solid #ebeef5;
  padding-top: 16px;
}
.form-fields-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
.form-fields-title {
  font-weight: bold;
  color: #303133;
}
</style>
