<template>
  <el-drawer
    title="任务详情"
    :visible.sync="drawerVisible"
    direction="rtl"
    size="700px"
    :before-close="handleClose"
    @opened="handleOpened"
  >
    <div v-if="loading" class="drawer-loading">
      <i class="el-icon-loading"></i>
      <span>加载中...</span>
    </div>

    <div v-else-if="taskData" class="task-drawer-content">
      <div class="drawer-header">
        <div class="task-title">
          <span class="task-name">{{ taskData.name || '未命名任务' }}</span>
          <el-tag :type="getStatusTagType(taskData.status)" size="medium">
            {{ getStatusLabel(taskData.status) }}
          </el-tag>
        </div>
        <div class="task-header-right">
          <div class="task-code">{{ taskData.taskNo || '-' }}</div>
          <div class="task-actions">
            <el-button
              v-if="taskData.status === 'draft'"
              type="primary"
              size="small"
              @click="handlePublish"
            >
              发布任务
            </el-button>
            <el-button
              v-if="taskData.status === 'draft'"
              type="danger"
              size="small"
              @click="handleDelete"
            >
              删除任务
            </el-button>
            <el-button
              v-if="taskData.status === 'published' || taskData.status === 'in_progress'"
              type="danger"
              size="small"
              @click="handleAbort"
            >
              取消任务
            </el-button>
            <el-button
              v-if="taskData.status === 'in_progress'"
              type="warning"
              size="small"
              @click="handleCloseTask"
            >
              关闭任务
            </el-button>
          </div>
        </div>
      </div>

      <el-divider content-position="left">任务信息</el-divider>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="任务编号">{{ taskData.taskNo || '-' }}</el-descriptions-item>
        <el-descriptions-item label="任务状态">{{ getStatusLabel(taskData.status) }}</el-descriptions-item>
        <el-descriptions-item label="创建时间">{{ formatDateTime(taskData.createTime) }}</el-descriptions-item>
        <el-descriptions-item label="更新时间">{{ formatDateTime(taskData.updateTime) }}</el-descriptions-item>
      </el-descriptions>

      <el-divider content-position="left">任务描述</el-divider>
      <div class="remark-section">
        {{ taskData.description || '暂无描述' }}
      </div>

      <!-- Associated Event Section -->
      <el-divider content-position="left">关联事件</el-divider>
      <div v-if="eventData" class="event-section">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="事件名称">{{ eventData.title || '-' }}</el-descriptions-item>
          <el-descriptions-item label="事件编号">{{ eventData.eventNo || '-' }}</el-descriptions-item>
          <el-descriptions-item label="事件状态">{{ getEventStatusLabel(eventData.status) }}</el-descriptions-item>
          <el-descriptions-item label="发生时间">{{ formatDateTime(eventData.occurredAt) }}</el-descriptions-item>
          <el-descriptions-item label="事件位置" :span="2">{{ eventData.location || '-' }}</el-descriptions-item>
        </el-descriptions>

        <div v-if="hasEventLocation() && mapReady" class="drawer-map-section">
          <div class="map-container">
            <Amap
              container-id="task-event-map"
              width="100%"
              height="260px"
              :center="[eventData.longitude, eventData.latitude]"
              :zoom="15"
              :markers="[
                {
                  lat: eventData.latitude,
                  lng: eventData.longitude,
                  title: eventData.title || eventData.eventNo || '事件'
                }
              ]"
            />
          </div>
        </div>

        <div class="event-actions">
          <el-button size="small" @click="viewEventDetail">查看事件详情</el-button>
          <el-button size="small" type="primary" @click="locateEvent">定位事件</el-button>
        </div>
      </div>
      <div v-else-if="taskData.eventId" class="event-loading">
        <i class="el-icon-loading"></i>
        <span>加载事件信息中...</span>
      </div>
      <div v-else class="event-empty">
        <el-empty description="未关联事件" :image-size="80" />
      </div>

      <!-- Participants Section -->
      <el-divider content-position="left">
        <span>参与方</span>
        <el-button
          v-if="canManageParticipants"
          type="text"
          size="mini"
          icon="el-icon-plus"
          @click="showAddParticipantDialog = true"
          style="margin-left: 8px;"
        >
          添加参与方
        </el-button>
      </el-divider>
      <div v-if="participantsLoading" class="section-loading">
        <i class="el-icon-loading"></i>
        <span>加载中...</span>
      </div>
      <div v-else-if="participants && participants.length > 0" class="participants-section">
        <el-table :data="participants" border size="small" :show-header="true">
          <el-table-column prop="personName" label="姓名" width="120">
            <template slot-scope="scope">
              {{ getPersonName(scope.row) }}
            </template>
          </el-table-column>
          <el-table-column prop="teamName" label="所属队伍" width="150">
            <template slot-scope="scope">
              {{ getTeamName(scope.row) || '-' }}
            </template>
          </el-table-column>
          <el-table-column prop="role" label="角色" width="100">
            <template slot-scope="scope">
              {{ getPersonRole(scope.row) || '-' }}
            </template>
          </el-table-column>
          <el-table-column prop="distance" label="距离" width="100" v-if="hasEventLocation()">
            <template slot-scope="scope">
              {{ getParticipantDistance(scope.row) }}
            </template>
          </el-table-column>
          <el-table-column prop="contact" label="联系方式" min-width="120">
            <template slot-scope="scope">
              {{ getPersonContact(scope.row) || '-' }}
            </template>
          </el-table-column>
          <el-table-column
            v-if="canManageParticipants"
            label="操作"
            width="100"
            fixed="right"
          >
            <template slot-scope="scope">
              <el-dropdown trigger="click" @command="(cmd) => handleParticipantAction(cmd, scope.row)">
                <el-button size="mini" type="text">
                  更多操作<i class="el-icon-arrow-down el-icon--right"></i>
                </el-button>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="voice">
                    <i class="el-icon-phone"></i> 语音通话
                  </el-dropdown-item>
                  <el-dropdown-item command="sms">
                    <i class="el-icon-message"></i> 短信
                  </el-dropdown-item>
                  <el-dropdown-item command="video">
                    <i class="el-icon-video-camera"></i> 视频
                  </el-dropdown-item>
                  <el-dropdown-item command="internal">
                    <i class="el-icon-chat-line-round"></i> 站内通信
                  </el-dropdown-item>
                  <el-dropdown-item command="delete" divided>
                    <i class="el-icon-delete"></i> 删除
                  </el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-else class="section-empty">
        <el-empty description="暂无参与方" :image-size="80">
          <el-button
            v-if="canManageParticipants"
            type="primary"
            size="small"
            icon="el-icon-plus"
            @click="showAddParticipantDialog = true"
          >
            添加参与方
          </el-button>
        </el-empty>
      </div>
      
      <!-- Add Participant Dialog -->
      <AddParticipantDialog
        :visible.sync="showAddParticipantDialog"
        :task-id="taskId"
        :existing-participants="participants"
        @success="handleParticipantAdded"
      />

      <!-- Steps Section -->
      <el-divider content-position="left">
        <span>行动项</span>
        <el-button
          v-if="canManageSteps"
          type="text"
          size="mini"
          icon="el-icon-plus"
          @click="handleAddStep"
          style="margin-left: 8px;"
        >
          添加行动项
        </el-button>
      </el-divider>
      <div v-if="stepsLoading" class="section-loading">
        <i class="el-icon-loading"></i>
        <span>加载中...</span>
      </div>
      <div v-else-if="steps && steps.length > 0" class="steps-section">
        <el-timeline>
          <el-timeline-item
            v-for="step in sortedSteps"
            :key="step.id"
            :timestamp="formatDateTime(step.createTime)"
            :type="getStepType(step.status)"
            placement="top"
          >
            <div class="step-item">
              <div class="step-header">
                <span class="step-title">{{ step.title || `行动项 #${step.stepOrder || step.id}` }}</span>
                <div class="step-header-right">
                  <el-tag :type="getStepStatusTagType(step.status)" size="mini">
                    {{ getStepStatusLabel(step.status) }}
                  </el-tag>
                  <div v-if="canManageSteps" class="step-actions">
                    <el-button
                      type="text"
                      size="mini"
                      icon="el-icon-setting"
                      @click="handleManageResources(step)"
                    >
                      管理资源
                    </el-button>
                    <el-button
                      type="text"
                      size="mini"
                      icon="el-icon-edit"
                      @click="handleEditStep(step)"
                    >
                      编辑
                    </el-button>
                    <!-- 暂时隐藏删除按钮，因为后端不支持删除行动项 -->
                    <!-- <el-button
                      type="text"
                      size="mini"
                      icon="el-icon-delete"
                      style="color: #f56c6c;"
                      @click="handleDeleteStep(step)"
                    >
                      删除
                    </el-button> -->
                  </div>
                  <div v-else-if="canExecuteSteps" class="step-actions">
                    <el-button
                      v-if="step.status === 'pending'"
                      type="text"
                      size="mini"
                      icon="el-icon-video-play"
                      @click="handleStartStep(step)"
                    >
                      开始执行
                    </el-button>
                    <el-button
                      v-if="step.status === 'in_progress'"
                      type="text"
                      size="mini"
                      icon="el-icon-check"
                      style="color: #67c23a;"
                      @click="handleCompleteStep(step)"
                    >
                      标记完成
                    </el-button>
                    <el-button
                      v-if="step.status === 'in_progress'"
                      type="text"
                      size="mini"
                      icon="el-icon-close"
                      style="color: #f56c6c;"
                      @click="handleFailStep(step)"
                    >
                      标记失败
                    </el-button>
                  </div>
                </div>
              </div>
              <div v-if="step.description" class="step-description">
                {{ step.description }}
              </div>
              <div v-if="getExecutorInfo(step)" class="step-executor">
                执行人: {{ getExecutorInfo(step) }}
              </div>
              <div v-if="getStepResources(step).length > 0" class="step-resources">
                <div class="step-resources-label">
                  所需资源:
                  <el-button
                    v-if="canManageSteps"
                    type="text"
                    size="mini"
                    icon="el-icon-setting"
                    style="margin-left: 8px;"
                    @click="handleManageResources(step)"
                  >
                    管理
                  </el-button>
                </div>
                <div class="step-resources-list">
                  <el-tag
                    v-for="resource in getStepResources(step)"
                    :key="resource.id"
                    :type="getResourceTagType(resource.resourceType)"
                    size="mini"
                    style="margin-right: 8px; margin-bottom: 4px; cursor: pointer;"
                    @click="canManageSteps && handleManageResources(step)"
                    :title="canManageSteps ? '点击管理资源' : ''"
                  >
                    {{ getResourceLabel(resource) }}
                  </el-tag>
                </div>
              </div>
              <div v-else-if="canManageSteps" class="step-resources">
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-plus"
                  @click="handleManageResources(step)"
                >
                  添加资源
                </el-button>
              </div>
              <div v-if="step.status === 'completed' && step.updateTime" class="step-completion-time">
                完成时间: {{ formatDateTime(step.updateTime) }}
              </div>
              <div v-if="step.status === 'failed' && step.updateTime" class="step-failure-time">
                失败时间: {{ formatDateTime(step.updateTime) }}
              </div>
            </div>
          </el-timeline-item>
        </el-timeline>
      </div>
      <div v-else class="section-empty">
        <el-empty description="暂无行动项" :image-size="80" />
        <el-button
          v-if="canManageSteps"
          type="primary"
          size="small"
          icon="el-icon-plus"
          @click="handleAddStep"
          style="margin-top: 16px;"
        >
          添加行动项
        </el-button>
      </div>

      <!-- Step Form Dialog -->
      <StepFormDialog
        :visible.sync="showStepFormDialog"
        :step-data="currentStep"
        :participants="participants"
        @submit="handleStepSubmit"
      />

      <!-- Step Resource Allocation Dialog -->
      <StepResourceAllocationDialog
        :visible.sync="showResourceAllocationDialog"
        :task-id="taskId"
        :step-id="currentResourceStep ? currentResourceStep.id : null"
        @resource-updated="handleResourceUpdated"
        @resource-removed="handleResourceRemoved"
      />
    </div>

    <div v-else class="drawer-error">
      <el-alert
        title="加载失败"
        type="error"
        :closable="false"
        show-icon
      >
        <template #default>
          <p>无法加载任务详情，请稍后重试</p>
          <el-button size="mini" @click="loadTaskDetail">重试</el-button>
        </template>
      </el-alert>
    </div>
  </el-drawer>
</template>

<script>
import Amap from '@/components/Amap'
import { getDispatchTask, listDispatchParticipants, listDispatchSteps, publishDispatchTask, markDispatchTaskInProgress, closeDispatchTask, abortDispatchTask, removeDispatchTasks, removeDispatchParticipant, upsertDispatchSteps, startDispatchStep, completeDispatchStep, failDispatchStep, listDispatchResourceLinks, listDispatchStepResources } from '@/api/emergency/dispatchTask'
import { getEvent } from '@/api/emergency/event'
import { formatDateTime } from '@/views/duty/alert/utils/dateHelpers'
import { listMaterial } from '@/api/resource/material'
import { listEquipment } from '@/api/resource/equipment'
import { listVehicle } from '@/api/resource/vehicle'
import { listWarehouse } from '@/api/resource/warehouse'
import AddParticipantDialog from './AddParticipantDialog.vue'
import StepFormDialog from './StepFormDialog.vue'
import StepResourceAllocationDialog from './StepResourceAllocationDialog.vue'

export default {
  name: 'TaskDetailDrawer',
  components: {
    Amap,
    AddParticipantDialog,
    StepFormDialog,
    StepResourceAllocationDialog
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    taskId: {
      type: [Number, String],
      default: null
    }
  },
  data() {
    return {
      drawerVisible: false,
      loading: false,
      taskData: null,
      eventData: null,
      participants: [],
      participantsLoading: false,
      steps: [],
      stepsLoading: false,
      mapReady: false,
      showAddParticipantDialog: false,
      showStepFormDialog: false,
      currentStep: null,
      showResourceAllocationDialog: false,
      currentResourceStep: null,
      availableMaterials: [],
      availableEquipment: [],
      availableVehicles: [],
      warehouses: []
    }
  },
  computed: {
    canManageParticipants() {
      // Can add/remove participants when task is draft, published, or in_progress
      return this.taskData && 
        this.taskData.status !== 'closed' && 
        this.taskData.status !== 'cancelled'
    },
    canManageSteps() {
      // Allow managing steps until the task is closed or cancelled
      return this.taskData &&
        this.taskData.status !== 'closed' &&
        this.taskData.status !== 'cancelled'
    },
    canExecuteSteps() {
      // Can execute steps when task is published or in_progress
      return this.taskData && 
        (this.taskData.status === 'published' || this.taskData.status === 'in_progress')
    },
    sortedSteps() {
      if (!this.steps || this.steps.length === 0) return []
      return [...this.steps].sort((a, b) => {
        const orderA = a.stepOrder || 0
        const orderB = b.stepOrder || 0
        if (orderA !== orderB) return orderA - orderB
        return new Date(a.createTime || 0).getTime() - new Date(b.createTime || 0).getTime()
      })
    }
  },
  methods: {
    async loadTaskDetail() {
      if (!this.taskId) return
      this.loading = true
      this.mapReady = false
      try {
        const res = await getDispatchTask(this.taskId)
        if (res && res.code === 200) {
          this.taskData = res.data || null
          // Load associated event if eventId exists
          if (this.taskData && this.taskData.eventId) {
            this.loadEventData(this.taskData.eventId)
          }
          // Load available resources, participants and steps in parallel
          this.loadAvailableResources()
          this.loadParticipants()
          this.loadSteps()
        } else {
          this.taskData = null
        }
      } catch (error) {
        console.error('加载任务详情失败:', error)
        this.taskData = null
      } finally {
        this.loading = false
      }
    },
    async loadEventData(eventId) {
      try {
        const res = await getEvent(eventId)
        if (res && res.code === 200) {
          this.eventData = res.data || null
        }
      } catch (error) {
        console.error('加载事件信息失败:', error)
        this.eventData = null
      }
    },
    async loadParticipants() {
      if (!this.taskId) return
      this.participantsLoading = true
      try {
        const res = await listDispatchParticipants(this.taskId)
        if (res && res.code === 200) {
          this.participants = res.data || []
        } else {
          this.participants = []
        }
      } catch (error) {
        console.error('加载参与方失败:', error)
        this.participants = []
      } finally {
        this.participantsLoading = false
      }
    },
    async loadSteps() {
      if (!this.taskId) return
      this.stepsLoading = true
      try {
        const res = await listDispatchSteps(this.taskId)
        if (res && res.code === 200) {
          this.steps = res.data || []
          // Load resources for each step (don't block on errors)
          try {
            await this.loadStepResources()
          } catch (error) {
            console.error('加载行动项资源失败:', error)
            // Continue even if resource loading fails
          }
        } else {
          this.steps = []
        }
      } catch (error) {
        console.error('加载行动项失败:', error)
        this.steps = []
      } finally {
        this.stepsLoading = false
      }
    },
    async loadStepResources() {
      if (!this.taskId || !this.steps || this.steps.length === 0) return
      this.stepResources = {}
      // Load resources for each step in parallel
      const promises = this.steps.map(async (step) => {
        if (step.id) {
          try {
            const res = await listDispatchStepResources(this.taskId, step.id)
            if (res && res.code === 200) {
              this.$set(this.stepResources, step.id, res.data || [])
            } else {
              this.$set(this.stepResources, step.id, [])
            }
          } catch (error) {
            console.error(`加载行动项 ${step.id} 的资源失败:`, error)
            this.$set(this.stepResources, step.id, [])
          }
        }
      })
      await Promise.all(promises)
    },
    async loadAvailableResources() {
      // Load materials, equipment, vehicles, and warehouses in parallel
      try {
        const [materialsRes, equipmentRes, vehiclesRes, warehousesRes] = await Promise.all([
          listMaterial({ pageNum: 1, pageSize: 1000 }).catch(() => ({ code: 200, rows: [] })),
          listEquipment({ pageNum: 1, pageSize: 1000 }).catch(() => ({ code: 200, rows: [] })),
          listVehicle({ pageNum: 1, pageSize: 1000 }).catch(() => ({ code: 200, rows: [] })),
          listWarehouse({ pageNum: 1, pageSize: 1000 }).catch(() => ({ code: 200, rows: [] }))
        ])
        this.availableMaterials = materialsRes.rows || materialsRes.data || []
        this.availableEquipment = equipmentRes.rows || equipmentRes.data || []
        this.availableVehicles = vehiclesRes.rows || vehiclesRes.data || []
        this.warehouses = warehousesRes.rows || warehousesRes.data || []
      } catch (error) {
        console.error('加载可用资源失败:', error)
        // Continue with empty arrays
        this.availableMaterials = []
        this.availableEquipment = []
        this.availableVehicles = []
        this.warehouses = []
      }
    },
    handleClose(done) {
      this.reset()
      done()
    },
    handleOpened() {
      this.$nextTick(() => {
        setTimeout(() => {
          this.mapReady = true
        }, 100)
      })
    },
    reset() {
      this.taskData = null
      this.eventData = null
      this.participants = []
      this.steps = []
      this.stepResources = {}
      this.mapReady = false
    },
    hasEventLocation() {
      return this.eventData && this.eventData.longitude && this.eventData.latitude
    },
    viewEventDetail() {
      if (this.taskData && this.taskData.eventId) {
        this.$emit('view-event', this.taskData.eventId)
      }
    },
    locateEvent() {
      if (this.taskData && this.taskData.eventId) {
        this.$emit('locate-event', this.taskData.eventId)
      }
    },
    getStatusLabel(status) {
      const map = {
        draft: '草稿',
        published: '已下达',
        in_progress: '执行中',
        closed: '已关闭',
        cancelled: '已取消'
      }
      return map[status] || status || '-'
    },
    getStatusTagType(status) {
      const map = {
        draft: 'info',
        published: 'warning',
        in_progress: 'success',
        closed: 'default',
        cancelled: 'danger'
      }
      return map[status] || 'info'
    },
    getEventStatusLabel(status) {
      const map = {
        draft: '草稿',
        pending: '待处理',
        processing: '处理中',
        completed: '已完成',
        archived: '已归档'
      }
      return map[status] || status || '-'
    },
    getStepStatusLabel(status) {
      const map = {
        pending: '待执行',
        in_progress: '执行中',
        completed: '已完成',
        failed: '失败'
      }
      return map[status] || status || '-'
    },
    getStepStatusTagType(status) {
      const map = {
        pending: 'info',
        in_progress: 'warning',
        completed: 'success',
        failed: 'danger'
      }
      return map[status] || 'info'
    },
    getStepType(status) {
      const map = {
        pending: 'primary',
        in_progress: 'warning',
        completed: 'success',
        failed: 'danger'
      }
      return map[status] || 'primary'
    },
    getExecutorInfo(step) {
      if (!step.executorId) return null
      // executorId 现在表示 dispatch_task_participant.id
      const participant = this.participants.find(p => 
        p.id && p.id.toString() === step.executorId.toString()
      )
      if (!participant || !participant.personSnapshot) {
        return `ID: ${step.executorId}`
      }
      try {
        const snapshot = typeof participant.personSnapshot === 'string' 
          ? JSON.parse(participant.personSnapshot) 
          : participant.personSnapshot
        const name = snapshot.name || snapshot.personName || '-'
        const teamName = snapshot.teamName || '-'
        const role = snapshot.role || snapshot.position || '-'
        return `${name} (${teamName} - ${role})`
      } catch (e) {
        return `ID: ${step.executorId}`
      }
    },
    handleAddStep() {
      this.currentStep = null
      this.showStepFormDialog = true
    },
    handleEditStep(step) {
      this.currentStep = step
      this.showStepFormDialog = true
    },
    async handleStepSubmit(stepData) {
      try {
        // Get all existing steps
        const existingSteps = [...this.steps]
        
        if (this.currentStep && this.currentStep.id) {
          // Update existing step
          const index = existingSteps.findIndex(s => s.id === this.currentStep.id)
          if (index >= 0) {
            existingSteps[index] = { ...existingSteps[index], ...stepData }
          }
        } else {
          // Add new step
          existingSteps.push({
            ...stepData,
            status: 'pending'
          })
        }
        
        const res = await upsertDispatchSteps(this.taskId, existingSteps)
        if (res && res.code === 200) {
          this.$message.success(this.currentStep ? '行动项更新成功' : '行动项添加成功')
          this.showStepFormDialog = false
          this.currentStep = null
          await this.loadSteps()
          await this.loadStepResources()
        } else {
          this.$message.error(res.msg || '操作失败')
        }
      } catch (error) {
        console.error('保存行动项失败:', error)
        this.$message.error('保存行动项失败，请稍后重试')
      }
    },
    async handleDeleteStep(step) {
      // 暂时不支持删除行动项
      this.$message.warning('暂不支持删除行动项功能')
      // 如果需要实现删除，需要后端提供删除接口或修改 upsertSteps 支持删除逻辑
      // try {
      //   await this.$confirm('确定要删除此行动项吗？', '提示', {
      //     confirmButtonText: '确定',
      //     cancelButtonText: '取消',
      //     type: 'warning'
      //   })
      //   
      //   // Remove step from list and update
      //   const updatedSteps = this.steps.filter(s => s.id !== step.id)
      //   const res = await upsertDispatchSteps(this.taskId, updatedSteps)
      //   if (res && res.code === 200) {
      //     this.$message.success('行动项删除成功')
      //     // 删除该步骤的资源缓存
      //     if (step.id) {
      //       this.$delete(this.stepResources, step.id)
      //     }
      //     // 重新加载步骤和资源
      //     await this.loadSteps()
      //     await this.loadStepResources()
      //   } else {
      //     this.$message.error(res.msg || '删除失败')
      //   }
      // } catch (error) {
      //   if (error !== 'cancel') {
      //     console.error('删除行动项失败:', error)
      //     this.$message.error('删除行动项失败，请稍后重试')
      //   }
      // }
    },
    handleManageResources(step) {
      this.currentResourceStep = step
      this.showResourceAllocationDialog = true
    },
    async handleResourceUpdated() {
      // Reload resources for the current step
      if (this.currentResourceStep && this.currentResourceStep.id) {
        try {
          const res = await listDispatchStepResources(this.taskId, this.currentResourceStep.id)
          if (res && res.code === 200) {
            this.$set(this.stepResources, this.currentResourceStep.id, res.data || [])
          }
        } catch (error) {
          console.error('刷新资源失败:', error)
        }
      }
    },
    async handleResourceRemoved() {
      // 删除资源后，刷新所有步骤的资源
      await this.loadStepResources()
    },
    async handleStartStep(step) {
      try {
        const res = await startDispatchStep(this.taskId, step.id)
        if (res && res.code === 200) {
          this.$message.success('行动项已开始执行')
          await this.loadSteps()
        } else {
          this.$message.error(res.msg || '操作失败')
        }
      } catch (error) {
        console.error('开始执行行动项失败:', error)
        this.$message.error('开始执行行动项失败，请稍后重试')
      }
    },
    async handleCompleteStep(step) {
      try {
        const { value: remark } = await this.$prompt('请输入完成备注（可选）', '标记完成', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputType: 'textarea',
          inputPlaceholder: '请输入完成备注...'
        }).catch(() => ({ value: null }))
        
        if (remark === null) return // User cancelled
        
        const res = await completeDispatchStep(this.taskId, step.id, remark)
        if (res && res.code === 200) {
          this.$message.success('行动项已标记为完成')
          await this.loadSteps()
        } else {
          this.$message.error(res.msg || '操作失败')
        }
      } catch (error) {
        if (error !== 'cancel') {
          console.error('完成行动项失败:', error)
          this.$message.error('完成行动项失败，请稍后重试')
        }
      }
    },
    async handleFailStep(step) {
      try {
        const { value: reason } = await this.$prompt('请输入失败原因', '标记失败', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputType: 'textarea',
          inputPlaceholder: '请输入失败原因...',
          inputValidator: (value) => {
            if (!value || value.trim().length === 0) {
              return '请输入失败原因'
            }
            return true
          }
        }).catch(() => ({ value: null }))
        
        if (reason === null) return // User cancelled
        
        const res = await failDispatchStep(this.taskId, step.id, reason)
        if (res && res.code === 200) {
          this.$message.success('行动项已标记为失败')
          await this.loadSteps()
        } else {
          this.$message.error(res.msg || '操作失败')
        }
      } catch (error) {
        if (error !== 'cancel') {
          console.error('标记行动项失败:', error)
          this.$message.error('标记行动项失败，请稍后重试')
        }
      }
    },
    getPersonName(participant) {
      if (participant.personSnapshot) {
        try {
          const snapshot = typeof participant.personSnapshot === 'string' 
            ? JSON.parse(participant.personSnapshot) 
            : participant.personSnapshot
          return snapshot.name || snapshot.personName || '-'
        } catch (e) {
          return '-'
        }
      }
      return '-'
    },
    getTeamName(participant) {
      if (participant.teamId) {
        return `队伍 ${participant.teamId}`
      }
      if (participant.personSnapshot) {
        try {
          const snapshot = typeof participant.personSnapshot === 'string' 
            ? JSON.parse(participant.personSnapshot) 
            : participant.personSnapshot
          return snapshot.teamName || snapshot.unit || '-'
        } catch (e) {
          return '-'
        }
      }
      return '-'
    },
    getPersonRole(participant) {
      if (participant.personSnapshot) {
        try {
          const snapshot = typeof participant.personSnapshot === 'string' 
            ? JSON.parse(participant.personSnapshot) 
            : participant.personSnapshot
          return snapshot.role || snapshot.position || '-'
        } catch (e) {
          return '-'
        }
      }
      return '-'
    },
    getPersonContact(participant) {
      if (participant.personSnapshot) {
        try {
          const snapshot = typeof participant.personSnapshot === 'string' 
            ? JSON.parse(participant.personSnapshot) 
            : participant.personSnapshot
          return snapshot.phone || snapshot.contact || snapshot.telephone || '-'
        } catch (e) {
          return '-'
        }
      }
      return '-'
    },
    calculateDistance(lat1, lon1, lat2, lon2) {
      if (!lat1 || !lon1 || !lat2 || !lon2) return null
      
      const R = 6371 // Earth's radius in km
      const dLat = (lat2 - lat1) * Math.PI / 180
      const dLon = (lon2 - lon1) * Math.PI / 180
      const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
                Math.sin(dLon / 2) * Math.sin(dLon / 2)
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
      return R * c
    },
    getParticipantDistance(participant) {
      if (!this.hasEventLocation() || !participant.personSnapshot) return '-'
      try {
        const snapshot = typeof participant.personSnapshot === 'string' 
          ? JSON.parse(participant.personSnapshot) 
          : participant.personSnapshot
        
        // Check for team member coordinates (teamLatitude/teamLongitude)
        if (snapshot.teamLatitude && snapshot.teamLongitude) {
          const distance = this.calculateDistance(
            snapshot.teamLatitude,
            snapshot.teamLongitude,
            parseFloat(this.eventData.latitude),
            parseFloat(this.eventData.longitude)
          )
          if (distance === null) return '-'
          if (distance < 1) {
            return `${(distance * 1000).toFixed(0)}m`
          } else {
            return `${distance.toFixed(1)}km`
          }
        }
        
        // Check for expert coordinates (expertLatitude/expertLongitude)
        if (snapshot.expertLatitude && snapshot.expertLongitude) {
          const distance = this.calculateDistance(
            snapshot.expertLatitude,
            snapshot.expertLongitude,
            parseFloat(this.eventData.latitude),
            parseFloat(this.eventData.longitude)
          )
          if (distance === null) return '-'
          if (distance < 1) {
            return `${(distance * 1000).toFixed(0)}m`
          } else {
            return `${distance.toFixed(1)}km`
          }
        }
        
        return '-'
      } catch (e) {
        return '-'
      }
    },
    formatDateTime(value) {
      return formatDateTime(value)
    },
    async handlePublish() {
      if (!this.taskId) return
      try {
        const res = await publishDispatchTask(this.taskId)
        if (res && res.code === 200) {
          this.$message.success('任务发布成功')
          await this.loadTaskDetail()
          this.$emit('task-status-changed', { taskId: this.taskId, status: 'published' })
        } else {
          this.$message.error(res.msg || '发布失败')
        }
      } catch (error) {
        console.error('发布任务失败:', error)
        this.$message.error('发布失败，请稍后重试')
      }
    },
    async handleStart() {
      if (!this.taskId) return
      try {
        const res = await markDispatchTaskInProgress(this.taskId)
        if (res && res.code === 200) {
          this.$message.success('任务已开始执行')
          await this.loadTaskDetail()
          this.$emit('task-status-changed', { taskId: this.taskId, status: 'in_progress' })
        } else {
          this.$message.error(res.msg || '操作失败')
        }
      } catch (error) {
        console.error('开始执行任务失败:', error)
        this.$message.error('操作失败，请稍后重试')
      }
    },
    handleCloseTask() {
      if (!this.taskId) return
      this.$prompt('请输入关闭备注', '关闭任务', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputType: 'textarea',
        inputPlaceholder: '请输入关闭原因或备注'
      }).then(async ({ value }) => {
        try {
          const res = await closeDispatchTask(this.taskId, { remark: value || '' })
          if (res && res.code === 200) {
            this.$message.success('任务已关闭')
            await this.loadTaskDetail()
            this.$emit('task-status-changed', { taskId: this.taskId, status: 'closed' })
          } else {
            this.$message.error(res.msg || '关闭失败')
          }
        } catch (error) {
          console.error('关闭任务失败:', error)
          this.$message.error('关闭失败，请稍后重试')
        }
      }).catch(() => {
        // User cancelled
      })
    },
    handleDelete() {
      if (!this.taskId) return
      this.$confirm('确定要删除此任务吗？删除后无法恢复。', '删除任务', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const res = await removeDispatchTasks([this.taskId])
          if (res && res.code === 200) {
            this.$message.success('任务已删除')
            this.$emit('update:visible', false)
            this.$emit('task-status-changed', { taskId: this.taskId, status: 'deleted' })
          } else {
            this.$message.error(res.msg || '删除失败')
          }
        } catch (error) {
          console.error('删除任务失败:', error)
          this.$message.error('删除失败，请稍后重试')
        }
      }).catch(() => {
        // User cancelled
      })
    },
    handleAbort() {
      if (!this.taskId) return
      this.$prompt('请输入取消原因', '取消任务', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputType: 'textarea',
        inputPlaceholder: '请输入取消原因'
      }).then(async ({ value }) => {
        try {
          const res = await abortDispatchTask(this.taskId, { reason: value || '' })
          if (res && res.code === 200) {
            this.$message.success('任务已取消')
            await this.loadTaskDetail()
            this.$emit('task-status-changed', { taskId: this.taskId, status: 'cancelled' })
          } else {
            this.$message.error(res.msg || '取消失败')
          }
        } catch (error) {
          console.error('取消任务失败:', error)
          this.$message.error('取消失败，请稍后重试')
        }
      }).catch(() => {
        // User cancelled
      })
    },
    handleParticipantAdded() {
      // Refresh participants list after adding
      this.loadParticipants()
    },
    async handleRemoveParticipant(participant) {
      if (!this.taskId || !participant.id) return
      
      this.$confirm('确定要移除该参与方吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const res = await removeDispatchParticipant(this.taskId, participant.id)
          if (res && res.code === 200) {
            this.$message.success('参与方已移除')
            this.loadParticipants()
          } else {
            this.$message.error(res.msg || '移除失败')
          }
        } catch (error) {
          console.error('移除参与方失败:', error)
          this.$message.error('移除失败，请稍后重试')
        }
      }).catch(() => {
        // User cancelled
      })
    },
    // 检查参与方是否有联系方式
    hasContact(participant) {
      const contact = this.getPersonContact(participant)
      return contact && contact !== '-'
    },
    // 处理参与方操作
    handleParticipantAction(command, participant) {
      switch (command) {
        case 'voice':
          this.handleVoiceCall(participant)
          break
        case 'sms':
          this.handleSms(participant)
          break
        case 'video':
          this.handleVideoCall(participant)
          break
        case 'internal':
          this.handleInternalMessage(participant)
          break
        case 'delete':
          this.handleRemoveParticipant(participant)
          break
        default:
          break
      }
    },
    // 处理语音通话
    handleVoiceCall(participant) {
      if (this.hasContact(participant)) {
        this.$message.info('功能集成中')
      } else {
        this.$message.warning('请先维护联系方式')
      }
    },
    // 处理短信
    handleSms(participant) {
      if (this.hasContact(participant)) {
        this.$message.info('功能集成中')
      } else {
        this.$message.warning('请先维护联系方式')
      }
    },
    // 处理视频通话
    handleVideoCall(participant) {
      this.$message.info('功能集成中')
    },
    // 处理站内通信
    handleInternalMessage(participant) {
      this.$message.info('功能集成中')
    },
    getStepResources(step) {
      if (!step || !step.id) return []
      return this.stepResources[step.id] || []
    },
    getResourceTagType(resourceType) {
      const typeMap = {
        'material': 'success',
        'equipment': 'warning',
        'vehicle': 'info'
      }
      return typeMap[resourceType] || 'info'
    },
    getResourceDistance(resource) {
      if (!this.hasEventLocation()) return ''
      
      const resourceType = resource.resourceType
      
      if (resourceType === 'material' || resourceType === 'equipment') {
        // Get warehouseId from snapshot
        let warehouseId = null
        if (resource.note) {
          try {
            const snapshot = typeof resource.note === 'string' ? JSON.parse(resource.note) : resource.note
            warehouseId = snapshot.warehouseId
          } catch (e) {
            // Ignore parse errors
          }
        }
        
        if (!warehouseId) return ''
        
        const warehouse = this.warehouses.find(w => 
          w.id === warehouseId || 
          String(w.id) === String(warehouseId) ||
          Number(w.id) === Number(warehouseId)
        )
        
        if (!warehouse || !warehouse.latitude || !warehouse.longitude) return ''
        
        const distance = this.calculateDistance(
          parseFloat(warehouse.latitude),
          parseFloat(warehouse.longitude),
          parseFloat(this.eventData.latitude),
          parseFloat(this.eventData.longitude)
        )
        
        if (distance === null) return ''
        
        if (distance < 1) {
          return ` ${(distance * 1000).toFixed(0)}m`
        } else {
          return ` ${distance.toFixed(1)}km`
        }
      } else if (resourceType === 'vehicle') {
        // Get vehicle GPS location
        const resourceId = resource.resourceId
        if (!resourceId) return ''
        
        const vehicle = this.availableVehicles.find(v => 
          v.id === resourceId || 
          String(v.id) === String(resourceId) ||
          Number(v.id) === Number(resourceId)
        )
        
        if (!vehicle || !vehicle.gpsLat || !vehicle.gpsLng) return ''
        
        const distance = this.calculateDistance(
          parseFloat(vehicle.gpsLat),
          parseFloat(vehicle.gpsLng),
          parseFloat(this.eventData.latitude),
          parseFloat(this.eventData.longitude)
        )
        
        if (distance === null) return ''
        
        if (distance < 1) {
          return ` ${(distance * 1000).toFixed(0)}m`
        } else {
          return ` ${distance.toFixed(1)}km`
        }
      }
      
      return ''
    },
    getResourceLabel(resource) {
      if (!resource) return '-'
      
      const resourceId = resource.resourceId
      const resourceType = resource.resourceType
      let resourceName = null
      let quantity = null
      let unit = null
      
      // First, try to look up from available resources based on resourceId and resourceType
      if (resourceId) {
        if (resourceType === 'material') {
          const material = this.availableMaterials.find(m => 
            m.id === resourceId || 
            String(m.id) === String(resourceId) ||
            Number(m.id) === Number(resourceId)
          )
          if (material) {
            resourceName = material.materialName
            unit = material.unit
          }
        } else if (resourceType === 'equipment') {
          const equipment = this.availableEquipment.find(e => 
            e.id === resourceId || 
            String(e.id) === String(resourceId) ||
            Number(e.id) === Number(resourceId)
          )
          if (equipment) {
            resourceName = equipment.equipmentName
          }
        } else if (resourceType === 'vehicle') {
          const vehicle = this.availableVehicles.find(v => 
            v.id === resourceId || 
            String(v.id) === String(resourceId) ||
            Number(v.id) === Number(resourceId)
          )
          if (vehicle) {
            resourceName = vehicle.vehicleName || vehicle.plateNo
          }
        }
      }
      
      // Extract quantity from snapshot for materials
      if (resourceType === 'material' && resource.note) {
        try {
          const snapshot = typeof resource.note === 'string'
            ? JSON.parse(resource.note)
            : resource.note
          quantity = snapshot.qty || snapshot.quantity
        } catch (e) {
          // Ignore parse errors
        }
      }
      
      // Fallback: try to get from resourceSnapshot (for backward compatibility)
      if (!resourceName && resource.resourceSnapshot) {
        try {
          const snapshot = typeof resource.resourceSnapshot === 'string'
            ? JSON.parse(resource.resourceSnapshot)
            : resource.resourceSnapshot
          resourceName = snapshot.name || snapshot.materialName || snapshot.equipmentName || snapshot.vehicleName
        } catch (e) {
          // Ignore parse errors
        }
      }
      
      // Final fallback
      if (!resourceName) {
        resourceName = resource.resourceName || `资源 #${resourceId || '?'}`
      }
      
      // Add resource type prefix
      let typePrefix = ''
      if (resourceType === 'material') {
        typePrefix = '物资: '
      } else if (resourceType === 'equipment') {
        typePrefix = '装备: '
      } else if (resourceType === 'vehicle') {
        typePrefix = '车辆: '
      }
      
      // Get distance text
      const distanceText = this.getResourceDistance(resource)
      
      // Format label: for materials, include quantity and unit
      if (resourceType === 'material' && quantity !== null && quantity !== undefined) {
        const unitText = unit ? unit : ''
        return `${typePrefix}${resourceName} (${quantity}${unitText})${distanceText}`
      }
      
      return `${typePrefix}${resourceName}${distanceText}`
    }
  },
  watch: {
    visible(newVal) {
      this.drawerVisible = newVal
      if (newVal && this.taskId) {
        this.loadTaskDetail()
      }
    },
    taskId(newVal) {
      if (newVal && this.drawerVisible) {
        this.loadTaskDetail()
      }
    },
    drawerVisible(newVal) {
      if (!newVal) {
        this.$emit('update:visible', false)
        this.reset()
      }
    }
  }
}
</script>

<style scoped lang="scss">
.drawer-loading,
.section-loading {
  text-align: center;
  padding: 40px 20px;
  color: #909399;
}

.drawer-loading i,
.section-loading i {
  font-size: 24px;
  margin-right: 8px;
  animation: rotating 2s linear infinite;
}

@keyframes rotating {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.task-drawer-content {
  padding: 20px;
}

.drawer-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid #ebeef5;
}

.task-title {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
}

.task-name {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.task-header-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

.task-code {
  font-size: 13px;
  color: #909399;
}

.task-actions {
  display: flex;
  gap: 8px;
}

.remark-section {
  padding: 12px;
  background: #f5f7fa;
  border-radius: 4px;
  line-height: 1.6;
  color: #606266;
  white-space: pre-wrap;
  word-break: break-word;
}

.event-section {
  margin-bottom: 16px;
}

.drawer-map-section {
  margin-top: 16px;
}

.map-container {
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #ebeef5;
}

.event-actions {
  margin-top: 12px;
  display: flex;
  gap: 8px;
}

.event-loading {
  text-align: center;
  padding: 20px;
  color: #909399;
}

.event-empty,
.section-empty {
  padding: 20px;
}

.participants-section {
  margin-bottom: 16px;
}

.steps-section {
  margin-bottom: 16px;
}

.step-item {
  padding: 8px 0;
}

.step-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.step-header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.step-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
}

.step-title {
  font-weight: 500;
  color: #303133;
}

.step-description {
  color: #606266;
  line-height: 1.6;
  margin-top: 4px;
}

.step-executor {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.step-resources {
  margin-top: 8px;
  padding: 8px;
  background: #f5f7fa;
  border-radius: 4px;
}

.step-resources-label {
  font-size: 12px;
  color: #606266;
  margin-bottom: 6px;
  font-weight: 500;
}

.step-resources-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.step-completion-time,
.step-failure-time {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
  font-style: italic;
}

.drawer-error {
  padding: 20px;
}
</style>