<template>
  <div>
    <h1 class="text-xl font-bold text-gray-800 mb-4">流程设计器</h1>

    <!-- 流程定义列表 -->
    <div class="bg-white rounded-xl shadow-sm border overflow-hidden">
      <div class="px-4 py-3 border-b flex items-center justify-between">
        <h2 class="text-base font-semibold text-gray-700">流程定义</h2>
        <el-button type="primary" size="small" @click="openCreateDef">+ 新建流程</el-button>
      </div>
      <el-table :data="defList" stripe class="w-full" v-loading="loading">
        <el-table-column prop="process_name" label="流程名称" min-width="160" />
        <el-table-column prop="process_code" label="编码" min-width="140" />
        <el-table-column prop="source" label="来源" min-width="100" />
        <el-table-column label="状态" width="80">
          <template #default="{ row }">
            <el-tag :type="row.is_active ? 'success' : 'info'" size="small">{{ row.is_active ? '启用' : '禁用' }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="created_at" label="创建时间" min-width="160" />
        <el-table-column label="操作" width="180">
          <template #default="{ row }">
            <el-button size="small" type="primary" link @click="openEditDef(row)">编辑节点</el-button>
            <el-button size="small" type="warning" link @click="toggleActive(row)">{{ row.is_active ? '禁用' : '启用' }}</el-button>
            <el-button size="small" type="danger" @click="handleDeleteDef(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 新建/编辑弹窗 -->
    <el-dialog v-model="defDialogVisible" :title="editingDef ? '编辑流程定义' : '新建流程定义'" width="420px">
      <el-form label-position="top">
        <el-form-item label="流程名称">
          <el-input v-model="defForm.process_name" placeholder="如：访客预约审批" />
        </el-form-item>
        <el-form-item label="流程编码">
          <el-input v-model="defForm.process_code" placeholder="如：visitor_approval" :disabled="!!editingDef" />
        </el-form-item>
        <el-form-item label="来源">
          <el-input v-model="defForm.source" placeholder="如：访客系统" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="defForm.description" type="textarea" :rows="2" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="defDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="defSaving" @click="handleDefSave">保存基本信息</el-button>
      </template>
    </el-dialog>

    <!-- 节点编辑器 -->
    <el-drawer v-model="nodeEditorVisible" :title="'节点编辑 — ' + (currentDef?.process_name || '')" size="800px">
      <div class="flex gap-4 h-full">
        <!-- 左侧：设计器 -->
        <div class="flex-1 overflow-y-auto px-1">
          <div class="text-xs text-gray-400 mb-3">第一个节点为开始节点（不可删除/移动）</div>

          <div
            v-for="(node, idx) in nodeList"
            :key="node._key"
            class="border rounded-lg mb-2 p-3"
            :class="{
              'border-blue-400 bg-blue-50': node._editing,
              'border-green-200 bg-green-50': idx === 0,
            }"
          >
            <div class="flex items-center justify-between mb-2">
              <div class="flex items-center gap-2">
                <el-tag size="small" :type="nodeTypeTag(node.node_type)">{{ nodeTypeLabel(node.node_type) }}</el-tag>
                <span class="text-sm font-medium">{{ node.node_name || '未命名' }}</span>
                <span class="text-xs text-gray-400">#{{ node.node_id }}</span>
              </div>
              <div class="flex gap-1">
                <el-button size="small" circle @click="moveNode(idx, -1)" :disabled="idx === 0 || idx === 1">▲</el-button>
                <el-button size="small" circle @click="moveNode(idx, 1)" :disabled="idx === nodeList.length - 1 || idx === 0">▼</el-button>
                <el-button size="small" type="primary" link @click="toggleEditNode(node)">{{ node._editing ? '完成' : '编辑' }}</el-button>
                <el-button size="small" type="danger" link :disabled="idx === 0" @click="nodeList.splice(idx, 1)">删除</el-button>
              </div>
            </div>

            <!-- 展开编辑 -->
            <div v-if="node._editing" class="border-t pt-2 mt-1 space-y-2">
              <el-form label-position="top" size="small">
                <el-row :gutter="8">
                  <el-col :span="12">
                    <el-form-item label="节点ID">
                      <el-input v-model="node.node_id" placeholder="如：Employee" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="节点名称">
                      <el-input v-model="node.node_name" placeholder="如：员工审批" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-form-item label="审批人变量">
                  <el-select v-model="node.user_var" filterable allow-create default-first-option class="w-full" placeholder="选择或输入变量名" :disabled="idx === 0">
                    <el-option label="$employee_id（公司接待员工）" value="$employee_id" />
                    <el-option label="$dept_approver_ids（部门审批人）" value="$dept_approver_ids" />
                    <el-option label="$vp_ids（分管领导）" value="$vp_ids" />
                    <el-option label="$default_approver_ids（兜底审批人）" value="$default_approver_ids" />
                    <el-option label="$starter（发起人）" value="$starter" />
                  </el-select>
                  <div v-if="idx === 0" class="text-xs text-gray-400 mt-0.5">开始节点固定为发起人</div>
                </el-form-item>
                <el-row :gutter="8">
                  <el-col :span="12">
                    <el-form-item label="会签（全部通过）">
                      <el-switch v-model="node.is_cosigned" :active-value="1" :inactive-value="0" />
                      <div class="text-xs text-gray-400 mt-0.5">开启后需所有审批人通过才流转</div>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>
            </div>
          </div>

          <el-button type="primary" plain size="small" class="w-full mt-2" @click="addNode">+ 添加审批节点</el-button>
        </div>

        <!-- 右侧：JSON 预览 -->
        <div class="w-80 border-l pl-4 flex flex-col h-full">
          <div class="text-sm font-medium text-gray-700 mb-2 shrink-0">JSON 预览</div>
          <div class="flex-1 overflow-y-auto bg-gray-50 p-2 rounded text-xs">
            <JsonViewer :value="parsedJSON" :expand-depth="3" copyable boxed sort />
          </div>
        </div>
      </div>

      <template #footer>
        <el-button @click="nodeEditorVisible = false">取消</el-button>
        <el-button type="primary" :loading="nodeSaving" @click="handleNodeSave">保存节点配置</el-button>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import request from '@/utils/request'
import { JsonViewer } from 'vue3-json-viewer'
import 'vue3-json-viewer/dist/vue3-json-viewer.css'

const loading = ref(false)
const defList = ref<any[]>([])

// ===== 流程定义 CRUD =====
const defDialogVisible = ref(false)
const editingDef = ref<any>(null)
const defSaving = ref(false)
const defForm = ref({ process_name: '', process_code: '', source: '', description: '' })

async function loadDefs() {
  loading.value = true
  try {
    const res = await request.Get('/v1/admin/workflow/definitions') as any
    const raw = res?.data
    if (Array.isArray(raw)) {
      defList.value = raw
    } else if (raw && typeof raw === 'object' && Array.isArray(raw.list)) {
      // 可能是分页格式 { list: [...], total }
      defList.value = raw.list
    } else if (raw && typeof raw === 'object' && Array.isArray(raw.data)) {
      // 双层嵌套 { code, msg, data: { data: [...] } }
      defList.value = raw.data
    } else {
      defList.value = []
      console.warn('[WF] unexpected format:', raw)
    }
  } catch { defList.value = [] }
  finally { loading.value = false }
}

function openCreateDef() {
  editingDef.value = null
  defForm.value = { process_name: '', process_code: '', source: '', description: '' }
  defDialogVisible.value = true
}

function openEditDef(row: any) {
  currentDef.value = row
  // 解析节点
  if (row.nodes_json) {
    try {
      nodeList.value = JSON.parse(row.nodes_json).map((n: any, i: number) => ({
        ...n,
        _key: Date.now() + i,
        _editing: false,
        _isStart: n.node_type === 0,
        user_var: (n.user_ids || []).join(', '),
      }))
    } catch { nodeList.value = [] }
  } else {
    nodeList.value = []
  }
  nodeEditorVisible.value = true
}

async function handleDefSave() {
  if (!defForm.value.process_name || !defForm.value.process_code) {
    ElMessage.warning('请填写流程名称和编码'); return
  }
  defSaving.value = true
  try {
    if (editingDef.value) {
      await request.Put(`/v1/workflow/definitions/${editingDef.value.id}`, defForm.value)
    } else {
      await request.Post('/v1/admin/workflow/definitions', defForm.value)
    }
    ElMessage.success('保存成功')
    defDialogVisible.value = false
    await loadDefs()
  } catch { /* */ }
  finally { defSaving.value = false }
}

async function toggleActive(row: any) {
  await request.Put(`/v1/workflow/definitions/${row.id}`, { is_active: !row.is_active })
  ElMessage.success(row.is_active ? '已禁用' : '已启用')
  await loadDefs()
}

async function handleDeleteDef(row: any) {
  await ElMessageBox.confirm(`确定删除「${row.process_name}」？`)
  await request.Delete(`/v1/workflow/definitions/${row.id}`)
  ElMessage.success('已删除')
  await loadDefs()
}

// ===== 节点编辑器 =====
const nodeEditorVisible = ref(false)
const currentDef = ref<any>(null)
const nodeSaving = ref(false)
let keyCounter = 0

const nodeList = ref<any[]>([])

function genKey() { return Date.now() + (keyCounter++) }

function addNode() {
  // 插入到第一个节点之后
  const insertIdx = 1
  const newNode = {
    node_id: 'Node' + (nodeList.value.length + 1),
    node_name: '审批节点',
    node_type: 1,
    prev_node_ids: nodeList.value.length > 0 ? [nodeList.value[nodeList.value.length - 1].node_id] : [],
    user_ids: ['$starter'],
    _key: genKey(),
    _editing: true,
    _isStart: false,
    user_var: '$starter',
  }
  nodeList.value.splice(insertIdx, 0, newNode)
  rebuildPrevNodeIDs()
}

function toggleEditNode(node: any) {
  node._editing = !node._editing
}

function moveNode(idx: number, dir: number) {
  const target = idx + dir
  if (target < 0 || target >= nodeList.value.length) return
  const tmp = nodeList.value[idx]
  nodeList.value[idx] = nodeList.value[target]
  nodeList.value[target] = tmp
  rebuildPrevNodeIDs()
}

let dragIdx = -1
function onDragStart(e: DragEvent, idx: number) { dragIdx = idx }
function onDrop(e: DragEvent, idx: number) {
  if (dragIdx >= 0 && dragIdx !== idx) {
    const tmp = nodeList.value[dragIdx]
    nodeList.value.splice(dragIdx, 1)
    nodeList.value.splice(idx, 0, tmp)
    rebuildPrevNodeIDs()
  }
  dragIdx = -1
}

function rebuildPrevNodeIDs() {
  nodeList.value.forEach((n, i) => {
    if (i === 0) {
      n.node_type = 0
      n._isStart = true
      n.prev_node_ids = []
    } else {
      if (n.node_type === 0) n.node_type = 1
      n._isStart = false
      n.prev_node_ids = [nodeList.value[i - 1].node_id]
    }
  })
}

const previewJSON = computed(() => {
  // 从 nodeList 构建预览，过滤内部属性
  const nodes = nodeList.value.map((n: any) => {
    const { _key, _editing, _isStart, user_var, ...rest } = n
    // 同步 user_var → user_ids
    if (user_var) {
      rest.user_ids = user_var.split(',').map((s: string) => s.trim()).filter(Boolean)
    }
    return rest
  })
  return JSON.stringify(nodes, null, 2)
})

// 供 JsonViewer 使用的对象格式
const parsedJSON = computed(() => {
  try { return JSON.parse(previewJSON.value) } catch { return {} }
})

async function handleNodeSave() {
  if (!currentDef.value) return

  // 1. 同步所有节点的 user_var → user_ids
  nodeList.value.forEach((n: any) => {
    if (n.user_var) {
      n.user_ids = n.user_var.split(',').map((s: string) => s.trim()).filter(Boolean)
    }
  })

  // 2. 固定第一个节点为开始节点
  if (nodeList.value.length > 0) {
    const first = nodeList.value[0]
    first.node_id = 'Start'
    first.node_type = 0
    first.user_ids = ['$starter']
    first.user_var = '$starter'
    first._isStart = true
    first.is_cosigned = 0
    first.prev_node_ids = []
  }

  // 3. 重建后续节点的 node_id 和 prev_node_ids（从第2个开始）
  for (let i = 1; i < nodeList.value.length; i++) {
    const n = nodeList.value[i]
    n.node_id = 'Node' + (i + 1)
    n.node_type = 1
    n._isStart = false
    n.prev_node_ids = [nodeList.value[i - 1].node_id]
  }

  // 4. 构建最终 JSON（去掉内部属性）
  const finalNodes = nodeList.value.map((n: any) => {
    const { _key, _editing, _isStart, user_var, ...rest } = n
    return rest
  })
  // 5. 添加结束节点
  finalNodes.push({
    node_id: 'End',
    node_name: '审批完成',
    node_type: 3,
    prev_node_ids: [nodeList.value[nodeList.value.length - 1]?.node_id || 'Node2'],
  })

  nodeSaving.value = true
  try {
    await request.Put(`/v1/admin/workflow/definitions/${currentDef.value.id}`, {
      nodes_json: JSON.stringify(finalNodes),
    })
    ElMessage.success('节点配置已保存')
    nodeEditorVisible.value = false
    await loadDefs()
  } catch { /* */ }
  finally { nodeSaving.value = false }
}

function nodeTypeLabel(t: number) {
  return ['开始', '审批', '网关', '结束'][t] || '未知'
}
function nodeTypeTag(t: number) {
  return ['success', 'primary', 'warning', 'info'][t] || 'info'
}

onMounted(loadDefs)
</script>

<style scoped>
pre { white-space: pre-wrap; word-break: break-all; }
[draggable] { cursor: grab; }
[draggable]:active { cursor: grabbing; opacity: 0.8; }
.el-drawer__body { padding: 16px; overflow: hidden; }
</style>
