<template>
  <div class="page-container" v-loading="loading">
    <!-- ========== PC 端 ========== -->
    <template v-if="!isMobile">
      <el-page-header @back="$router.back()" class="page-header">
        <template #content>
          <span class="page-title">任务链详情 - {{ chain?.code }}</span>
        </template>
      </el-page-header>

      <template v-if="chain">
        <el-card shadow="hover">
          <template #header>
            <div class="card-header">
              <div class="card-header-left">
                <span>基本信息</span>
                <el-tag v-bind="getChainStatusTag(chain.status)" size="default">
                  {{ chainStatusMap[chain.status] || chain.status }}
                </el-tag>
              </div>
              <div v-if="!isMonitorMode" class="card-header-actions">
                <el-button
                  v-if="canCancel(chain.status)"
                  type="danger" size="small" :loading="canceling"
                  @click="handleCancelChain"
                >取消任务链</el-button>
                <el-button
                  v-if="canExecuteNext(chain.status)"
                  type="warning" size="small" :loading="executing"
                  @click="handleExecuteNext"
                >执行下一步</el-button>
              </div>
            </div>
          </template>
          <el-descriptions :column="3" border>
            <el-descriptions-item label="任务链编号">{{ chain.code }}</el-descriptions-item>
            <el-descriptions-item label="类型">
              <el-tag size="small">{{ typeMap[chain.type] || chain.type }}</el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="仓库">{{ chain.warehouse }}</el-descriptions-item>
            <el-descriptions-item label="首任务厂商">{{ chain.firstTaskVendor || '-' }}</el-descriptions-item>
            <el-descriptions-item label="优先级">{{ chain.priority }}</el-descriptions-item>
            <el-descriptions-item label="提升机">
              {{ chain.elevatorId ? `#${chain.elevatorId}` : '-' }}
            </el-descriptions-item>
            <el-descriptions-item label="业务追踪号">{{ chain.businessNo || '-' }}</el-descriptions-item>
            <el-descriptions-item label="描述">{{ chain.description || '-' }}</el-descriptions-item>
            <el-descriptions-item label="执行时间">
              {{ chain.executionTime ? `${chain.executionTime}s` : '-' }}
            </el-descriptions-item>
            <el-descriptions-item label="源库位">{{ chain.sourceLocation || '-' }}</el-descriptions-item>
            <el-descriptions-item label="源点位">{{ chain.sourcePoint || '-' }}</el-descriptions-item>
            <el-descriptions-item label="源容器">{{ chain.sourceContainer || '-' }}</el-descriptions-item>
            <el-descriptions-item label="目标类型">{{ chain.targetType || '-' }}</el-descriptions-item>
            <el-descriptions-item label="目标编号">{{ chain.targetCode || '-' }}</el-descriptions-item>
            <el-descriptions-item label="目标库位">{{ chain.targetLocation || '-' }}</el-descriptions-item>
            <el-descriptions-item label="目标点位">{{ chain.targetPoint || '-' }}</el-descriptions-item>
            <el-descriptions-item label="创建时间">{{ chain.createTime }}</el-descriptions-item>
            <el-descriptions-item label="完成时间">{{ chain.completeTime || '-' }}</el-descriptions-item>
            <el-descriptions-item v-if="chain.cancelReason" label="取消原因" :span="2">
              {{ chain.cancelReason }}
            </el-descriptions-item>
            <el-descriptions-item v-if="chain.cancelTime" label="取消时间">
              {{ chain.cancelTime }}
            </el-descriptions-item>
          </el-descriptions>
        </el-card>

        <el-card shadow="hover" class="task-card">
          <template #header>
            <div class="card-header">
              <span>子任务列表 ({{ tasks.length }})</span>
            </div>
          </template>

          <el-timeline>
            <el-timeline-item
              v-for="task in tasks"
              :key="task.id"
              :type="timelineType(task.status)"
              :hollow="task.status === 'CREATED'"
              size="large"
            >
              <el-card shadow="never" class="task-item-card">
                <div class="task-item-header">
                  <div class="task-item-title">
                    <span class="task-code">{{ task.code }}</span>
                    <el-tag size="small" class="task-type-tag">{{ task.type }}</el-tag>
                    <el-tag size="small" type="info">{{ task.vendor }}</el-tag>
                    <el-tag size="small" type="info">批次 {{ task.batchNo }}</el-tag>
                  </div>
                  <div class="task-status-area">
                    <el-tag v-bind="getTaskStatusTag(task.status)" size="small">
                      {{ taskStatusMap[task.status] || task.status }}
                    </el-tag>
                    <el-button
                      v-if="!isMonitorMode && canMockCallback(task)"
                      text type="success" size="small"
                      @click="openMockCallback(task)"
                    >模拟回调</el-button>
                    <el-button
                      v-if="!isMonitorMode && canReturnToWarehouse(task)"
                      text type="warning" size="small"
                      :loading="returningTaskCode === task.code"
                      @click="handleReturnToWarehouse(task)"
                    >回库</el-button>
                    <el-button v-if="!isMonitorMode" text type="danger" size="small" @click="handleDeleteTask(task)">
                      删除
                    </el-button>
                    <el-dropdown v-if="!isMonitorMode" trigger="click" @command="(cmd: string) => handleForceStatus(task, cmd)">
                      <el-button text type="primary" size="small">变更状态</el-button>
                      <template #dropdown>
                        <el-dropdown-menu>
                          <el-dropdown-item
                            v-for="opt in statusOptions"
                            :key="opt.value"
                            :command="opt.value"
                            :disabled="opt.value === task.status"
                          >{{ opt.label }}</el-dropdown-item>
                        </el-dropdown-menu>
                      </template>
                    </el-dropdown>
                  </div>
                </div>

                <el-descriptions :column="3" size="small" class="task-desc">
                  <el-descriptions-item label="机器调用码">{{ task.machineCallCode || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="源库位">{{ task.sourceLocation || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="源点位">{{ task.sourcePoint || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="源容器">{{ task.sourceContainer || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="目标库位">{{ task.targetLocation || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="目标点位">{{ task.targetPoint || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="目标编码">{{ task.targetCode || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="开始时间">{{ task.startTime || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="完成时间">{{ task.completeTime || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="执行时间">
                    {{ task.executionTime ? `${task.executionTime}s` : '-' }}
                  </el-descriptions-item>
                  <el-descriptions-item label="创建时间">{{ task.createTime || '-' }}</el-descriptions-item>
                  <el-descriptions-item v-if="task.remark" label="备注">{{ task.remark }}</el-descriptions-item>
                </el-descriptions>

                <el-alert
                  v-if="task.exceptionReason"
                  :title="task.exceptionReason"
                  type="error" :closable="false" show-icon class="task-error"
                />
                <el-alert
                  v-if="task.cancelReason"
                  :title="`取消原因: ${task.cancelReason}`"
                  type="warning" :closable="false" show-icon class="task-error"
                />
              </el-card>
            </el-timeline-item>
          </el-timeline>

          <el-empty v-if="tasks.length === 0" description="暂无子任务" />
        </el-card>
      </template>
    </template>

    <!-- ========== 移动端 ========== -->
    <template v-else>
      <!-- 顶部返回栏 -->
      <div class="m-nav-bar">
        <el-icon class="m-back-btn" @click="$router.back()"><ArrowLeft /></el-icon>
        <span class="m-nav-title">任务链详情</span>
        <div style="width: 24px;" />
      </div>

      <template v-if="chain">
        <!-- 状态和操作 -->
        <div class="m-status-banner" :class="`m-status-banner--${chain.status}`">
          <div class="m-status-banner-top">
            <el-tag v-bind="getChainStatusTag(chain.status)" size="default" effect="dark">
              {{ chainStatusMap[chain.status] || chain.status }}
            </el-tag>
            <span class="m-chain-type">{{ typeMap[chain.type] || chain.type }}</span>
          </div>
          <div class="m-chain-code-mobile">{{ chain.code }}</div>
          <div v-if="!isMonitorMode" class="m-status-actions">
            <el-button
              v-if="canCancel(chain.status)"
              type="danger" size="small" round :loading="canceling"
              @click="handleCancelChain"
            >取消</el-button>
            <el-button
              v-if="canExecuteNext(chain.status)"
              type="warning" size="small" round :loading="executing"
              @click="handleExecuteNext"
            >执行下一步</el-button>
          </div>
        </div>

        <!-- 基本信息分组 -->
        <div class="m-section">
          <div class="m-section-title">基本信息</div>
          <div class="m-info-grid">
            <div class="m-info-item">
              <span class="m-info-label">仓库</span>
              <span class="m-info-value">{{ chain.warehouse }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">首任务厂商</span>
              <span class="m-info-value">{{ chain.firstTaskVendor || '-' }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">优先级</span>
              <span class="m-info-value">{{ chain.priority }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">提升机</span>
              <span class="m-info-value">{{ chain.elevatorId ? `#${chain.elevatorId}` : '-' }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">业务追踪号</span>
              <span class="m-info-value">{{ chain.businessNo || '-' }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">执行时间</span>
              <span class="m-info-value">{{ chain.executionTime ? `${chain.executionTime}s` : '-' }}</span>
            </div>
          </div>
        </div>

        <div class="m-section">
          <div class="m-section-title">位置信息</div>
          <div class="m-info-grid">
            <div class="m-info-item">
              <span class="m-info-label">源库位</span>
              <span class="m-info-value">{{ chain.sourceLocation || '-' }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">源点位</span>
              <span class="m-info-value">{{ chain.sourcePoint || '-' }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">源容器</span>
              <span class="m-info-value">{{ chain.sourceContainer || '-' }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">目标类型</span>
              <span class="m-info-value">{{ chain.targetType || '-' }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">目标编号</span>
              <span class="m-info-value">{{ chain.targetCode || '-' }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">目标库位</span>
              <span class="m-info-value">{{ chain.targetLocation || '-' }}</span>
            </div>
          </div>
        </div>

        <div class="m-section">
          <div class="m-section-title">时间</div>
          <div class="m-info-grid m-info-grid-1">
            <div class="m-info-item">
              <span class="m-info-label">创建时间</span>
              <span class="m-info-value">{{ chain.createTime }}</span>
            </div>
            <div class="m-info-item">
              <span class="m-info-label">完成时间</span>
              <span class="m-info-value">{{ chain.completeTime || '-' }}</span>
            </div>
            <div v-if="chain.cancelReason" class="m-info-item">
              <span class="m-info-label">取消原因</span>
              <span class="m-info-value" style="color: #f56c6c;">{{ chain.cancelReason }}</span>
            </div>
          </div>
        </div>

        <!-- 子任务列表 -->
        <div class="m-section">
          <div class="m-section-title">子任务 ({{ tasks.length }})</div>

          <div
            v-for="task in tasks"
            :key="task.id"
            class="m-task-card"
          >
            <div class="m-task-card-top">
              <div class="m-task-card-tags">
                <el-tag v-bind="getTaskStatusTag(task.status)" size="small">
                  {{ taskStatusMap[task.status] || task.status }}
                </el-tag>
                <el-tag size="small" type="info">{{ task.type }}</el-tag>
                <el-tag size="small" type="info">{{ task.vendor }}</el-tag>
              </div>
              <el-icon v-if="!isMonitorMode" class="m-task-more" @click="openTaskActions(task)"><MoreFilled /></el-icon>
            </div>
            <div class="m-task-code">{{ task.code }}</div>

            <div class="m-info-grid">
              <div class="m-info-item">
                <span class="m-info-label">源容器</span>
                <span class="m-info-value">{{ task.sourceContainer || '-' }}</span>
              </div>
              <div class="m-info-item">
                <span class="m-info-label">目标点位</span>
                <span class="m-info-value">{{ task.targetPoint || '-' }}</span>
              </div>
              <div class="m-info-item">
                <span class="m-info-label">机器调用码</span>
                <span class="m-info-value">{{ task.machineCallCode || '-' }}</span>
              </div>
              <div class="m-info-item">
                <span class="m-info-label">批次</span>
                <span class="m-info-value">{{ task.batchNo }}</span>
              </div>
            </div>

            <div v-if="task.createTime" class="m-task-time">{{ task.createTime }}</div>

            <el-alert
              v-if="task.exceptionReason"
              :title="task.exceptionReason"
              type="error" :closable="false" show-icon style="margin-top: 8px;"
            />
          </div>

          <el-empty v-if="tasks.length === 0" description="暂无子任务" :image-size="48" />
        </div>
      </template>

      <!-- 移动端子任务操作面板 -->
      <el-drawer
        v-if="!isMonitorMode"
        v-model="taskActionDrawerVisible"
        direction="btt"
        size="auto"
        :with-header="false"
      >
        <div class="m-action-sheet">
          <div class="m-action-sheet-title">{{ actionTask?.code }}</div>
          <div class="m-action-list">
            <div
              v-if="actionTask && canMockCallback(actionTask)"
              class="m-action-item"
              @click="taskActionDrawerVisible = false; openMockCallback(actionTask!)"
            >
              <el-icon color="#67c23a"><VideoPlay /></el-icon>
              <span>模拟回调</span>
            </div>
            <div
              v-if="actionTask && canReturnToWarehouse(actionTask)"
              class="m-action-item"
              @click="taskActionDrawerVisible = false; handleReturnToWarehouse(actionTask!)"
            >
              <el-icon color="#e6a23c"><House /></el-icon>
              <span>回库</span>
            </div>
            <div class="m-action-item" @click="taskActionDrawerVisible = false; openStatusPicker()">
              <el-icon color="#409eff"><Switch /></el-icon>
              <span>变更状态</span>
            </div>
            <div class="m-action-item m-action-danger" @click="taskActionDrawerVisible = false; handleDeleteTask(actionTask!)">
              <el-icon color="#f56c6c"><Delete /></el-icon>
              <span>删除子任务</span>
            </div>
          </div>
          <div class="m-action-cancel" @click="taskActionDrawerVisible = false">取消</div>
        </div>
      </el-drawer>

      <!-- 移动端变更状态选择 -->
      <el-drawer
        v-if="!isMonitorMode"
        v-model="statusPickerVisible"
        direction="btt"
        size="auto"
        :with-header="false"
      >
        <div class="m-action-sheet">
          <div class="m-action-sheet-title">变更为</div>
          <div class="m-action-list">
            <div
              v-for="opt in statusOptions"
              :key="opt.value"
              :class="['m-action-item', { 'm-action-item-disabled': opt.value === actionTask?.status }]"
              @click="opt.value !== actionTask?.status && onPickStatus(opt.value)"
            >
              <span>{{ opt.label }}</span>
            </div>
          </div>
          <div class="m-action-cancel" @click="statusPickerVisible = false">取消</div>
        </div>
      </el-drawer>
    </template>

    <!-- ========== 共用弹窗 ========== -->
    <!-- 取消任务链 -->
    <el-dialog
      v-model="cancelDialogVisible"
      title="取消任务链"
      :width="isMobile ? '90%' : '420px'"
      destroy-on-close
    >
      <el-form :model="cancelForm" label-width="110px">
        <el-form-item label="任务链编号">
          <el-input :model-value="chain?.code || ''" disabled />
        </el-form-item>
        <el-form-item label="取消原因">
          <el-input
            v-model="cancelForm.reason"
            type="textarea"
            :rows="3"
            placeholder="取消原因（可选）"
            clearable
          />
        </el-form-item>
        <el-form-item label="移至库外">
          <el-switch
            v-model="cancelForm.moveOut"
            active-text="是"
            inactive-text="否"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="cancelDialogVisible = false">返回</el-button>
        <el-button type="danger" :loading="canceling" @click="submitCancelChain">
          确认取消
        </el-button>
      </template>
    </el-dialog>

    <!-- 模拟回调：选择场景 -->
    <el-dialog
      v-model="scenarioDialogVisible"
      title="选择回调场景"
      :width="isMobile ? '90%' : '400px'"
      destroy-on-close
    >
      <el-radio-group v-model="selectedScenarioKey" class="scenario-radio-group">
        <el-radio
          v-for="s in currentScenarios"
          :key="s.key"
          :value="s.key"
          border
          class="scenario-radio-item"
        >{{ s.label }}</el-radio>
      </el-radio-group>
      <template #footer>
        <el-button @click="scenarioDialogVisible = false">取消</el-button>
        <el-button type="primary" :disabled="!selectedScenarioKey" @click="confirmScenario">
          下一步
        </el-button>
      </template>
    </el-dialog>

    <!-- 模拟回调：填写参数 -->
    <el-dialog
      v-model="callbackDialogVisible"
      :title="`模拟回调 - ${activeScenario?.label}`"
      :width="isMobile ? '95%' : '520px'"
      destroy-on-close
    >
      <el-form :model="callbackForm" :label-width="isMobile ? '100px' : '140px'" size="default">
        <el-form-item v-for="field in activeScenario?.fields" :key="field.name" :label="field.label">
          <el-select
            v-if="field.type === 'select'"
            v-model="callbackForm[field.name]"
            placeholder="请选择"
            clearable
          >
            <el-option
              v-for="opt in field.options"
              :key="opt.value"
              :label="opt.label"
              :value="opt.value"
            />
          </el-select>
          <el-switch v-else-if="field.type === 'boolean'" v-model="callbackForm[field.name]" />
          <el-input-number
            v-else-if="field.type === 'number'"
            v-model="callbackForm[field.name]"
            :controls="false"
            style="width: 100%"
          />
          <el-input v-else v-model="callbackForm[field.name]" placeholder="请输入" clearable />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="callbackDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="callbackSubmitting" @click="submitMockCallback">
          发送回调
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
defineOptions({ name: 'TaskChainDetail' })
import { computed, onMounted, reactive, ref } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ArrowLeft, MoreFilled, VideoPlay, Switch, Delete, House } from '@element-plus/icons-vue'
import { useDevice } from '@/composables/useDevice'
import { useUserStore } from '@/stores/user'
import { chainStatusMap, getChainStatusTag } from '@/constants/chainStatus'
import { taskStatusMap, getTaskStatusTag } from '@/constants/taskStatus'
import {
  cancelChain, deleteTask, dispatchExecute, forceTaskStatus, getChainDetail, taskStatusOptions,
  callbackScenarioMap, sendMockCallback,
  type CallbackScenario, type TaskChainDetailVO, type TaskVO,
} from '@/api/task'
import { generateRelease } from '@/api/generate'

const { isMobile } = useDevice()
const userStore = useUserStore()
const isMonitorMode = computed(() => userStore.isMonitorMode())
const route = useRoute()
const loading = ref(false)
const executing = ref(false)
const canceling = ref(false)
const cancelDialogVisible = ref(false)
const cancelForm = reactive({
  reason: '',
  moveOut: false,
})
const returningTaskCode = ref<string | null>(null)
const chain = ref<TaskChainDetailVO | null>(null)
const tasks = ref<TaskVO[]>([])
const statusOptions = taskStatusOptions

const cancelableStatuses = ['CREATED', 'WAITING', 'READY', 'IN_PROGRESS']
function canCancel(status: string) {
  return cancelableStatuses.includes(status)
}

function canExecuteNext(status: string) {
  return status === 'IN_PROGRESS' || status === 'CREATED' || status === 'READY'
}

/** TP/HJ 前缀映射回库库区；与任务生成-释放信号约定一致 */
function resolveReturnWarehouseTargetCode(container: string | undefined | null): string | null {
  const c = container?.trim().toUpperCase()
  if (!c) return null
  if (c.startsWith('TP')) return 'WH01-3-2'
  if (c.startsWith('HJ')) return 'WH01-3-3'
  return null
}

function canReturnToWarehouse(task: TaskVO): boolean {
  if (task.type !== 'HK_STATION_RELEASE' || task.status !== 'WAITING_RELEASE') return false
  if (!chain.value?.warehouse || !task.sourceContainer?.trim()) return false
  return resolveReturnWarehouseTargetCode(task.sourceContainer) != null
}

async function handleReturnToWarehouse(task: TaskVO) {
  const wh = chain.value?.warehouse
  if (!wh) return
  const targetCode = resolveReturnWarehouseTargetCode(task.sourceContainer)
  if (!targetCode) {
    ElMessage.warning('仅支持容器号以 TP、HJ 开头时回库')
    return
  }
  const taskChainCode = task.chainCode || chain.value?.code
  if (!taskChainCode) {
    ElMessage.warning('缺少任务链编号')
    return
  }
  try {
    await ElMessageBox.confirm(
      `确认发送回库释放信号？目标库区：${targetCode}，容器：${task.sourceContainer}`,
      '回库',
      { type: 'warning' },
    )
    returningTaskCode.value = task.code
    await generateRelease({
      warehouse: wh,
      taskChainCode,
      container: task.sourceContainer,
      targetType: 'AREA',
      targetCode,
    })
    ElMessage.success('回库释放信号已发送')
    await loadData()
  } catch { /* cancelled */ } finally {
    returningTaskCode.value = null
  }
}

// ==================== 移动端子任务操作 ====================
const taskActionDrawerVisible = ref(false)
const statusPickerVisible = ref(false)
const actionTask = ref<TaskVO | null>(null)

function openTaskActions(task: TaskVO) {
  actionTask.value = task
  taskActionDrawerVisible.value = true
}

function openStatusPicker() {
  statusPickerVisible.value = true
}

function onPickStatus(targetStatus: string) {
  statusPickerVisible.value = false
  if (actionTask.value) {
    handleForceStatus(actionTask.value, targetStatus)
  }
}

// ==================== 操作逻辑（共用） ====================
async function handleCancelChain() {
  if (!chain.value) return
  cancelForm.reason = ''
  cancelForm.moveOut = false
  cancelDialogVisible.value = true
}

async function submitCancelChain() {
  if (!chain.value) return
  try {
    canceling.value = true
    const reason = cancelForm.reason.trim()
    await cancelChain(chain.value.code, reason || undefined, cancelForm.moveOut)
    ElMessage.success('任务链已取消')
    cancelDialogVisible.value = false
    await loadData()
  } catch { /* cancelled */ } finally {
    canceling.value = false
  }
}

async function handleExecuteNext() {
  if (!chain.value) return
  try {
    await ElMessageBox.confirm('确认手动执行该任务链的下一步？', '确认', { type: 'warning' })
    executing.value = true
    await dispatchExecute(chain.value.warehouse, chain.value.code)
    ElMessage.success('执行已触发')
    await loadData()
  } catch { /* cancelled */ } finally {
    executing.value = false
  }
}

// ==================== 模拟回调 ====================
const scenarioDialogVisible = ref(false)
const callbackDialogVisible = ref(false)
const callbackSubmitting = ref(false)
const selectedScenarioKey = ref('')
const currentScenarios = ref<CallbackScenario[]>([])
const activeScenario = ref<CallbackScenario | null>(null)
const activeCallbackTask = ref<TaskVO | null>(null)
const callbackForm = ref<Record<string, unknown>>({})

function canMockCallback(task: TaskVO): boolean {
  const mockableStatuses = ['CREATED', 'IN_PROGRESS', 'FAILED']
  if (!mockableStatuses.includes(task.status)) return false
  return !!callbackScenarioMap[task.type]?.length
}

function openMockCallback(task: TaskVO) {
  const scenarios = callbackScenarioMap[task.type]
  if (!scenarios?.length) return
  activeCallbackTask.value = task
  currentScenarios.value = scenarios
  if (scenarios.length === 1) {
    activeScenario.value = scenarios[0]
    callbackForm.value = buildDefaultCallbackForm(task)
    callbackDialogVisible.value = true
  } else {
    selectedScenarioKey.value = ''
    scenarioDialogVisible.value = true
  }
}

function confirmScenario() {
  const scenario = currentScenarios.value.find(s => s.key === selectedScenarioKey.value)
  const task = activeCallbackTask.value
  if (!scenario || !task) return
  scenarioDialogVisible.value = false
  activeScenario.value = scenario
  callbackForm.value = buildDefaultCallbackForm(task)
  callbackDialogVisible.value = true
}

function buildDefaultCallbackForm(task: TaskVO): Record<string, unknown> {
  const callCode = task.machineCallCode || task.chainCode || chain.value?.code || ''
  const palletCode = task.sourceContainer || chain.value?.sourceContainer || ''
  const form: Record<string, unknown> = {
    robotTaskCode: callCode,
    singleRobotCode: 'MOCK_ROBOT',
    currentSeq: String(task.batchNo ?? ''),
    taskCode: callCode,
    palletCode,
    status: 'FINISHED',
    hasPick: false,
    start: task.sourcePoint || chain.value?.sourcePoint || '',
    end: task.targetPoint || chain.value?.targetPoint || '',
    actualStart: task.sourcePoint || chain.value?.sourcePoint || '',
    actualEnd: task.targetPoint || chain.value?.targetPoint || '',
  }
  if (task.type === 'ZS_PRE_PICK_UP') form.taskStep = 'VEHICLE_WILL_PICK'
  if (task.type === 'ZS_PICK_UP') form.hasPick = true
  if (task.type === 'ZS_OUTBOUND_IN_LIFTER') form.taskStep = 'IN_LIFTER'
  return form
}

async function submitMockCallback() {
  if (!activeScenario.value) return
  try {
    await ElMessageBox.confirm(
      `确认发送「${activeScenario.value.label}」模拟回调？`,
      '模拟回调',
      { type: 'warning' },
    )
    callbackSubmitting.value = true
    const data: Record<string, unknown> = {}
    for (const field of activeScenario.value.fields) {
      const val = callbackForm.value[field.name]
      if (val !== undefined && val !== '' && val !== null) {
        data[field.name] = val
      }
    }
    await sendMockCallback(activeScenario.value.url, data)
    ElMessage.success('回调已发送')
    callbackDialogVisible.value = false
    await loadData()
  } catch { /* cancelled */ } finally {
    callbackSubmitting.value = false
  }
}

async function handleDeleteTask(task: TaskVO) {
  try {
    await ElMessageBox.confirm(
      `确认删除子任务 ${task.code}？此操作不可恢复。`,
      '删除子任务',
      { type: 'warning', confirmButtonText: '确认删除', cancelButtonText: '取消' },
    )
    await deleteTask(task.code)
    ElMessage.success('子任务已删除')
    await loadData()
  } catch { /* cancelled */ }
}

async function handleForceStatus(task: TaskVO, targetStatus: string) {
  const label = statusOptions.find(o => o.value === targetStatus)?.label || targetStatus
  try {
    await ElMessageBox.confirm(
      `确认将子任务 ${task.code} 的状态强制变更为「${label}」？此操作绕过状态机，请谨慎操作。`,
      '强制变更状态',
      { type: 'warning' },
    )
    await forceTaskStatus(task.code, targetStatus)
    ElMessage.success('状态已变更')
    await loadData()
  } catch { /* cancelled */ }
}

// ==================== 映射 ====================
const typeMap: Record<string, string> = {
  INBOUND: '入库', QUICK_PALLET_INBOUND: '托盘快速入库',
  OUTBOUND: '出库', OUTBOUND_NEW: '拣货出库(新模版)',
  OUTBOUND_NO_WAIT: '出库(不等待)', OUTBOUND_NO_WAIT_NEW: '直出模式(新模版)', MOVE: '移库', MOVE_NEW: '移库(新模版)',
}
function timelineType(status: string) {
  const map: Record<string, string> = {
    CREATED: 'info', READY: 'primary', IN_PROGRESS: 'primary',
    WAITING_WAKE: 'warning', WAITING_RELEASE: 'warning',
    COMPLETED: 'success', CANCELED: 'info', FAILED: 'danger',
  }
  return map[status] || 'info'
}

function sortTasksById(taskList: TaskVO[]) {
  return [...taskList].sort((left, right) => left.id - right.id)
}

async function loadData() {
  const code = route.params.code as string
  if (!code) return
  loading.value = true
  try {
    const res = await getChainDetail(code)
    chain.value = res.data
    tasks.value = sortTasksById(res.data.tasks || [])
  } catch { /* handled by interceptor */ } finally {
    loading.value = false
  }
}

onMounted(loadData)
</script>

<style scoped>
/* ===== 公共 ===== */
.page-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ===== PC ===== */
.page-header {
  background: #fff;
  padding: 16px 20px;
  border-radius: 8px;
}

.page-title {
  font-size: 16px;
  font-weight: 600;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
}

.card-header-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.card-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.task-card {
  margin-top: 0;
}

.task-item-card {
  border: 1px solid #ebeef5;
}

.task-item-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.task-item-title {
  display: flex;
  align-items: center;
  gap: 8px;
}

.task-code {
  font-weight: 600;
  font-size: 14px;
}

.task-status-area {
  display: flex;
  align-items: center;
  gap: 8px;
}

.task-type-tag {
  font-weight: 500;
}

.task-desc {
  margin-top: 4px;
}

.task-error {
  margin-top: 8px;
}

.scenario-radio-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

.scenario-radio-item {
  margin: 0 !important;
  width: 100%;
}

/* ===== 移动端 ===== */
.m-nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 4px;
  margin-bottom: -4px;
}

.m-back-btn {
  font-size: 22px;
  color: #303133;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.m-nav-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.m-status-banner {
  background: #fff;
  border-radius: 12px;
  padding: 16px;
}

.m-status-banner-top {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.m-chain-type {
  font-size: 13px;
  color: #909399;
}

.m-chain-code-mobile {
  font-size: 13px;
  font-weight: 600;
  color: #303133;
  word-break: break-all;
  margin-bottom: 10px;
}

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

.m-section {
  background: #fff;
  border-radius: 12px;
  padding: 14px;
}

.m-section-title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid #f0f2f5;
}

.m-info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 12px;
}

.m-info-grid-1 {
  grid-template-columns: 1fr;
}

.m-info-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.m-info-label {
  font-size: 11px;
  color: #909399;
}

.m-info-value {
  font-size: 13px;
  color: #303133;
  word-break: break-all;
}

.m-task-card {
  background: #f8f9fb;
  border-radius: 10px;
  padding: 12px;
  margin-bottom: 10px;
}

.m-task-card:last-child {
  margin-bottom: 0;
}

.m-task-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

.m-task-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.m-task-more {
  font-size: 20px;
  color: #909399;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  padding: 4px;
}

.m-task-code {
  font-size: 12px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 8px;
  word-break: break-all;
}

.m-task-time {
  font-size: 11px;
  color: #c0c4cc;
  margin-top: 8px;
}

/* ===== 移动端操作面板 ===== */
.m-action-sheet {
  padding: 0 0 8px;
}

.m-action-sheet-title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  text-align: center;
  padding: 4px 0 16px;
  word-break: break-all;
}

.m-action-list {
  border-top: 1px solid #f0f2f5;
}

.m-action-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  font-size: 15px;
  color: #303133;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  border-bottom: 1px solid #f8f9fb;
}

.m-action-item:active {
  background: #f5f7fa;
}

.m-action-item-disabled {
  color: #c0c4cc;
  pointer-events: none;
}

.m-action-danger span {
  color: #f56c6c;
}

.m-action-cancel {
  text-align: center;
  padding: 14px;
  font-size: 15px;
  color: #909399;
  cursor: pointer;
  border-top: 8px solid #f5f7fa;
  -webkit-tap-highlight-color: transparent;
}
</style>
