<template>
  <div class="app-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>我的待办</span>
          <div class="header-actions">
            <el-tag v-if="total > 0" type="danger" effect="dark" round>{{ total }}</el-tag>
            <el-button type="primary" size="small" :icon="Filter" @click="openFilterDrawer">筛选</el-button>
          </div>
        </div>
      </template>

      <el-form :inline="true" :model="queryParams" class="search-form">
        <el-form-item label="流程名称">
          <el-select v-model="queryParams.processName" placeholder="全部流程" clearable style="width: 200px;" @change="onProcessChange">
            <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.currentNodeId" placeholder="全部节点" clearable style="width: 160px;">
            <el-option v-for="node in currentNodeOptions" :key="node.id" :label="node.name" :value="node.id" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>

      <el-radio-group v-model="activeUrgency" class="urgency-tabs" @change="handleUrgencyChange">
        <el-radio-button label="all">全部</el-radio-button>
        <el-radio-button label="overdue">已超时</el-radio-button>
        <el-radio-button label="warning">即将超时</el-radio-button>
        <el-radio-button label="normal">正常</el-radio-button>
      </el-radio-group>

      <!-- 批量操作工具条 -->
      <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="success" :icon="Check" size="small" @click="openBatchDrawer('pass')">批量通过</el-button>
          <el-button type="danger" :icon="Close" size="small" @click="openBatchDrawer('reject')">批量拒绝</el-button>
          <el-button size="small" @click="clearSelection">取消选择</el-button>
        </div>
      </div>

      <!-- 飞书多维表格风格列表 -->
      <div v-loading="loading" class="todo-table-wrapper">
        <el-empty v-if="!loading && filteredTableData.length === 0" description="暂无待办任务" />
        <el-table
          v-else
          ref="tableRef"
          :data="filteredTableData"
          class="todo-table"
          row-key="id"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="48" fixed="left" />

          <el-table-column label="流程名称" min-width="200" fixed="left" show-overflow-tooltip>
            <template #default="{ row }">
              <div class="process-cell">
                <div class="process-title">
                  <el-tag
                    :type="urgencyType(row.urgency)"
                    size="small"
                    effect="dark"
                    class="urgency-tag"
                  >
                    {{ urgencyText(row.urgency) }}
                  </el-tag>
                  <span class="process-name">{{ row.definitionName || '未命名流程' }}</span>
                </div>
                <div v-if="row.instanceTitle" class="process-subtitle">
                  {{ row.instanceTitle }}
                </div>
              </div>
            </template>
          </el-table-column>

          <el-table-column label="当前节点" width="140" show-overflow-tooltip>
            <template #default="{ row }">
              <el-tag type="warning" size="small"><strong>{{ row.nodeName }}</strong></el-tag>
            </template>
          </el-table-column>

          <!-- 动态流程表单字段列 -->
          <el-table-column
            v-for="field in dynamicFields"
            :key="field.name"
            :label="field.label"
            :prop="field.name"
            min-width="140"
            show-overflow-tooltip
          >
            <template #default="{ row }">
              <span class="field-value">{{ getFieldDisplayValue(row, field) }}</span>
            </template>
          </el-table-column>

          <el-table-column label="到达时间" width="160">
            <template #default="{ row }">
              <span class="time-text">{{ row.createTime }}</span>
            </template>
          </el-table-column>

          <el-table-column label="剩余时间" width="120">
            <template #default="{ row }">
              <span v-if="row.timeoutTime" :class="{ 'text-danger': row.urgency === 2, 'text-warning': row.urgency === 1 }">
                {{ formatRemaining(row) }}
              </span>
              <span v-else class="text-muted">—</span>
            </template>
          </el-table-column>

          <el-table-column label="实例编号" width="170" show-overflow-tooltip>
            <template #default="{ row }">
              <span class="text-muted">{{ row.instanceNo || '—' }}</span>
            </template>
          </el-table-column>

          <el-table-column label="操作" width="220" fixed="right">
            <template #default="{ row }">
              <div class="operation-cell">
                <el-button
                  link
                  type="success"
                  size="small"
                  :icon="Check"
                  style="padding: 0 4px;"
                  @click.stop="openQuickApprove(row, 'pass')"
                >
                  通过
                </el-button>
                <el-button
                  link
                  type="warning"
                  size="small"
                  :icon="Back"
                  style="padding: 0 4px;"
                  @click.stop="openRollback(row)"
                >
                  回退
                </el-button>
                <el-button
                  link
                  type="primary"
                  size="small"
                  :icon="View"
                  style="padding: 0 4px;"
                  @click.stop="handleDetail(row)"
                >
                  详情
                </el-button>
                <el-dropdown trigger="click" @command="(cmd: string) => handleMoreAction(cmd, row)">
                  <el-button link type="primary" size="small" style="padding: 0 4px;">
                    更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
                  </el-button>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item command="reject">
                        <el-icon><Close /></el-icon>拒绝
                      </el-dropdown-item>
                      <el-dropdown-item command="addSign">
                        <el-icon><Plus /></el-icon>加签
                      </el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <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>

    <!-- 审批抽屉 -->
    <ApprovalDrawer ref="approvalDrawerRef" @success="onApproved" />

    <!-- 加签对话框 -->
    <AddSignDialog ref="addSignDialogRef" @success="onAddSigned" />

    <!-- 流程详情抽屉 -->
    <InstanceDetail
      v-model="detailVisible"
      :instance-id="currentInstanceId"
      @approved="loadData"
    />

    <!-- 表单字段筛选抽屉 -->
    <el-drawer
      v-model="filterDrawerVisible"
      title="筛选"
      direction="rtl"
      size="360px"
      :destroy-on-close="false"
      @closed="closeFilterDrawer"
    >
      <div class="filter-drawer-content">
        <el-form :model="filterForm" label-width="100px">
          <el-form-item label="流程名称">
            <el-select v-model="filterForm.processName" placeholder="全部流程" clearable style="width: 100%" @change="onFilterProcessChange">
              <el-option v-for="def in definitionList" :key="def.id" :label="def.name" :value="def.name" />
            </el-select>
          </el-form-item>
          <template v-if="filterFields.length > 0">
            <el-divider>表单字段</el-divider>
            <el-form-item v-for="field in filterFields" :key="field.name" :label="field.label">
              <el-input
                v-if="!field.type || field.type === 'text' || field.type === 'textarea'"
                v-model="filterForm[field.name]"
                :placeholder="`请输入${field.label}`"
                clearable
              />
              <el-input-number
                v-else-if="field.type === 'number'"
                v-model="filterForm[field.name]"
                style="width: 100%;"
                :placeholder="`请输入${field.label}`"
                controls-position="right"
              />
              <el-select
                v-else-if="field.type === 'select'"
                v-model="filterForm[field.name]"
                style="width: 100%;"
                :placeholder="`请选择${field.label}`"
                clearable
              >
                <el-option v-for="opt in normalizeFilterOptions(field.options)" :key="String(opt.value)" :label="opt.label" :value="String(opt.value)" />
              </el-select>
              <el-date-picker
                v-else-if="field.type === 'date'"
                v-model="filterForm[field.name]"
                type="date"
                style="width: 100%;"
                value-format="YYYY-MM-DD"
                :placeholder="`请选择${field.label}`"
              />
            </el-form-item>
          </template>
        </el-form>
        <div class="drawer-footer">
          <el-button @click="filterDrawerVisible = false">取消</el-button>
          <el-button @click="resetFilter">重置</el-button>
          <el-button type="primary" @click="applyFilter">确定</el-button>
        </div>
      </div>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Check, Close, Back, Plus, View, ArrowDown, Filter } from '@element-plus/icons-vue'
import { listTodo } from '@/api/flow/task'
import { listEnabled } from '@/api/flow/definition'
import type { FlowTask, FormField, FormFieldOption, FlowDefinition } from '@/types/flow'
import type { TableInstance } from 'element-plus'
import InstanceDetail from '@/views/flow/execute/InstanceDetail.vue'
import ApprovalDrawer from '@/components/ApprovalDrawer/index.vue'
import AddSignDialog from '@/components/AddSignDialog/index.vue'

const loading = ref(false)
const tableData = ref<FlowTask[]>([])
const total = ref(0)
const tableRef = ref<TableInstance>()
const definitionList = ref<FlowDefinition[]>([])
const currentNodeOptions = ref<{ id: string; name: string }[]>([])

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

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

// 表单字段筛选
const filterDrawerVisible = ref(false)
const filterForm = reactive<Record<string, any>>({
  processName: undefined
})

const filterFields = computed<FormField[]>(() => {
  const name = filterForm.processName
  if (!name) return []
  const def = definitionList.value.find(d => d.name === name)
  if (!def || !def.formSchema) return []
  try {
    const parsed = JSON.parse(def.formSchema)
    return Array.isArray(parsed) ? parsed.filter((f: FormField) => f.name && f.label) : []
  } catch {
    return []
  }
})

function openFilterDrawer() {
  filterForm.processName = queryParams.processName
  // 初始化已保存的筛选值
  if (queryParams.formFilters) {
    try {
      const saved = JSON.parse(queryParams.formFilters)
      Object.assign(filterForm, saved)
    } catch { /* ignore */ }
  }
  filterDrawerVisible.value = true
}

// 筛选抽屉打开后，给超长 label 加上 title 属性，hover 时显示完整文字
watch(filterDrawerVisible, async (val) => {
  if (!val) return
  await nextTick()
  const labels = document.querySelectorAll('.filter-drawer-content .el-form-item__label')
  labels.forEach((el) => {
    const htmlEl = el as HTMLElement
    htmlEl.title = htmlEl.textContent || ''
  })
})

function closeFilterDrawer() {
  // 不自动保存，只有点击确定才保存
}

function onFilterProcessChange() {
  // 切换流程时清空旧表单字段值
  Object.keys(filterForm).forEach(key => {
    if (key !== 'processName') {
      delete filterForm[key]
    }
  })
}

function normalizeFilterOptions(options?: FormFieldOption[] | string[]): FormFieldOption[] {
  if (!options || !Array.isArray(options)) return []
  return options.map((opt: any) => {
    if (typeof opt === 'string') {
      return { label: opt, value: opt }
    }
    return { label: String(opt.label ?? opt.value), value: String(opt.value) }
  })
}

function resetFilter() {
  Object.keys(filterForm).forEach(key => delete filterForm[key])
  queryParams.processName = undefined
  queryParams.formFilters = undefined
  queryParams.pageNum = 1
  filterDrawerVisible.value = false
  loadData()
}

function applyFilter() {
  const filters: Record<string, string> = {}
  filterFields.value.forEach(field => {
    const value = filterForm[field.name]
    if (value !== undefined && value !== null && String(value).trim() !== '') {
      filters[field.name] = String(value)
    }
  })
  queryParams.processName = filterForm.processName
  queryParams.formFilters = Object.keys(filters).length > 0 ? JSON.stringify(filters) : undefined
  queryParams.pageNum = 1
  filterDrawerVisible.value = false
  loadData()
}

const activeUrgency = ref<'all' | 'overdue' | 'warning' | 'normal'>('all')

const urgencyText = (urgency?: number) => {
  const map: Record<number, string> = { 0: '正常', 1: '即将超时', 2: '已超时' }
  return map[urgency ?? 0] || '正常'
}

const urgencyType = (urgency?: number) => {
  const map: Record<number, string> = { 0: 'info', 1: 'warning', 2: 'danger' }
  return map[urgency ?? 0] || 'info'
}

function formatRemaining(row: FlowTask) {
  if (row.urgency === 2) {
    const hours = Math.abs(Math.ceil((row.remainingMinutes ?? 0) / 60))
    return `已超时 ${hours} 小时`
  }
  const hours = Math.ceil((row.remainingMinutes ?? 0) / 60)
  return `剩余 ${hours} 小时`
}

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

const filteredTableData = computed(() => {
  if (activeUrgency.value === 'all') return tableData.value
  const map: Record<string, number> = { overdue: 2, warning: 1, normal: 0 }
  return tableData.value.filter(row => row.urgency === map[activeUrgency.value])
})

// 动态表单字段列：从当前页所有任务的 formSchema 聚合
const dynamicFields = computed<FormField[]>(() => {
  const fieldMap = new Map<string, FormField>()
  filteredTableData.value.forEach(row => {
    if (!row.formSchema) return
    try {
      const parsed = JSON.parse(row.formSchema)
      if (Array.isArray(parsed)) {
        parsed.forEach((field: FormField) => {
          if (field.name && !fieldMap.has(field.name)) {
            fieldMap.set(field.name, field)
          }
        })
      }
    } catch {
      // ignore
    }
  })
  return Array.from(fieldMap.values())
})

function parseFormData(row: FlowTask): Record<string, unknown> {
  if (!row.formData) return {}
  try {
    return JSON.parse(row.formData)
  } catch {
    return {}
  }
}

function normalizeOptions(options?: FormFieldOption[] | string[]): FormFieldOption[] {
  if (!options || !Array.isArray(options)) return []
  return options.map((opt: any) => {
    if (typeof opt === 'string') {
      return { label: opt, value: opt }
    }
    return { label: String(opt.label ?? opt.value), value: opt.value }
  })
}

function formatValue(value: unknown): string {
  if (value === undefined || value === null) return ''
  if (typeof value === 'boolean') return value ? '是' : '否'
  return String(value)
}

function formatSelectValue(value: unknown, field: FormField): string {
  const options = normalizeOptions(field.options)
  if (!options.length) return formatValue(value)
  const list = field.multiple && Array.isArray(value) ? value : [value]
  const labels = list.map(v => {
    const found = options.find(opt => String(opt.value) === String(v))
    return found ? found.label : formatValue(v)
  })
  return labels.join('，')
}

function getFieldDisplayValue(row: FlowTask, field: FormField): string {
  const data = parseFormData(row)
  const value = data[field.name]
  if (value === undefined || value === null) return '—'
  if (field.type === 'select') {
    return formatSelectValue(value, field)
  }
  return formatValue(value)
}

const approvalDrawerRef = ref<InstanceType<typeof ApprovalDrawer> | null>(null)
const addSignDialogRef = ref<InstanceType<typeof AddSignDialog> | null>(null)

// 选择相关
const selectedIds = ref<number[]>([])

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

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

function openQuickApprove(row: FlowTask, action: 'pass' | 'reject') {
  approvalDrawerRef.value?.open(row, action)
}

function openBatchDrawer(action: 'pass' | 'reject') {
  if (selectedIds.value.length === 0) {
    ElMessage.warning('请先选择待办任务')
    return
  }
  const selectedTasks = tableData.value.filter(r => selectedIds.value.includes(r.id))
  approvalDrawerRef.value?.open(selectedTasks, action)
}

function openRollback(row: FlowTask) {
  approvalDrawerRef.value?.open(row, 'rollback')
}

function onApproved() {
  selectedIds.value = []
  loadData()
}

// 详情抽屉
const detailVisible = ref(false)
const currentInstanceId = ref(0)

function handleDetail(row: FlowTask) {
  if (!row.instanceId) {
    ElMessage.warning('该任务没有关联流程实例')
    return
  }
  currentInstanceId.value = row.instanceId
  detailVisible.value = true
}

function handleRowClick(row: FlowTask) {
  handleDetail(row)
}

function handleAddSign(row: FlowTask) {
  addSignDialogRef.value?.open(row.id)
}

function onAddSigned() {
  loadData()
}

function handleMoreAction(cmd: string, row: FlowTask) {
  switch (cmd) {
    case 'reject':
      openQuickApprove(row, 'reject')
      break
    case 'addSign':
      handleAddSign(row)
      break
  }
}

async function loadData() {
  loading.value = true
  try {
    const res = await listTodo(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
  }
}

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

function resetQuery() {
  queryParams.processName = undefined
  queryParams.formFilters = undefined
  queryParams.currentNodeId = undefined
  currentNodeOptions.value = []
  activeUrgency.value = 'all'
  queryParams.pageNum = 1
  Object.keys(filterForm).forEach(key => delete filterForm[key])
  loadData()
}

async function loadDefinitions() {
  try {
    definitionList.value = await listEnabled()
    // 默认选中第一个流程并触发查询
    if (definitionList.value.length > 0 && !queryParams.processName) {
      queryParams.processName = definitionList.value[0].name
      onProcessChange()
      loadData()
    }
  } catch {
    definitionList.value = []
  }
}

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

<style scoped>
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}
.search-form {
  margin-bottom: 20px;
}
.urgency-tabs {
  margin-bottom: 16px;
}
.text-danger {
  color: #f56c6c;
}
.text-warning {
  color: #e6a23c;
}
.text-muted {
  color: #909399;
}
.time-text {
  color: #606266;
  font-size: 13px;
}
.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;
}

/* 飞书多维表格风格列表 */
.todo-table-wrapper {
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  overflow: hidden;
}
.todo-table {
  width: 100%;
}
.todo-table :deep(.el-table__header-wrapper th) {
  background-color: #f5f7fa;
  color: #606266;
  font-weight: 600;
  font-size: 13px;
  padding: 12px 0;
}
.todo-table :deep(.el-table__row) {
  transition: background-color 0.2s ease;
}
.todo-table :deep(.el-table__row:hover) {
  background-color: #f5f7ff !important;
}
.todo-table :deep(.el-table__cell) {
  padding: 12px 0;
}
.process-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.process-title {
  display: flex;
  align-items: center;
  gap: 8px;
}
.urgency-tag {
  flex-shrink: 0;
}
.process-name {
  font-weight: 600;
  color: #303133;
  font-size: 14px;
}
.process-subtitle {
  color: #909399;
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.field-value {
  color: #303133;
  font-size: 13px;
}
.operation-cell {
  display: flex;
  align-items: center;
  gap: 4px;
}
.operation-cell .el-button {
  padding: 4px 6px;
}
.pagination {
  margin-top: 20px;
  justify-content: flex-end;
}
.drawer-content {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.batch-alert {
  margin-bottom: 16px;
}
.drawer-footer {
  margin-top: auto;
  padding-top: 20px;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
.previous-attachments {
  margin-bottom: 10px;
  padding: 10px 12px;
  background: #f5f7fa;
  border-radius: 4px;
}
.previous-title {
  font-size: 13px;
  color: #909399;
  margin-bottom: 6px;
}
.previous-item {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.previous-meta {
  font-size: 12px;
  color: #909399;
}
.filter-drawer-content {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding-right: 8px;
}
.filter-drawer-content :deep(.el-form-item__label) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block !important;
  text-align: left !important;
  direction: ltr !important;
}
.filter-drawer-content :deep(.el-input__inner),
.filter-drawer-content :deep(.el-select .el-input__inner) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:deep(.el-table__body-wrapper .el-button--small.is-link + .el-button--small.is-link) {
  margin-left: 0;
}
</style>
