<!--工单处置管理-->
<template>
  <div class="min-h-screen bg-[#f0f2f6] p-5">
    <div class="mb-5 flex flex-wrap items-center justify-between gap-4 rounded-[20px] bg-white px-6 py-4">
      <div class="flex items-center gap-[14px] text-[20px] font-600">
        <el-icon><Tickets /></el-icon>
        <span>工单任务管理中心</span>
        <el-tag type="primary" effect="dark">待办工单 {{ pendingCount }}</el-tag>
      </div>
      <div class="flex flex-wrap gap-3">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索工单编号/案件编号"
          clearable
          :prefix-icon="Search"
          class="w-[220px]"
          @keyup.enter="loadOrders"
        />
        <el-button type="primary" @click="loadOrders">刷新</el-button>
      </div>
    </div>

    <div class="mb-5 flex flex-wrap gap-6">
      <div class="min-w-[120px] cursor-pointer rounded-2xl bg-white px-4 py-3 text-center" :class="{ 'bg-[#ecf5ff]': statusFilter === '' }" @click="filterStatus('')">
        <div class="text-[26px] font-bold">{{ totalOrders }}</div>
        <div>全部工单</div>
      </div>
      <div class="min-w-[120px] cursor-pointer rounded-2xl bg-white px-4 py-3 text-center" :class="{ 'bg-[#ecf5ff]': statusFilter === 'pending' }" @click="filterStatus('pending')">
        <div class="text-[26px] font-bold text-[#e6a23c]">{{ pendingCount }}</div>
        <div>待处理</div>
      </div>
      <div class="min-w-[120px] cursor-pointer rounded-2xl bg-white px-4 py-3 text-center" :class="{ 'bg-[#ecf5ff]': statusFilter === 'processing' }" @click="filterStatus('processing')">
        <div class="text-[26px] font-bold">{{ processingCount }}</div>
        <div>处理中</div>
      </div>
      <div class="min-w-[120px] cursor-pointer rounded-2xl bg-white px-4 py-3 text-center" :class="{ 'bg-[#ecf5ff]': statusFilter === 'verify' }" @click="filterStatus('verify')">
        <div class="text-[26px] font-bold">{{ verifyCount }}</div>
        <div>待验收</div>
      </div>
      <div class="min-w-[120px] cursor-pointer rounded-2xl bg-white px-4 py-3 text-center" :class="{ 'bg-[#ecf5ff]': statusFilter === 'completed' }" @click="filterStatus('completed')">
        <div class="text-[26px] font-bold">{{ completedCount }}</div>
        <div>已完成</div>
      </div>
    </div>

    <div class="flex gap-5">
      <div class="w-[380px] flex flex-col overflow-hidden rounded-[20px] bg-white" v-loading="loading">
        <div class="flex justify-between border-b border-[#e9ecef] px-4 py-4 font-600">
          <span>工单列表</span>
        </div>
        <div class="flex-1 overflow-y-auto p-3">
          <div
            v-for="order in paginatedOrders"
            :key="order.orderId"
            class="mb-2 cursor-pointer rounded-[14px] border border-transparent bg-[#fafbfc] p-3"
            :class="{ 'border-[#409eff] bg-[#ecf5ff]': selectedOrder?.orderId === order.orderId }"
            @click="selectOrder(order)"
          >
            <div class="mb-1.5 flex justify-between">
              <span class="font-600">{{ order.orderNo }}</span>
              <el-tag :type="order.orderStatusTag" size="small">{{ order.orderStatusText }}</el-tag>
            </div>
            <div class="text-[12px] text-[#666]">关联案件: {{ order.caseNo || '—' }}</div>
            <div class="my-1 text-[12px] text-[#666]">设备编号: {{ order.deviceCode || '—' }}</div>
            <div class="text-[12px] text-[#666]">创建: {{ order.createTimeText }}</div>
          </div>
          <el-empty v-if="!paginatedOrders.length" description="暂无工单数据" :image-size="80" />
        </div>
        <div class="border-t border-[#eee] p-3 text-center">
          <el-pagination small layout="prev, pager, next" :total="filteredOrders.length" :page-size="pageSize" v-model:current-page="currentPage" />
        </div>
      </div>

      <div class="flex-1 overflow-y-auto rounded-[20px] bg-white p-5" v-if="selectedOrder" v-loading="detailLoading">
        <el-tabs v-model="activeTab">
          <el-tab-pane label="工单信息" name="info">
            <div class="mb-3 mt-4 flex items-center gap-2 text-[16px] font-600">
              <span><el-icon><Document /></el-icon> 工单基本信息</span>
            </div>
            <el-descriptions :column="2" border>
              <el-descriptions-item label="工单编号">{{ selectedOrder.orderNo }}</el-descriptions-item>
              <el-descriptions-item label="工单状态">
                <el-tag :type="selectedOrder.orderStatusTag">{{ selectedOrder.orderStatusText }}</el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="关联案件编号">{{ selectedOrder.caseNo || '—' }}</el-descriptions-item>
              <el-descriptions-item label="设备编号">{{ selectedOrder.deviceCode || '—' }}</el-descriptions-item>
              <el-descriptions-item label="优先级">
                <el-tag :type="selectedOrder.orderLevelTag">{{ selectedOrder.orderLevelText }}</el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="工单类型">{{ selectedOrder.orderTypeText }}</el-descriptions-item>
              <el-descriptions-item label="问题描述" :span="2">{{ selectedOrder.orderDesc || '—' }}</el-descriptions-item>
              <el-descriptions-item label="设备类别">{{ selectedOrder.equipmentTypeName || '—' }}</el-descriptions-item>
              <el-descriptions-item label="派单时间">{{ selectedOrder.dispatchTimeText }}</el-descriptions-item>
              <el-descriptions-item label="创建时间">{{ selectedOrder.createTimeText }}</el-descriptions-item>
              <el-descriptions-item label="计划完成时间">{{ selectedOrder.planFinishTimeText }}</el-descriptions-item>
              <el-descriptions-item label="延期原因">{{ selectedOrder.delayedReason || '—' }}</el-descriptions-item>
              <el-descriptions-item label="延期截止时间">{{ selectedOrder.delayedDeadlineText }}</el-descriptions-item>
              <el-descriptions-item label="验收时间">{{ selectedOrder.verifyTimeText }}</el-descriptions-item>
              <el-descriptions-item label="实际完成时间">{{ selectedOrder.realFinishTimeText }}</el-descriptions-item>
              <el-descriptions-item label="运维状态">{{ selectedOrder.currentStatusText }}</el-descriptions-item>
              <el-descriptions-item label="在线状态">{{ selectedOrder.onlineStatusText }}</el-descriptions-item>
              <el-descriptions-item label="报警状态">{{ selectedOrder.alarmStatusText }}</el-descriptions-item>
              <el-descriptions-item label="处置结果" :span="2">{{ selectedOrder.repairResult || '—' }}</el-descriptions-item>
            </el-descriptions>

            <RepairImagePanel :before-images="selectedOrder.maintenanceBeforeImg" :after-images="selectedOrder.maintenanceAfterImg" />

            <div class="mt-5 border-t border-[#e9ecef] pt-3">
              <div class="mb-3 mt-4 flex items-center gap-2 text-[16px] font-600">
                <span><el-icon><Timer /></el-icon> 工单操作</span>
              </div>
              <div class="mb-3 flex items-center gap-3" v-if="canDispatch(selectedOrder)">
                <el-input v-model="receiveUserDisplay" readonly placeholder="请选择接单人" class="w-[260px]" />
                <el-button @click="openDispatchDialog">选择人员</el-button>
                <el-button type="primary" @click="dispatchOrder">下派任务</el-button>
              </div>
              <div class="flex flex-wrap gap-3">
                <el-button v-if="canAcceptOrder(selectedOrder)" type="warning" @click="acceptOrder">接单</el-button>
                <el-button v-if="canStartRepair(selectedOrder)" type="primary" @click="startRepair">开始维修</el-button>
                <el-button v-if="canSubmitVerify(selectedOrder)" type="warning" @click="submitVerify">提交验收</el-button>
                <el-button v-if="canApprove(selectedOrder)" type="success" @click="approveOrder(true)">验收通过</el-button>
                <el-button v-if="canApprove(selectedOrder)" type="danger" @click="approveOrder(false)">驳回工单</el-button>
                <el-button v-if="canApproveDelay(selectedOrder)" type="success" @click="approveDelay">延期审核通过</el-button>
                <el-button v-if="canRejectDelay(selectedOrder)" type="danger" @click="rejectDelay">驳回延期</el-button>
                <el-button v-if="canDelay(selectedOrder)" type="info" plain @click="openDelayDialog">申请延期</el-button>
              </div>
              <el-empty v-if="!hasOperationButtons(selectedOrder)" description="当前状态暂无可操作项" :image-size="80" />
            </div>
          </el-tab-pane>

          <el-tab-pane label="处理历史" name="history">
            <el-timeline v-if="selectedOrder.workOrderLogList?.length">
              <el-timeline-item
                v-for="log in selectedOrder.workOrderLogList"
                :key="log.logId"
                :timestamp="formatDateTime(log.operTime)"
                :type="getLogType(log.operType)"
              >
                <div>
                  <span>{{ log.operDesc }}</span>
                  <span v-if="log.operUserName" class="ml-3 text-[12px] text-[#909399]">操作人：{{ log.operUserName }}</span>
                  <!-- 显示处理图片（如果有的话） -->
                  <div v-if="log.maintenanceImages && log.maintenanceImages.length" class="mt-2 flex gap-2">
                    <div
                      v-for="(img, idx) in log.maintenanceImages"
                      :key="idx"
                      class="cursor-pointer rounded border p-1 hover:shadow-md"
                      @click="() => previewImage(img.url)"
                    >
                      <img :src="img.url" alt="处理图片" class="h-[60px] w-[80px] object-cover" />
                      <div class="text-center text-xs text-[#909399]">
                        {{ img.type === 'before' ? '⚠️ 处理前' : img.type === 'after' ? '✅ 处理后' : '🖼️ 图片' }}
                      </div>
                    </div>
                  </div>
                </div>
              </el-timeline-item>
            </el-timeline>
            <el-empty v-else description="暂无工单日志" :image-size="80" />
          </el-tab-pane>
        </el-tabs>
      </div>

      <div v-else class="flex flex-1 items-center justify-center rounded-[20px] bg-white">
        <el-empty description="请从左侧选择工单进行处理" :image-size="140" />
      </div>
    </div>

    <el-dialog v-model="beforeImageDialogVisible" title="开始维修" width="600px">
      <ImageUpload v-model="maintenanceBeforeImages" :limit="9" :isShowTip="true" :upload-url="imageUploadUrl" />
      <template #footer>
        <el-button @click="beforeImageDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitStartRepair">确定</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="afterImageDialogVisible" title="提交验收" width="600px">
      <ImageUpload v-model="maintenanceAfterImages" :limit="9" :isShowTip="true" :upload-url="imageUploadUrl" />
      <template #footer>
        <el-button @click="afterImageDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitVerify">提交</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="delayDialogVisible" title="申请延期" width="450px">
      <el-form label-width="88px">
        <el-form-item label="截止时间">
          <el-date-picker
            v-model="delayDeadline"
            type="datetime"
            value-format="YYYY-MM-DD HH:mm:ss"
            placeholder="选择截止时间"
            class="w-full"
          />
        </el-form-item>
        <el-form-item label="申请理由">
          <el-input type="textarea" v-model="delayReason" placeholder="请详细说明延期理由" rows="3" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="delayDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitDelay">提交申请</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="dispatchDialogVisible" title="下派任务" width="860px">
      <div class="flex gap-4">
        <div class="w-[260px] overflow-auto rounded-lg border border-[#ebeef5] p-3">
          <div class="mb-3 font-600">部门树</div>
          <el-input
            v-model="deptKeyword"
            placeholder="筛选部门"
            clearable
            size="small"
            class="mb-3"
          />
          <el-tree
            ref="deptTreeRef"
            :data="deptOptions"
            node-key="id"
            :props="{ label: 'label', children: 'children' }"
            default-expand-all
            highlight-current
            :filter-node-method="filterDeptNode"
            @node-click="handleDeptClick"
          />
        </div>
        <div class="flex-1 rounded-lg border border-[#ebeef5] p-3">
          <div class="mb-3 font-600">用户列表</div>
          <el-table
            :data="dispatchUsers"
            height="360"
            border
            highlight-current-row
            v-loading="dispatchUserLoading"
            @current-change="handleUserCurrentChange"
            @row-click="handleUserCurrentChange"
          >
            <el-table-column prop="userName" label="用户名" min-width="120" />
            <el-table-column prop="nickName" label="昵称" min-width="120" />
            <el-table-column prop="dept.deptName" label="部门" min-width="140" show-overflow-tooltip />
          </el-table>
          <div class="mt-3 text-[#606266]">
            已选人员：{{ dispatchSelectedUser ? `${dispatchSelectedUser.userName}${dispatchSelectedUser.nickName ? ` / ${dispatchSelectedUser.nickName}` : ''}` : '未选择' }}
          </div>
        </div>
      </div>
      <template #footer>
        <el-button @click="dispatchDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmDispatchUser">确认选择</el-button>
      </template>
    </el-dialog>

    <!-- 图片预览弹窗 -->
    <el-dialog v-model="imagePreviewVisible" title="图片预览" width="600px" append-to-body>
      <img :src="currentImagePreviewUrl" alt="工单图片" class="max-w-full" style="border-radius: 4px;" />
    </el-dialog>
  </div>
</template>

<script setup>
import{computed, nextTick, onMounted, ref, watch} from 'vue'
import {Document, Search, Tickets, Timer} from '@element-plus/icons-vue'
import {ElMessage} from 'element-plus'
import ImageUpload from '@/components/ImageUpload/index.vue'
import RepairImagePanel from '@/components/RepairImagePanel/index.vue'
import {getManholeWorkOrderDetail, getManholeWorkOrderPage, operManholeWorkOrder} from '@/api/pipeNetwork/basic'
import {deptTreeSelect, listUser} from '@/api/system/user'

const DEFAULT_OPER_USER_ID = 1

const orders = ref([])
const loading = ref(false)
const detailLoading = ref(false)
const searchKeyword = ref('')
const statusFilter = ref('')
const currentPage = ref(1)
const pageSize = 5
const selectedOrder = ref(null)
const activeTab = ref('info')
const receiveUserId = ref(null)
const receiveUserDisplay = ref('')
const delayDialogVisible = ref(false)
const delayDeadline = ref('')
const delayReason = ref('')
const beforeImageDialogVisible = ref(false)
const afterImageDialogVisible = ref(false)
const maintenanceBeforeImages = ref('')
const maintenanceAfterImages = ref('')
const imageUploadUrl = import.meta.env.VITE_APP_BASE_API + '/minio/upload'
const dispatchDialogVisible = ref(false)
const dispatchUserLoading = ref(false)
const deptOptions = ref([])
const deptKeyword = ref('')
const selectedDeptId = ref(undefined)
const dispatchUsers = ref([])
const dispatchSelectedUser = ref(null)
const deptTreeRef = ref(null)

// 图片预览相关
const imagePreviewVisible = ref(false)
const currentImagePreviewUrl = ref('')
const baseUrl = import.meta.env.VITE_APP_BASE_API

function formatDateTime(value) {
  if (!value) return '—'
  return String(value).replace('T', ' ')
}

const maintenanceBeforeImageList = computed(() => splitImageList(selectedOrder.value?.maintenanceBeforeImg))
const maintenanceAfterImageList = computed(() => splitImageList(selectedOrder.value?.maintenanceAfterImg))

function previewImage(url) {
  currentImagePreviewUrl.value = url
  imagePreviewVisible.value = true
}

function getOrderLevelMeta(level) {
  const map = {
    1: { text: '紧急', tag: 'danger' },
    2: { text: '一般', tag: 'warning' },
    3: { text: '低', tag: 'info' }
  }
  return map[Number(level)] || { text: '—', tag: 'info' }
}

function getOrderTypeText(type) {
  const map = {
    1: '故障维修',
    2: '日常巡检',
    3: '设备保养'
  }
  return map[Number(type)] || '—'
}

function getOrderStatusMeta(status) {
  const map = {
    1: { key: 'pending', text: '待派单', tag: 'danger' },
    2: { key: 'pending', text: '待接单', tag: 'danger' },
    3: { key: 'processing', text: '已接单', tag: 'warning' },
    4: { key: 'processing', text: '处理中', tag: 'warning' },
    5: { key: 'verify', text: '待验收', tag: 'primary' },
    6: { key: 'completed', text: '已结案', tag: 'success' },
    7: { key: 'completed', text: '已驳回', tag: 'danger' },
    8: { key: 'processing', text: '延期审核', tag: 'warning' },
    9: { key: 'pending', text: '延期待接单', tag: 'warning' }
  }
  return map[Number(status)] || { key: '', text: '—', tag: 'info' }
}

function getCurrentStatusText(status) {
  const map = {
    1: '在用',
    2: '闲置',
    3: '维修',
    4: '报废',
    5: '待入库'
  }
  return map[Number(status)] || '—'
}

function getOnlineStatusText(status) {
  const map = {
    0: '离线',
    1: '在线'
  }
  return map[Number(status)] || '—'
}

function getAlarmStatusText(status) {
  const map = {
    0: '正常',
    1: '报警'
  }
  return map[Number(status)] || '—'
}

function normalizeOrder(item) {
  const levelMeta = getOrderLevelMeta(item.orderLevel)
  const statusMeta = getOrderStatusMeta(item.orderStatus)
  return {
    ...item,
    orderLevelText: levelMeta.text,
    orderLevelTag: levelMeta.tag,
    orderTypeText: getOrderTypeText(item.orderType),
    orderStatusKey: statusMeta.key,
    orderStatusText: statusMeta.text,
    orderStatusTag: statusMeta.tag,
    createTimeText: formatDateTime(item.createTime),
    dispatchTimeText: formatDateTime(item.dispatchTime),
    planFinishTimeText: formatDateTime(item.planFinishTime),
    delayedDeadlineText: formatDateTime(item.delayedDeadline),
    realFinishTimeText: formatDateTime(item.realFinishTime),
    verifyTimeText: formatDateTime(item.verifyTime),
    updateTimeText: formatDateTime(item.updateTime),
    currentStatusText: getCurrentStatusText(item.equipmentStatus?.currentStatus),
    onlineStatusText: getOnlineStatusText(item.equipmentStatus?.onlineStatus),
    alarmStatusText: getAlarmStatusText(item.equipmentStatus?.alarmStatus),
    statusUpdateTimeText: formatDateTime(item.equipmentStatus?.statusUpdateTime)
  }
}

const filteredOrders = computed(() => {
  if (!statusFilter.value) return orders.value
  return orders.value.filter(item => item.orderStatusKey === statusFilter.value)
})

const paginatedOrders = computed(() => {
  const start = (currentPage.value - 1) * pageSize
  return filteredOrders.value.slice(start, start + pageSize)
})

const totalOrders = computed(() => orders.value.length)
const pendingCount = computed(() => orders.value.filter(item => item.orderStatusKey === 'pending').length)
const processingCount = computed(() => orders.value.filter(item => item.orderStatusKey === 'processing').length)
const verifyCount = computed(() => orders.value.filter(item => item.orderStatusKey === 'verify').length)
const completedCount = computed(() => orders.value.filter(item => item.orderStatusKey === 'completed').length)

async function loadOrders() {
  loading.value = true
  try {
    const keyword = searchKeyword.value.trim()
    const res = await getManholeWorkOrderPage({
      pageNum: 1,
      pageSize: 200,
      orderNo: keyword || undefined,
      caseNo: keyword || undefined
    })
    const records = Array.isArray(res?.data?.records) ? res.data.records : []
    orders.value = records.map(normalizeOrder)
    currentPage.value = 1
    const first = filteredOrders.value[0]
    if (!first) {
      selectedOrder.value = null
      return
    }
    if (selectedOrder.value) {
      const matched = orders.value.find(item => item.orderId === selectedOrder.value.orderId)
      if (matched) {
        await selectOrder(matched)
        return
      }
    }
    await selectOrder(first)
  } catch (error) {
    orders.value = []
    selectedOrder.value = null
    ElMessage.error('工单列表加载失败')
  } finally {
    loading.value = false
  }
}

async function selectOrder(order) {
  detailLoading.value = true
  receiveUserId.value = order.receiveUser || null
  receiveUserDisplay.value = order.receiveUser ? '已选择接单人' : ''
  try {
    const res = await getManholeWorkOrderDetail(order.orderId)
    selectedOrder.value = normalizeOrder(res?.data || order)
    receiveUserId.value = selectedOrder.value.receiveUser || null
    receiveUserDisplay.value = selectedOrder.value.receiveUser ? '已选择接单人' : ''
  } catch (error) {
    selectedOrder.value = order
    ElMessage.error('工单详情加载失败')
  } finally {
    detailLoading.value = false
  }
}

function filterStatus(status) {
  statusFilter.value = status
  currentPage.value = 1
  const first = filteredOrders.value[0]
  if (first) {
    selectOrder(first)
  }
}

function canDispatch(order) {
  return Number(order.orderStatus) === 1
}

function canAcceptOrder(order) {
  return [2, 9].includes(Number(order.orderStatus))
}

function canStartRepair(order) {
  return Number(order.orderStatus) === 3
}

function canSubmitVerify(order) {
  return Number(order.orderStatus) === 4
}

function canApprove(order) {
  return Number(order.orderStatus) === 5
}

function canApproveDelay(order) {
  return Number(order.orderStatus) === 8
}

function canRejectDelay(order) {
  return Number(order.orderStatus) === 8
}

function canDelay(order) {
  return [2, 3, 4].includes(Number(order.orderStatus))
}

function hasOperationButtons(order) {
  if (!order) return false
  return (
    canDispatch(order) ||
    canAcceptOrder(order) ||
    canStartRepair(order) ||
    canSubmitVerify(order) ||
    canApprove(order) ||
    canApproveDelay(order) ||
    canRejectDelay(order) ||
    canDelay(order)
  )
}

async function operateCurrent(operType, operDesc, extra = {}) {
  if (!selectedOrder.value?.orderId) return
  await operManholeWorkOrder({
    orderId: selectedOrder.value.orderId,
    operType,
    operDesc,
    operUserId: DEFAULT_OPER_USER_ID,
    ...extra
  })
  await loadOrders()
}

async function dispatchOrder() {
  if (!receiveUserId.value) {
    ElMessage.warning('请先选择接单人')
    return
  }
  try {
    const receiveUserName = dispatchSelectedUser.value?.userName || '指定人员'
    await operateCurrent(2, `下派工单至${receiveUserName}`, { receiveUser: Number(receiveUserId.value) })
    ElMessage.success('工单下派成功')
  } catch (error) {
    ElMessage.error(error?.message || '工单下派失败')
  }
}

function filterDeptNode(value, data) {
  if (!value) return true
  return data.label?.includes(value)
}

watch(deptKeyword, value => {
  nextTick(() => {
    deptTreeRef.value?.filter(value)
  })
})

async function loadDeptTree() {
  const res = await deptTreeSelect()
  deptOptions.value = Array.isArray(res?.data) ? res.data : []
}

async function loadDispatchUsers(deptId) {
  dispatchUserLoading.value = true
  try {
    const res = await listUser({
      pageNum: 1,
      pageSize: 100,
      deptId,
      status: '0'
    })
    dispatchUsers.value = Array.isArray(res?.rows) ? res.rows : []
  } catch (error) {
    dispatchUsers.value = []
    ElMessage.error('用户列表加载失败')
  } finally {
    dispatchUserLoading.value = false
  }
}

async function openDispatchDialog() {
  dispatchDialogVisible.value = true
  dispatchSelectedUser.value = null
  dispatchUsers.value = []
  deptKeyword.value = ''
  if (!deptOptions.value.length) {
    await loadDeptTree()
  }
  const firstDept = findFirstDept(deptOptions.value)
  if (firstDept?.id) {
    selectedDeptId.value = firstDept.id
    await nextTick()
    deptTreeRef.value?.setCurrentKey(firstDept.id)
    await loadDispatchUsers(firstDept.id)
  }
}

function findFirstDept(nodes = []) {
  for (const node of nodes) {
    if (node?.id) return node
    if (node?.children?.length) {
      const child = findFirstDept(node.children)
      if (child) return child
    }
  }
  return null
}

function handleDeptClick(data) {
  selectedDeptId.value = data.id
  loadDispatchUsers(data.id)
}

function handleUserCurrentChange(row) {
  dispatchSelectedUser.value = row || null
}

function confirmDispatchUser() {
  if (!dispatchSelectedUser.value?.userId) {
    ElMessage.warning('请选择用户')
    return
  }
  receiveUserId.value = dispatchSelectedUser.value.userId
  receiveUserDisplay.value = `${dispatchSelectedUser.value.userName}${dispatchSelectedUser.value.nickName ? ` / ${dispatchSelectedUser.value.nickName}` : ''}`
  dispatchDialogVisible.value = false
}

async function acceptOrder() {
  try {
    await operateCurrent(3, '接单')
    ElMessage.success('已接单')
  } catch (error) {
    ElMessage.error(error?.message || '接单失败')
  }
}

async function startRepair() {
  maintenanceBeforeImages.value = ''
  beforeImageDialogVisible.value = true
}

function normalizeImageUrl(value) {
  const url = String(value || '').trim()
  if (!url || /^(https?:|blob:|data:)/.test(url)) return url
  if (baseUrl && (url === baseUrl || url.startsWith(`${baseUrl}/`))) return url
  return url.startsWith('/') ? baseUrl + url : `${baseUrl}/${url}`
}

function splitImageList(value) {
  return value
    ? String(value).split(',').map(normalizeImageUrl).filter(Boolean)
    : []
}

async function submitStartRepair() {
  try {
    await operateCurrent(4, '开始维修', { maintenanceBeforeImg: maintenanceBeforeImages.value })
    beforeImageDialogVisible.value = false
    ElMessage.success('已开始维修')
  } catch (error) {
    ElMessage.error(error?.message || '开始维修失败')
  }
}

async function submitVerify() {
  if (!afterImageDialogVisible.value) {
    maintenanceAfterImages.value = ''
    afterImageDialogVisible.value = true
    return
  }
  try {
    await operateCurrent(5, '提交验收', { maintenanceAfterImg: maintenanceAfterImages.value })
    afterImageDialogVisible.value = false
    ElMessage.success('已提交验收')
  } catch (error) {
    ElMessage.error(error?.message || '提交验收失败')
  }
}

async function approveOrder(isApproved) {
  try {
    await operateCurrent(isApproved ? 6 : 7, isApproved ? '验收通过' : '驳回工单')
    ElMessage.success(isApproved ? '验收已通过' : '工单已驳回')
  } catch (error) {
    ElMessage.error(error?.message || '工单操作失败')
  }
}

async function approveDelay() {
  try {
    await operateCurrent(9, '延期审核通过')
    ElMessage.success('延期审核已通过')
  } catch (error) {
    ElMessage.error(error?.message || '延期审核通过失败')
  }
}

async function rejectDelay() {
  try {
    await operateCurrent(7, '驳回延期')
    ElMessage.success('延期申请已驳回')
  } catch (error) {
    ElMessage.error(error?.message || '驳回延期失败')
  }
}

function openDelayDialog() {
  delayDeadline.value = ''
  delayReason.value = ''
  delayDialogVisible.value = true
}

async function submitDelay() {
  if (!delayDeadline.value) {
    ElMessage.warning('请选择截止时间')
    return
  }
  if (!delayReason.value.trim()) {
    ElMessage.warning('请填写延期理由')
    return
  }
  try {
    await operateCurrent(8, '申请延期', {
      delayedDeadline: delayDeadline.value,
      delayedReason: delayReason.value.trim()
    })
    delayDialogVisible.value = false
    ElMessage.success('延期申请已提交')
  } catch (error) {
    ElMessage.error(error?.message || '延期申请失败')
  }
}

function getLogType(operType) {
  const map = {
    2: 'primary',
    3: 'warning',
    4: 'primary',
    5: 'warning',
    6: 'success',
    7: 'danger',
    8: 'warning',
    9: 'warning'
  }
  return map[Number(operType)] || 'info'
}

onMounted(() => {
  loadOrders()
})
</script>

<style scoped lang="scss">
.repair-image-panel {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid #e9ecef;
}

.repair-image-panel__header,
.repair-image-column__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.repair-image-panel__header {
  margin-bottom: 12px;
}

.repair-image-panel__title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
}

.repair-image-panel__total {
  color: #909399;
  font-size: 13px;
}

.repair-image-panel__body {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.repair-image-column {
  min-width: 0;
  padding: 14px;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  background: #fafbfc;
}

.repair-image-column__header {
  margin-bottom: 12px;
  color: #606266;
  font-size: 14px;
  font-weight: 600;
}

.repair-image-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(116px, 1fr));
  gap: 10px;
}

.repair-image-item {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid #dcdfe6;
  border-radius: 6px;
  background: #f2f6fc;
  cursor: pointer;
}

.repair-image-item:hover img {
  transform: scale(1.04);
}

.repair-image-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.2s ease;
}

.repair-image-item__index {
  position: absolute;
  right: 5px;
  bottom: 5px;
  min-width: 20px;
  padding: 2px 5px;
  border-radius: 10px;
  background: rgb(0 0 0 / 55%);
  color: #fff;
  font-size: 12px;
  line-height: 16px;
  text-align: center;
}

.repair-image-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  border: 1px dashed #dcdfe6;
  border-radius: 6px;
  color: #a8abb2;
  font-size: 13px;
}

@media (max-width: 900px) {
  .repair-image-panel__body {
    grid-template-columns: 1fr;
  }
}
</style>
