<template>
  <div class="app-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>我的流程</span>
        </div>
      </template>

      <el-form :inline="true" :model="queryParams" class="search-form">
        <el-form-item label="流程名称">
          <el-select v-model="queryParams.processName" placeholder="全部" clearable @change="onProcessNameChange" style="width: 180px;">
            <el-option v-for="def in definitionList" :key="def.id" :label="def.name" :value="def.name" />
          </el-select>
        </el-form-item>
        <el-form-item label="当前节点">
          <el-select v-model="queryParams.currentNodeName" placeholder="全部" clearable :disabled="!queryParams.processName" style="width: 180px;">
            <el-option v-for="node in currentNodeOptions" :key="node" :label="node" :value="node" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
          <el-button type="success" @click="importDialogVisible = true">导入流程</el-button>
        </el-form-item>
      </el-form>

      <!-- 批量操作工具条 -->
      <div v-if="selectedIds.length > 0" class="batch-toolbar">
        <div class="batch-info">
          <el-checkbox :model-value="true" @change="clearSelection" />
          <span>已选择 <strong>{{ selectedIds.length }}</strong> 项</span>
        </div>
        <div class="batch-actions">
          <el-button type="warning" :icon="RefreshLeft" size="small" @click="handleBatchRevoke">批量撤回</el-button>
          <el-button type="danger" :icon="Delete" size="small" @click="handleBatchDelete">批量删除</el-button>
          <el-button size="small" @click="clearSelection">取消选择</el-button>
        </div>
      </div>

      <el-table
        ref="tableRef"
        v-loading="loading"
        :data="tableData"
        border
        row-key="id"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="48" />
        <el-table-column type="index" label="序号" width="60" />
        <el-table-column prop="definitionName" label="流程名称" />
        <el-table-column label="业务编号">
          <template #default="{ row }">
            {{ row.bizValue || row.instanceNo || '-' }}
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template #default="{ row }">
            <el-tag :type="instanceStatusTagType(row.status)">
              {{ instanceStatusText(row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="currentNodeName" label="当前节点">
          <template #default="{ row }">
            {{ row.currentNodeName || row.currentNode || '-' }}
          </template>
        </el-table-column>
        <el-table-column prop="startTime" label="发起时间" />
        <el-table-column prop="endTime" label="结束时间" />
        <el-table-column label="操作" width="200">
          <template #default="{ row }">
            <el-button link type="primary" @click="handleDetail(row)">查看详情</el-button>
            <el-button v-if="row.status === 0 || row.status === 1" link type="warning" @click="handleRevoke(row)">撤回</el-button>
            <el-button v-if="row.status === 6" link type="danger" @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <InstanceDetail v-model="detailVisible" :instance-id="selectedInstanceId" @approved="loadData" />

      <el-pagination
        v-model:current-page="queryParams.pageNum"
        v-model:page-size="queryParams.pageSize"
        :total="total"
        :page-sizes="[10, 20, 50]"
        layout="total, sizes, prev, pager, next, jumper"
        class="pagination"
        @current-change="loadData"
        @size-change="loadData"
      />
    </el-card>

    <!-- 导入流程弹窗 -->
    <el-dialog v-model="importDialogVisible" title="导入流程" width="550px">
      <el-form label-width="100px">
        <el-form-item label="选择流程">
          <el-select v-model="importDefinitionId" placeholder="请选择要导入的流程" style="width: 100%">
            <el-option v-for="def in definitionList" :key="def.id" :label="def.name" :value="def.id" />
          </el-select>
        </el-form-item>
      </el-form>
      <div class="import-buttons" style="margin-left: 100px; margin-bottom: 16px;">
        <el-button type="primary" :disabled="!importDefinitionId" @click="downloadTemplate">下载Excel模板</el-button>
        <el-upload
          :show-file-list="false"
          :before-upload="handleImportFlow"
          accept=".xlsx,.xls"
          action="#"
          style="display: inline-block; margin-left: 12px;"
        >
          <el-button type="success" :disabled="!importDefinitionId" :loading="importing">导入流程</el-button>
        </el-upload>
      </div>
      <el-alert v-if="importDefinitionId" type="info" :closable="false">
        <template #title>操作说明：先下载模板，填写数据后点击「导入流程」上传。</template>
      </el-alert>
      <template #footer>
        <el-button @click="importDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { listMyInstance, revokeInstance, deleteInstance, batchRevokeInstance, batchDeleteInstance } from '@/api/flow/instance'
import { listEnabled, getDefinition } from '@/api/flow/definition'
import InstanceDetail from '@/views/flow/execute/InstanceDetail.vue'
import { instanceStatusText, instanceStatusTagType } from '@/utils/flow'
import { downloadTemplate as downloadFlowTemplate, importFlow } from '@/api/flow/import'
import type { FlowInstance, FlowDefinition } from '@/types/flow'
import { ElMessage, ElMessageBox } from 'element-plus'
import { RefreshLeft, Delete } from '@element-plus/icons-vue'
import type { TableInstance } from 'element-plus'

const loading = ref(false)
const tableData = ref<FlowInstance[]>([])
const total = ref(0)
const detailVisible = ref(false)
const selectedInstanceId = ref<number>(0)
const definitionList = ref<FlowDefinition[]>([])
const currentNodeOptions = ref<string[]>([])
const tableRef = ref<TableInstance>()
const selectedIds = ref<number[]>([])

const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
  processName: undefined as string | undefined,
  currentNodeName: undefined as string | undefined
})

function handleSelectionChange(selection: FlowInstance[]) {
  selectedIds.value = selection.map(row => row.id)
}

function clearSelection() {
  selectedIds.value = []
  tableRef.value?.clearSelection()
}

function onProcessNameChange() {
  queryParams.currentNodeName = undefined
  const def = definitionList.value.find(d => d.name === queryParams.processName)
  if (def?.flowJson) {
    try {
      const model = JSON.parse(def.flowJson)
      currentNodeOptions.value = (model.nodes || [])
        .filter((n: any) => n.type !== 'start' && n.type !== 'end' && n.type !== 'condition' && n.type !== 'cc')
        .map((n: any) => n.name)
    } catch { currentNodeOptions.value = [] }
  } else {
    currentNodeOptions.value = []
  }
}

function handleDetail(row: FlowInstance) {
  selectedInstanceId.value = row.id
  detailVisible.value = true
}

async function handleRevoke(row: FlowInstance) {
  try {
    await ElMessageBox.confirm(`确认撤回流程 "${row.definitionName || row.instanceNo}" 吗？`, '提示', { type: 'warning' })
    await revokeInstance(row.id)
    ElMessage.success('撤回成功')
    loadData()
  } catch {
    // cancel
  }
}

async function handleDelete(row: FlowInstance) {
  try {
    await ElMessageBox.confirm(`确认删除流程 "${row.definitionName || row.instanceNo}" 吗？删除后不可恢复。`, '提示', { type: 'error' })
    await deleteInstance(row.id)
    ElMessage.success('删除成功')
    loadData()
  } catch {
    // cancel
  }
}

function getRevocableIds(): number[] {
  return selectedIds.value.filter(id => {
    const row = tableData.value.find(r => r.id === id)
    return row && (row.status === 0 || row.status === 1)
  })
}

function getDeletableIds(): number[] {
  return selectedIds.value.filter(id => {
    const row = tableData.value.find(r => r.id === id)
    return row && row.status === 6
  })
}

async function handleBatchRevoke() {
  const ids = getRevocableIds()
  if (ids.length === 0) {
    ElMessage.warning('请选择可撤回的流程（待接收或运行中）')
    return
  }
  try {
    await ElMessageBox.confirm(`确认批量撤回 ${ids.length} 个流程吗？`, '提示', { type: 'warning' })
    await batchRevokeInstance(ids)
    ElMessage.success('批量撤回成功')
    clearSelection()
    loadData()
  } catch {
    // cancel
  }
}

async function handleBatchDelete() {
  const ids = getDeletableIds()
  if (ids.length === 0) {
    ElMessage.warning('请选择可删除的流程（已撤回状态）')
    return
  }
  try {
    await ElMessageBox.confirm(`确认批量删除 ${ids.length} 个流程吗？删除后不可恢复。`, '提示', { type: 'error' })
    await batchDeleteInstance(ids)
    ElMessage.success('批量删除成功')
    clearSelection()
    loadData()
  } catch {
    // cancel
  }
}

function handleQuery() {
  queryParams.pageNum = 1
  loadData()
}

function resetQuery() {
  queryParams.processName = undefined
  queryParams.currentNodeName = undefined
  currentNodeOptions.value = []
  queryParams.pageNum = 1
  loadData()
}

async function loadData() {
  loading.value = true
  try {
    const res = await listMyInstance(queryParams)
    tableData.value = res.list
    total.value = res.total
    const pageIds = new Set(res.list.map(r => r.id))
    selectedIds.value = selectedIds.value.filter(id => pageIds.has(id))
  } finally {
    loading.value = false
  }
}

async function loadDefinitions() {
  try {
    definitionList.value = await listEnabled()
  } catch { /* ignore */ }
}

// 导入流程
const importDialogVisible = ref(false)
const importDefinitionId = ref<number | null>(null)
const importing = ref(false)

async function downloadTemplate() {
  if (!importDefinitionId.value) return
  try {
    const def = definitionList.value.find(d => d.id === importDefinitionId.value)
    await downloadFlowTemplate(importDefinitionId.value, (def?.name || '流程') + '模板')
  } catch {
    ElMessage.error({ message: '下载模板失败', duration: 3000 })
  }
}

async function handleImportFlow(file: any) {
  if (!importDefinitionId.value) return false
  importing.value = true
  try {
    const def = await getDefinition(importDefinitionId.value)
    const mappings = buildMappings(def)
    const res = await importFlow(file, importDefinitionId.value, mappings)
    ElMessage.success({ message: `导入成功：新增 ${res.successCount} 条，更新 ${res.updateCount} 条`, duration: 3000 })
    importDialogVisible.value = false
    loadData()
  } catch (e: any) {
    ElMessage.error({ message: e?.message || '导入失败', duration: 3000 })
  } finally {
    importing.value = false
  }
  return false
}

function buildMappings(def: any): Record<string, string> {
  const map: Record<string, string> = {}
  if (def.formSchema) {
    try {
      for (const f of JSON.parse(def.formSchema)) {
        if (f.label && f.name) map[f.label] = f.name
      }
    } catch { /* ignore */ }
  }
  return map
}

onMounted(() => {
  loadDefinitions()
  loadData()
})
</script>

<style scoped>
.card-header { display: flex; justify-content: space-between; align-items: center; }
.pagination { margin-top: 20px; justify-content: flex-end; }
.search-form { margin-bottom: 20px; }
.batch-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #f5f7fa;
  padding: 12px 16px;
  border-radius: 8px;
  margin-bottom: 16px;
}
.batch-info {
  display: flex;
  align-items: center;
  gap: 12px;
  color: #606266;
}
.batch-actions {
  display: flex;
  gap: 10px;
}
</style>
