<template>
  <div class="agv-task-page">
    <header class="agv-page-header">
      <div>
        <h2>AGV任务调度</h2>
        <p>{{ pointList[0]?.产线代码 || "产线未识别" }} / 单AGV</p>
      </div>
      <div class="header-actions">
        <span class="auto-refresh-label">自动刷新</span>
        <el-switch v-model="autoRefresh" />
        <el-button :icon="Refresh" :loading="refreshing" @click="refreshAll(true)">刷新</el-button>
      </div>
    </header>

    <el-alert
      v-if="overviewError"
      class="config-alert"
      title="AGV数据配置不可用"
      :description="overviewError"
      type="error"
      show-icon
      :closable="false"
    />
    <el-alert
      v-else-if="configLoaded && !tcsEnabled"
      class="config-alert"
      title="TCS真实下发未启用"
      description="当前仅可查看任务和点位。确认现场TCS地址、机器人组及AGV IP后，将 TCS_Enabled 配置为 1。"
      type="warning"
      show-icon
      :closable="false"
    />

    <section v-loading="overviewLoading" class="status-band">
      <div class="status-cell">
        <span class="status-label">AGV</span>
        <strong>{{ robotInfo?.name || "MCR" }} / {{ robotInfo?.ip || tcsConfig.McrIp || "-" }}</strong>
      </div>
      <div class="status-cell">
        <span class="status-label">运行状态</span>
        <el-tag :type="robotError ? 'danger' : robotStatusTag(robotInfo?.status)" effect="plain">
          {{ robotError ? "查询异常" : robotInfo ? robotStatusText(robotInfo.status) : "获取中" }}
        </el-tag>
      </div>
      <div class="status-cell">
        <span class="status-label">当前工位</span>
        <strong>{{ robotPositionText(robotInfo?.currentPos) }}</strong>
      </div>
      <div class="status-cell">
        <span class="status-label">当前电量</span>
        <strong>{{ robotInfo ? `${robotPower}%` : "-" }}</strong>
      </div>
      <div class="status-cell">
        <span class="status-label">使能状态</span>
        <el-tag :type="robotControlTag(robotInfo?.control)" effect="plain">
          {{ robotInfo ? robotControlText(robotInfo.control) : "-" }}
        </el-tag>
      </div>
      <div class="status-cell">
        <span class="status-label">状态更新时间</span>
        <strong>{{ robotUpdatedAt || "-" }}</strong>
      </div>
    </section>

    <section class="current-task-strip" :class="{ idle: unfinishedTaskCount === 0 }">
      <div class="current-task-title">
        <el-icon><Position /></el-icon>
        <span>任务概览</span>
      </div>
      <el-tag type="info" effect="plain">等待TCS {{ taskOverview.待执行数量 }}</el-tag>
      <el-tag type="warning" effect="plain">进行中 {{ taskOverview.进行中数量 }}</el-tag>
      <el-tag type="danger" effect="plain">失败待处理 {{ taskOverview.失败待处理数量 }}</el-tag>
      <template v-if="currentTask">
        <span class="current-execution-label">当前执行</span>
        <button class="task-code-link" type="button" @click="openDetail(currentTask)">
          {{ currentTask.外部任务编号 }}
        </button>
        <span>{{ currentTask.MES工位号 }} / {{ currentTask.现场位置 }}</span>
        <span>{{ currentTask.任务动作 }}</span>
      </template>
    </section>

    <section class="command-bar">
      <div class="command-group">
        <el-button
          type="primary"
          :icon="Plus"
          :disabled="!tcsEnabled"
          @click="openDispatch('station')"
        >
          整站任务
        </el-button>
        <el-button :icon="Operation" :disabled="!tcsEnabled" @click="openDispatch('step')">
          单步任务
        </el-button>
      </div>
      <div class="command-group danger-group">
        <el-button :icon="VideoPause" :disabled="!tcsEnabled" @click="stopPendingTasks">
          停止未开始任务
        </el-button>
        <el-button
          type="danger"
          :icon="WarningFilled"
          :disabled="!tcsEnabled"
          @click="emergencyStop"
        >
          紧急停止
        </el-button>
      </div>
    </section>

    <el-collapse v-model="expandedPanels" class="point-collapse">
      <el-collapse-item name="points">
        <template #title>
          <div class="collapse-title">
            <el-icon><Setting /></el-icon>
            <span>点位与程序配置</span>
            <el-tag size="small" effect="plain">{{ pointList.length }} 个点位</el-tag>
          </div>
        </template>
        <el-table :data="pointList" border max-height="360" empty-text="暂无点位配置">
          <el-table-column prop="MES工位号" label="MES工位" width="125" fixed />
          <el-table-column prop="现场位置" label="现场位置" width="100" />
          <el-table-column prop="WorkStation" label="TCS站点" width="110" />
          <el-table-column
            prop="插XSDProgramName"
            label="插XSD"
            min-width="155"
            show-overflow-tooltip
          />
          <el-table-column
            prop="插XSEProgramName"
            label="插XSE"
            min-width="155"
            show-overflow-tooltip
          />
          <el-table-column
            prop="拔XSDProgramName"
            label="拔XSD"
            min-width="155"
            show-overflow-tooltip
          />
          <el-table-column
            prop="拔XSEProgramName"
            label="拔XSE"
            min-width="155"
            show-overflow-tooltip
          />
        </el-table>
      </el-collapse-item>
    </el-collapse>

    <el-tabs v-model="activeRecordTab" class="record-tabs" @tab-change="handleRecordTabChange">
      <el-tab-pane label="任务记录" name="tasks">
        <section class="task-list-section">
      <div class="section-heading">
        <div>
          <h3>任务记录</h3>
          <span>共 {{ total }} 条</span>
        </div>
      </div>

      <el-form class="filter-form" :inline="true" @submit.prevent>
        <el-form-item label="时间">
          <el-date-picker
            v-model="filters.dateRange"
            type="datetimerange"
            value-format="YYYY-MM-DD HH:mm:ss"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            range-separator="至"
            clearable
          />
        </el-form-item>
        <el-form-item label="工位">
          <el-select
            v-model="filters.stationCode"
            clearable
            filterable
            placeholder="全部工位"
            style="width: 145px"
          >
            <el-option
              v-for="point in pointList"
              :key="point.MES工位号"
              :label="`${point.MES工位号} ${point.现场位置}`"
              :value="point.MES工位号"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="filters.status" clearable placeholder="全部状态" style="width: 170px">
            <el-option
              v-for="item in statusOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="动作">
          <el-select v-model="filters.action" clearable placeholder="全部动作" style="width: 125px">
            <el-option label="插" value="插" />
            <el-option label="拔" value="拔" />
            <el-option label="插-单步" value="插-单步" />
            <el-option label="拔-单步" value="拔-单步" />
          </el-select>
        </el-form-item>
        <el-form-item label="来源">
          <el-select v-model="filters.source" clearable placeholder="全部来源" style="width: 120px">
            <el-option label="PLC自动" value="PLC_AUTO" />
            <el-option label="人工下发" value="MANUAL" />
            <el-option label="整单重试" value="RETRY" />
          </el-select>
        </el-form-item>
        <el-form-item label="任务号">
          <el-input
            v-model.trim="filters.externalCode"
            clearable
            placeholder="外部任务编号"
            style="width: 210px"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :icon="Search" @click="searchTasks">查询</el-button>
          <el-button :icon="RefreshLeft" @click="resetFilters">重置</el-button>
        </el-form-item>
      </el-form>

      <el-table
        v-loading="taskLoading"
        :data="taskList"
        border
        stripe
        row-key="ID"
        empty-text="暂无任务记录"
      >
        <el-table-column
          prop="外部任务编号"
          label="外部任务编号"
          min-width="235"
          fixed="left"
          show-overflow-tooltip
        />
        <el-table-column prop="MES工位号" label="MES工位" width="120" />
        <el-table-column prop="现场位置" label="位置" width="90" />
        <el-table-column prop="任务动作" label="动作" width="95" />
        <el-table-column prop="产品型号" label="产品型号" width="130" show-overflow-tooltip />
        <el-table-column prop="动作组合" label="动作组合" width="110" />
        <el-table-column prop="来源" label="来源" width="90">
          <template #default="scope">{{ sourceText(scope.row.来源) }}</template>
        </el-table-column>
        <el-table-column label="状态" width="155">
          <template #default="scope">
            <el-tag :type="statusTagType(scope.row.任务状态)" effect="plain">
              {{ statusText(scope.row.任务状态) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="异常处理" width="105">
          <template #default="scope">
            <template v-if="[4, 5].includes(Number(scope.row.任务状态))">
              <el-tag v-if="isTrue(scope.row.处理状态)" type="success" effect="plain"
                >已处理</el-tag
              >
              <el-tag v-else-if="isTrue(scope.row.已复位)" type="warning" effect="plain"
                >已复位</el-tag
              >
              <el-tag v-else type="danger" effect="plain">待复位</el-tag>
            </template>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column prop="机器人IP" label="AGV IP" width="125" show-overflow-tooltip />
        <el-table-column prop="开始时间" label="开始时间" width="165" show-overflow-tooltip />
        <el-table-column prop="结束时间" label="结束时间" width="165" show-overflow-tooltip />
        <el-table-column prop="创建时间" label="创建时间" width="165">
          <template #default="scope">{{ formatDateTime(scope.row.创建时间) }}</template>
        </el-table-column>
        <el-table-column label="操作" width="245" fixed="right">
          <template #default="scope">
            <el-button link type="primary" :icon="View" @click="openDetail(scope.row)"
              >详情</el-button
            >
            <el-button
              v-if="[0, 1].includes(Number(scope.row.任务状态))"
              link
              :icon="RefreshRight"
              :disabled="!tcsEnabled"
              @click="syncTask(scope.row)"
              >同步</el-button
            >
            <el-button
              v-if="Number(scope.row.任务状态) === 0"
              link
              type="danger"
              :icon="CircleClose"
              :disabled="!tcsEnabled"
              @click="cancelTask(scope.row)"
              >取消</el-button
            >
            <el-dropdown
              v-if="[4, 5].includes(Number(scope.row.任务状态)) && !isTrue(scope.row.处理状态)"
              trigger="click"
              @command="handleFailureCommand($event, scope.row)"
            >
              <el-button link type="danger">
                异常处理<el-icon class="el-icon--right"><ArrowDown /></el-icon>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item
                    command="reset"
                    :disabled="!tcsEnabled || isTrue(scope.row.已复位)"
                  >
                    复位小车
                  </el-dropdown-item>
                  <el-dropdown-item
                    command="step"
                    :disabled="!tcsEnabled || !isTrue(scope.row.已复位)"
                  >
                    单步补做
                  </el-dropdown-item>
                  <el-dropdown-item
                    command="station"
                    :disabled="!tcsEnabled || !isTrue(scope.row.已复位)"
                  >
                    整站重做
                  </el-dropdown-item>
                  <el-dropdown-item
                    command="retry"
                    :disabled="!tcsEnabled || !isTrue(scope.row.已复位)"
                  >
                    原任务重试
                  </el-dropdown-item>
                  <el-dropdown-item command="handle" :disabled="!isTrue(scope.row.已复位)" divided>
                    标记已处理
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-row">
        <el-pagination
          v-model:current-page="pageCurrent"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          background
          @size-change="handlePageSizeChange"
          @current-change="loadTasks(true)"
        />
      </div>
        </section>
      </el-tab-pane>

      <el-tab-pane label="工位日志" name="logs">
        <section class="task-list-section">
          <div class="section-heading">
            <div>
              <h3>磨合工位日志</h3>
              <span>共 {{ logTotal }} 条</span>
            </div>
          </div>

          <el-form class="filter-form" :inline="true" @submit.prevent>
            <el-form-item label="开始">
              <el-date-picker
                v-model="logFilters.startTime"
                type="datetime"
                format="YYYY-MM-DD HH:mm"
                value-format="YYYY-MM-DD HH:mm:ss"
                placeholder="开始时间"
                clearable
                style="width: 195px"
              />
            </el-form-item>
            <el-form-item label="结束">
              <el-date-picker
                v-model="logFilters.endTime"
                type="datetime"
                format="YYYY-MM-DD HH:mm"
                value-format="YYYY-MM-DD HH:mm:ss"
                placeholder="结束时间"
                clearable
                style="width: 195px"
              />
            </el-form-item>
            <el-form-item label="工位">
              <el-select
                v-model="logFilters.stationCode"
                clearable
                filterable
                placeholder="全部磨合工位"
                style="width: 190px"
              >
                <el-option
                  v-for="point in pointList"
                  :key="point.MES工位号"
                  :label="`${point.MES工位号} ${point.现场位置}`"
                  :value="point.MES工位号"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="类型">
              <el-select
                v-model="logFilters.logType"
                clearable
                placeholder="全部类型"
                style="width: 125px"
              >
                <el-option label="信息" value="INFO" />
                <el-option label="警告" value="WARNING" />
                <el-option label="错误" value="ERROR" />
              </el-select>
            </el-form-item>
            <el-form-item label="内容">
              <el-input
                v-model.trim="logFilters.keyword"
                clearable
                placeholder="日志内容关键词"
                style="width: 230px"
                @keyup.enter="searchStationLogs"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" :icon="Search" @click="searchStationLogs">查询</el-button>
              <el-button :icon="RefreshLeft" @click="resetLogFilters">重置</el-button>
            </el-form-item>
          </el-form>

          <el-table
            v-loading="logLoading"
            :data="stationLogList"
            border
            stripe
            row-key="ID"
            max-height="560"
            empty-text="暂无磨合工位日志"
          >
            <el-table-column prop="操作时间" label="时间" width="170">
              <template #default="scope">{{ formatDateTime(scope.row.操作时间) }}</template>
            </el-table-column>
            <el-table-column prop="工位号" label="工位" width="125" />
            <el-table-column label="类型" width="100" align="center">
              <template #default="scope">
                <el-tag :type="logTypeTag(scope.row.日志类型)" effect="plain">
                  {{ logTypeText(scope.row.日志类型) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="日志文本" label="日志内容" min-width="520">
              <template #default="scope">
                <div class="log-content">{{ scope.row.日志文本 || "-" }}</div>
              </template>
            </el-table-column>
          </el-table>

          <div class="pagination-row">
            <el-pagination
              v-model:current-page="logPageCurrent"
              v-model:page-size="logPageSize"
              :page-sizes="[10, 20, 50, 100]"
              :total="logTotal"
              layout="total, sizes, prev, pager, next, jumper"
              background
              @size-change="handleLogPageSizeChange"
              @current-change="loadStationLogs(true)"
            />
          </div>
        </section>
      </el-tab-pane>
    </el-tabs>

    <el-dialog
      v-model="dispatchDialogVisible"
      :title="dispatchForm.mode === 'step' ? '下发单步任务' : '下发整站任务'"
      width="680px"
      class="agv-dialog"
      :close-on-click-modal="false"
    >
      <el-form label-width="110px" @submit.prevent>
        <el-form-item label="MES工位" required>
          <el-select
            v-model="dispatchForm.stationCode"
            filterable
            :disabled="Boolean(dispatchForm.parentExternalCode)"
            placeholder="选择工位"
            style="width: 100%"
            @change="dispatchForm.programName = ''"
          >
            <el-option
              v-for="point in pointList"
              :key="point.MES工位号"
              :label="`${point.MES工位号} / ${point.现场位置} / ${point.WorkStation}`"
              :value="point.MES工位号"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="dispatchForm.mode === 'station'" label="动作方向" required>
          <el-radio-group v-model="dispatchForm.actionType">
            <el-radio-button value="插">插</el-radio-button>
            <el-radio-button value="拔">拔</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item v-if="dispatchForm.mode === 'station'" label="动作组合" required>
          <el-radio-group v-model="dispatchForm.portCombination">
            <el-radio-button value="XSD">XSD</el-radio-button>
            <el-radio-button value="XSE">XSE</el-radio-button>
            <el-radio-button value="XSD+XSE">XSD + XSE</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item v-else label="动作名称" required>
          <el-select
            v-model="dispatchForm.programName"
            filterable
            placeholder="选择一个动作"
            style="width: 100%"
          >
            <el-option
              v-for="program in selectedPrograms"
              :key="program"
              :label="program"
              :value="program"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="dispatchForm.mode === 'step'" label="AGV当前工位">
          <el-input :model-value="currentMesStation" disabled />
        </el-form-item>
        <el-alert
          v-if="
            dispatchForm.mode === 'step' &&
            selectedPoint &&
            currentRobotStation !== selectedPoint.WorkStation
          "
          class="dispatch-warning"
          :title="`单步任务不导航，AGV必须位于 ${selectedPoint.MES工位号}`"
          type="warning"
          show-icon
          :closable="false"
        />
        <el-form-item v-if="dispatchForm.parentExternalCode" label="原失败任务">
          <el-input :model-value="dispatchForm.parentExternalCode" disabled />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dispatchDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="dispatchLoading" @click="submitDispatch"
          >确认下发</el-button
        >
      </template>
    </el-dialog>

    <el-dialog
      v-model="handleDialogVisible"
      title="标记失败任务已处理"
      width="620px"
      class="agv-dialog"
      :close-on-click-modal="false"
    >
      <el-alert
        title="该操作会结束 MES 侧失败阻断，之后可接收新的 PLC 任务。"
        type="warning"
        show-icon
        :closable="false"
      />
      <el-form class="handle-form" label-width="100px" @submit.prevent>
        <el-form-item label="失败任务">
          <el-input :model-value="failureForm.externalCode" disabled />
        </el-form-item>
        <el-form-item label="处理说明" required>
          <el-input
            v-model.trim="failureForm.remark"
            type="textarea"
            :rows="4"
            maxlength="500"
            show-word-limit
            placeholder="填写现场判断及处理结果"
          />
        </el-form-item>
        <el-form-item label="通知PLC">
          <el-checkbox v-model="failureForm.notifyPlc">同时写入对应的插/拔完成信号</el-checkbox>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="handleDialogVisible = false">取消</el-button>
        <el-button type="danger" :loading="handleLoading" @click="submitHandleFailure"
          >确认已处理</el-button
        >
      </template>
    </el-dialog>

    <el-drawer v-model="detailVisible" title="AGV任务详情" size="720px" class="agv-detail-drawer">
      <div v-loading="detailLoading" class="detail-content">
        <el-descriptions v-if="detailTask" :column="2" border>
          <el-descriptions-item label="外部任务编号" :span="2">{{
            detailTask.外部任务编号
          }}</el-descriptions-item>
          <el-descriptions-item label="原任务编号">{{
            detailTask.原任务编号 || "-"
          }}</el-descriptions-item>
          <el-descriptions-item label="来源">{{
            sourceText(detailTask.来源)
          }}</el-descriptions-item>
          <el-descriptions-item label="MES工位">{{ detailTask.MES工位号 }}</el-descriptions-item>
          <el-descriptions-item label="TCS站点">{{ detailTask.TCS站点 }}</el-descriptions-item>
          <el-descriptions-item label="任务动作">{{ detailTask.任务动作 }}</el-descriptions-item>
          <el-descriptions-item label="任务类型">{{ detailTask.任务类型 }}</el-descriptions-item>
          <el-descriptions-item label="产品型号">{{
            detailTask.产品型号 || "-"
          }}</el-descriptions-item>
          <el-descriptions-item label="动作组合">{{
            detailTask.动作组合 || "-"
          }}</el-descriptions-item>
          <el-descriptions-item label="程序名称" :span="2">{{
            detailTask.ProgramName || "-"
          }}</el-descriptions-item>
          <el-descriptions-item label="任务状态">
            <el-tag :type="statusTagType(detailTask.任务状态)">{{
              statusText(detailTask.任务状态)
            }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="处理状态">
            {{ isTrue(detailTask.处理状态) ? "已处理" : "未处理" }} /
            {{ isTrue(detailTask.已复位) ? "已复位" : "未复位" }}
          </el-descriptions-item>
          <el-descriptions-item label="开始时间">{{
            detailTask.开始时间 || "-"
          }}</el-descriptions-item>
          <el-descriptions-item label="结束时间">{{
            detailTask.结束时间 || "-"
          }}</el-descriptions-item>
          <el-descriptions-item label="错误信息" :span="2">{{
            detailTask.错误信息 || "-"
          }}</el-descriptions-item>
          <el-descriptions-item label="处理说明" :span="2">{{
            detailTask.处理说明 || "-"
          }}</el-descriptions-item>
        </el-descriptions>

        <section v-if="detailTask" class="payload-section">
          <h4>任务参数</h4>
          <pre>{{ formatJson(detailTask.参数) }}</pre>
          <h4>请求报文</h4>
          <pre>{{ formatJson(detailTask.请求报文) }}</pre>
          <h4>响应报文</h4>
          <pre>{{ formatJson(detailTask.响应报文) }}</pre>
        </section>

        <section class="operation-section">
          <h4>操作记录</h4>
          <el-table :data="operationList" border empty-text="暂无操作记录">
            <el-table-column prop="操作时间" label="时间" width="165">
              <template #default="scope">{{ formatDateTime(scope.row.操作时间) }}</template>
            </el-table-column>
            <el-table-column prop="操作类型" label="操作" width="130" />
            <el-table-column prop="操作人" label="操作人" width="100" />
            <el-table-column label="结果" width="80">
              <template #default="scope">
                <el-tag :type="isTrue(scope.row.是否成功) ? 'success' : 'danger'" size="small">
                  {{ isTrue(scope.row.是否成功) ? "成功" : "失败" }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="操作结果" label="说明" min-width="180" show-overflow-tooltip />
          </el-table>
        </section>
      </div>
    </el-drawer>

  </div>
</template>

<script setup>
import {
  computed,
  getCurrentInstance,
  inject,
  onMounted,
  onUnmounted,
  reactive,
  ref,
  watch
} from "vue"
import { ElMessage, ElMessageBox } from "element-plus"
import {
  ArrowDown,
  CircleClose,
  Operation,
  Plus,
  Position,
  Refresh,
  RefreshLeft,
  RefreshRight,
  Search,
  Setting,
  VideoPause,
  View,
  WarningFilled
} from "@element-plus/icons-vue"

const { proxy } = getCurrentInstance()
const ExecHttpRequest = inject("ExecHttpRequest")

const statusOptions = [
  { label: "未开始", value: "0" },
  { label: "进行中", value: "1" },
  { label: "已完成", value: "2" },
  { label: "已取消", value: "3" },
  { label: "任务错误", value: "4" },
  { label: "任务错误（已处理）", value: "5" }
]

const dateTimeValue = (date) => {
  const pad = (value) => String(value).padStart(2, "0")
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(
    date.getHours()
  )}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
}

const todayLogRange = () => {
  const start = new Date()
  start.setHours(0, 0, 0, 0)
  const end = new Date()
  end.setHours(23, 59, 59, 999)
  return [dateTimeValue(start), dateTimeValue(end)]
}

const refreshing = ref(false)
const overviewLoading = ref(false)
const taskLoading = ref(false)
const configLoaded = ref(false)
const overviewError = ref("")
const autoRefresh = ref(true)
const expandedPanels = ref([])
const tcsConfig = reactive({
  TCS_BaseUrl: "",
  TCS_Enabled: "0",
  McrGroup: "",
  McrIp: "",
  TCS_OperatorUserId: "",
  DefaultPriority: "",
  HttpTimeoutSeconds: ""
})
const pointList = ref([])
const currentTask = ref(null)
const taskOverview = reactive({
  待执行数量: 0,
  进行中数量: 0,
  失败待处理数量: 0
})
const taskList = ref([])
const pageCurrent = ref(1)
const pageSize = ref(20)
const total = ref(0)
const activeRecordTab = ref("tasks")
const logLoading = ref(false)
const logsLoaded = ref(false)
const stationLogList = ref([])
const logPageCurrent = ref(1)
const logPageSize = ref(20)
const logTotal = ref(0)
let refreshTimer = null

const filters = reactive({
  dateRange: [],
  stationCode: "",
  status: "",
  action: "",
  source: "",
  externalCode: ""
})

const initialLogRange = todayLogRange()
const logFilters = reactive({
  startTime: initialLogRange[0],
  endTime: initialLogRange[1],
  stationCode: "",
  logType: "",
  keyword: ""
})

const dispatchDialogVisible = ref(false)
const dispatchLoading = ref(false)
const dispatchForm = reactive({
  mode: "station",
  stationCode: "",
  actionType: "插",
  portCombination: "XSD+XSE",
  programName: "",
  parentExternalCode: ""
})

const handleDialogVisible = ref(false)
const handleLoading = ref(false)
const failureForm = reactive({
  externalCode: "",
  remark: "",
  notifyPlc: false
})

const detailVisible = ref(false)
const detailLoading = ref(false)
const detailTask = ref(null)
const operationList = ref([])
const robotLoading = ref(false)
const robotInfo = ref(null)
const robotUpdatedAt = ref("")
const robotError = ref("")

const tcsEnabled = computed(() => String(tcsConfig.TCS_Enabled) === "1")
const selectedPoint = computed(() =>
  pointList.value.find((item) => item.MES工位号 === dispatchForm.stationCode)
)
const selectedPrograms = computed(() => {
  const point = selectedPoint.value
  if (!point) return []
  return [
    point.插XSDProgramName,
    point.插XSEProgramName,
    point.拔XSDProgramName,
    point.拔XSEProgramName
  ].filter(Boolean)
})
const mesStationDisplay = (stationCode) => {
  if (!stationCode) return "-"
  const point = pointList.value.find((item) => item.WorkStation === stationCode)
  return point?.MES工位号 || stationCode
}
const currentRobotStation = computed(
  () => robotInfo.value?.currentPos || ""
)
const currentMesStation = computed(() => {
  return currentRobotStation.value
    ? mesStationDisplay(currentRobotStation.value)
    : "尚未收到位置"
})
const unfinishedTaskCount = computed(
  () => Number(taskOverview.待执行数量 || 0) + Number(taskOverview.进行中数量 || 0)
)
const robotPower = computed(() => {
  const power = Number(robotInfo.value?.power)
  if (!Number.isFinite(power)) return 0
  return Math.min(100, Math.max(0, Math.round(power)))
})

const operatorCode = () => "磨合系统"

const createDbData = (procedureName, params = []) => proxy.CreateData("11", procedureName, params)

const loadOverview = async (showLoading = true) => {
  if (showLoading) overviewLoading.value = true
  try {
    overviewError.value = ""
    const [configRes, pointRes, currentRes, taskOverviewRes] = await Promise.all([
      proxy.ExecDatabase(createDbData("XD_TCS_AGV_配置_获取")),
      proxy.ExecDatabase(createDbData("XD_TCS_AGV_点位配置_查询", [["MES工位号", ""]])),
      proxy.ExecDatabase(createDbData("XD_TCS_AGV_任务_当前查询")),
      proxy.ExecDatabase(createDbData("XD_TCS_AGV_任务_概览查询"))
    ])

    const configRow = configRes.data?.[0]
    if (
      !configRow ||
      String(configRow.result || "") === "0" ||
      configRow.TCS_Enabled === undefined
    ) {
      throw new Error("当前数据库尚未部署AGV任务配置，请核对数据库连接与部署脚本。")
    }

    Object.assign(tcsConfig, configRow)
    pointList.value = Array.isArray(pointRes.data)
      ? pointRes.data.filter((item) => item.MES工位号 && item.WorkStation)
      : []
    const currentRow = currentRes.data?.[0]
    currentTask.value = currentRow?.外部任务编号 ? currentRow : null
    Object.assign(taskOverview, {
      待执行数量: Number(taskOverviewRes.data?.[0]?.待执行数量 || 0),
      进行中数量: Number(taskOverviewRes.data?.[0]?.进行中数量 || 0),
      失败待处理数量: Number(taskOverviewRes.data?.[0]?.失败待处理数量 || 0)
    })
    configLoaded.value = true
  } catch (error) {
    console.warn("加载AGV概览失败:", error)
    configLoaded.value = false
    overviewError.value = error.message || "加载AGV数据配置失败"
    pointList.value = []
    currentTask.value = null
    Object.assign(taskOverview, { 待执行数量: 0, 进行中数量: 0, 失败待处理数量: 0 })
    if (showLoading) ElMessage.error("加载AGV概览失败")
  } finally {
    overviewLoading.value = false
  }
}

const taskQueryParams = () => [
  ["开始时间", filters.dateRange?.[0] || ""],
  ["结束时间", filters.dateRange?.[1] || ""],
  ["MES工位号", filters.stationCode],
  ["外部任务编号", filters.externalCode],
  ["任务动作", filters.action],
  ["任务状态", filters.status],
  ["来源", filters.source],
  ["PageCurrent", pageCurrent.value],
  ["PageSize", pageSize.value],
  ["PageCount", "0", "int", "1"],
  ["ItemCount", "0", "int", "1"]
]

const loadTasks = async (showLoading = true) => {
  if (showLoading) taskLoading.value = true
  try {
    const data = proxy.CreateData("11", "XD_TCS_AGV_任务_分页查询", taskQueryParams())
    const response = await proxy.ExecDatabase(data)
    taskList.value = Array.isArray(response.data?.result) ? response.data.result : []
    total.value = Number(response.data?.output?.[0]?.ItemCount || 0)
  } catch (error) {
    console.error("加载AGV任务失败:", error)
    if (showLoading) ElMessage.error("加载AGV任务失败")
  } finally {
    taskLoading.value = false
  }
}

const stationLogQueryParams = () => [
  ["MES工位号", logFilters.stationCode],
  ["日志类型", logFilters.logType],
  ["日志文本", logFilters.keyword],
  ["开始时间", logFilters.startTime || ""],
  ["结束时间", logFilters.endTime || ""],
  ["PageCurrent", logPageCurrent.value],
  ["PageSize", logPageSize.value],
  ["PageCount", "0", "int", "1"],
  ["ItemCount", "0", "int", "1"]
]

const loadStationLogs = async (showLoading = true) => {
  if (showLoading) logLoading.value = true
  try {
    const data = proxy.CreateData(
      "11",
      "XD_TCS_AGV_工位日志_分页查询",
      stationLogQueryParams()
    )
    const response = await proxy.ExecDatabase(data)
    stationLogList.value = Array.isArray(response.data?.result) ? response.data.result : []
    logTotal.value = Number(response.data?.output?.[0]?.ItemCount || 0)
    logsLoaded.value = true
  } catch (error) {
    console.error("加载磨合工位日志失败:", error)
    if (showLoading) ElMessage.error("加载磨合工位日志失败")
  } finally {
    logLoading.value = false
  }
}

const handleRecordTabChange = (name) => {
  if (name === "logs" && !logsLoaded.value) loadStationLogs(true)
}

const searchStationLogs = () => {
  logPageCurrent.value = 1
  loadStationLogs(true)
}

const resetLogFilters = () => {
  const range = todayLogRange()
  logFilters.startTime = range[0]
  logFilters.endTime = range[1]
  logFilters.stationCode = ""
  logFilters.logType = ""
  logFilters.keyword = ""
  logPageCurrent.value = 1
  loadStationLogs(true)
}

const handleLogPageSizeChange = () => {
  logPageCurrent.value = 1
  loadStationLogs(true)
}

const refreshAll = async (showLoading = true) => {
  if (refreshing.value) return
  refreshing.value = true
  try {
    await Promise.all([loadOverview(showLoading), loadTasks(showLoading), queryRobot(showLoading)])
  } finally {
    refreshing.value = false
  }
}

const restartRefreshTimer = () => {
  if (refreshTimer) clearInterval(refreshTimer)
  refreshTimer = null
  if (autoRefresh.value) {
    refreshTimer = setInterval(() => refreshAll(false), 10000)
  }
}

watch(autoRefresh, restartRefreshTimer)

const searchTasks = () => {
  pageCurrent.value = 1
  loadTasks(true)
}

const resetFilters = () => {
  filters.dateRange = []
  filters.stationCode = ""
  filters.status = ""
  filters.action = ""
  filters.source = ""
  filters.externalCode = ""
  pageCurrent.value = 1
  loadTasks(true)
}

const handlePageSizeChange = () => {
  pageCurrent.value = 1
  loadTasks(true)
}

const apiBaseUrl = () => window.g?.API_MES_Controller_URL || ""

const callTcsApi = async (path, method = "post", payload = {}) => {
  const baseUrl = apiBaseUrl()
  if (!baseUrl) throw new Error("未配置MES接口服务地址")
  const response = await ExecHttpRequest(baseUrl + path, method, payload)
  const body = response?.data
  if (!body || body.success !== true || Number(body.code) !== 200) {
    throw new Error(body?.message || "AGV接口操作失败")
  }
  return body
}

const openDispatch = (mode, failedTask = null) => {
  const currentPoint = pointList.value.find(
    (item) => item.WorkStation === currentRobotStation.value
  )
  dispatchForm.mode = mode
  dispatchForm.stationCode =
    failedTask?.MES工位号 ||
    (mode === "step" ? currentPoint?.MES工位号 : pointList.value[0]?.MES工位号) ||
    ""
  dispatchForm.actionType = String(failedTask?.任务动作 || "").startsWith("拔") ? "拔" : "插"
  dispatchForm.portCombination = failedTask?.动作组合 || "XSD+XSE"
  dispatchForm.programName = ""
  dispatchForm.parentExternalCode = failedTask?.外部任务编号 || ""
  dispatchDialogVisible.value = true
}

const submitDispatch = async () => {
  if (!dispatchForm.stationCode) {
    ElMessage.warning("请选择MES工位")
    return
  }
  if (dispatchForm.mode === "step" && !dispatchForm.programName) {
    ElMessage.warning("请选择动作名称")
    return
  }
  if (dispatchForm.mode === "station" && !dispatchForm.portCombination) {
    ElMessage.warning("请选择动作组合")
    return
  }
  if (
    dispatchForm.mode === "step" &&
    currentRobotStation.value !== selectedPoint.value?.WorkStation
  ) {
    ElMessage.warning("AGV当前位置与所选站点不一致，不能执行单步任务")
    return
  }

  dispatchLoading.value = true
  try {
    const isStep = dispatchForm.mode === "step"
    const payload = isStep
      ? {
          stationCode: dispatchForm.stationCode,
          programName: dispatchForm.programName,
          operatorCode: operatorCode(),
          parentExternalCode: dispatchForm.parentExternalCode
        }
      : {
          stationCode: dispatchForm.stationCode,
          actionType: dispatchForm.actionType,
          portCombination: dispatchForm.portCombination,
          operatorCode: operatorCode(),
          parentExternalCode: dispatchForm.parentExternalCode
        }
    const result = await callTcsApi(
      isStep ? "/agv/tcs/dispatchStep" : "/agv/tcs/dispatchStation",
      "post",
      payload
    )
    ElMessage.success(result.message)
    dispatchDialogVisible.value = false
    await refreshAll(false)
  } catch (error) {
    console.error("下发AGV任务失败:", error)
    ElMessage.error(error.message)
  } finally {
    dispatchLoading.value = false
  }
}

const strongConfirm = async (title, message, keyword) => {
  try {
    await ElMessageBox.prompt(`${message} 请输入“${keyword}”确认。`, title, {
      confirmButtonText: "确认执行",
      cancelButtonText: "取消",
      type: "warning",
      inputPlaceholder: keyword,
      inputValidator: (value) => value === keyword || `请输入“${keyword}”`
    })
    return true
  } catch {
    return false
  }
}

const confirmAction = async (title, message, confirmButtonText) => {
  try {
    await ElMessageBox.confirm(message, title, {
      confirmButtonText,
      cancelButtonText: "取消",
      type: "warning"
    })
    return true
  } catch {
    return false
  }
}

const resetRobot = async (row) => {
  const ip = row.机器人IP || robotInfo.value?.ip || tcsConfig.McrIp
  if (!ip) {
    ElMessage.error("未配置AGV IP")
    return
  }
  if (!(await strongConfirm("移动机器人复位", `复位 ${ip} 并解除失败任务阻断。`, "复位"))) return

  try {
    const result = await callTcsApi("/agv/tcs/reset", "post", {
      externalCode: row.外部任务编号,
      ip,
      operatorCode: operatorCode()
    })
    ElMessage.success(result.message)
    await refreshAll(false)
  } catch (error) {
    console.error("移动机器人复位失败:", error)
    ElMessage.error(error.message)
  }
}

const retryTask = async (row) => {
  try {
    await ElMessageBox.confirm(`确认按原参数重试任务 ${row.外部任务编号}？`, "原任务重试", {
      confirmButtonText: "确认重试",
      cancelButtonText: "取消",
      type: "warning"
    })
  } catch {
    return
  }

  try {
    const result = await callTcsApi("/agv/tcs/retry", "post", {
      externalCode: row.外部任务编号,
      operatorCode: operatorCode()
    })
    ElMessage.success(result.message)
    await refreshAll(false)
  } catch (error) {
    console.error("重试AGV任务失败:", error)
    ElMessage.error(error.message)
  }
}

const openHandleFailure = (row) => {
  failureForm.externalCode = row.外部任务编号
  failureForm.remark = ""
  failureForm.notifyPlc = false
  handleDialogVisible.value = true
}

const submitHandleFailure = async () => {
  if (!failureForm.remark) {
    ElMessage.warning("请填写现场处理说明")
    return
  }
  if (failureForm.notifyPlc) {
    const confirmed = await strongConfirm(
      "通知PLC完成",
      "该操作将写入对应工位的插/拔完成信号。",
      "通知PLC"
    )
    if (!confirmed) return
  }

  handleLoading.value = true
  try {
    const result = await callTcsApi("/agv/tcs/handleFailure", "post", {
      externalCode: failureForm.externalCode,
      operatorCode: operatorCode(),
      remark: failureForm.remark,
      notifyPlc: failureForm.notifyPlc
    })
    ElMessage.success(result.message)
    handleDialogVisible.value = false
    await refreshAll(false)
  } catch (error) {
    console.error("标记失败任务已处理失败:", error)
    ElMessage.error(error.message)
  } finally {
    handleLoading.value = false
  }
}

const handleFailureCommand = (command, row) => {
  if (command === "reset") resetRobot(row)
  if (command === "step") openDispatch("step", row)
  if (command === "station") openDispatch("station", row)
  if (command === "retry") retryTask(row)
  if (command === "handle") openHandleFailure(row)
}

const cancelTask = async (row) => {
  try {
    await ElMessageBox.confirm(`确认取消未开始任务 ${row.外部任务编号}？`, "取消任务", {
      confirmButtonText: "确认取消",
      cancelButtonText: "返回",
      type: "warning"
    })
  } catch {
    return
  }
  try {
    const result = await callTcsApi("/agv/tcs/cancel", "post", {
      externalCode: row.外部任务编号,
      operatorCode: operatorCode()
    })
    ElMessage.success(result.message)
    await refreshAll(false)
  } catch (error) {
    console.error("取消AGV任务失败:", error)
    ElMessage.error(error.message)
  }
}

const syncTask = async (row) => {
  try {
    const result = await callTcsApi("/agv/tcs/syncTask", "post", {
      externalCode: row.外部任务编号,
      operatorCode: operatorCode()
    })
    ElMessage.success(result.message)
    await refreshAll(false)
  } catch (error) {
    console.error("同步AGV任务状态失败:", error)
    ElMessage.error(error.message)
  }
}

const stopPendingTasks = async () => {
  if (
    !(await confirmAction(
      "停止未开始任务",
      "适用于任务已下发但尚未开始执行、需要撤销排队任务的情况。确认后将停止TCS中全部未开始任务；正在执行的任务不会停止，被停止的任务后续需要重新下发。",
      "确认停止"
    ))
  ) return
  try {
    const result = await callTcsApi("/agv/tcs/stopPending", "post", {
      externalCode: currentTask.value?.外部任务编号 || "",
      operatorCode: operatorCode()
    })
    ElMessage.success(result.message)
    await refreshAll(false)
  } catch (error) {
    console.error("停止未开始任务失败:", error)
    ElMessage.error(error.message)
  }
}

const emergencyStop = async () => {
  const ip = robotInfo.value?.ip || currentTask.value?.机器人IP || tcsConfig.McrIp
  if (!ip) {
    ElMessage.error("未配置AGV IP")
    return
  }
  if (
    !(await confirmAction(
      "AGV紧急停止",
      `仅用于AGV运动异常、碰撞风险、人员或设备安全风险等紧急情况。确认后机器人 ${ip} 将立即停止，当前任务可能失败，AGV可能停在当前位置；排除现场风险后通常需要人工复位并重新处理任务。`,
      "确认紧急停止"
    ))
  )
    return
  try {
    const result = await callTcsApi("/agv/tcs/stopNow", "post", {
      externalCode: currentTask.value?.外部任务编号 || "",
      ip,
      operatorCode: operatorCode()
    })
    ElMessage.success(result.message)
    await refreshAll(false)
  } catch (error) {
    console.error("AGV紧急停止失败:", error)
    ElMessage.error(error.message)
  }
}

const queryRobot = async (showError = false) => {
  if (robotLoading.value) return
  robotLoading.value = true
  try {
    const result = await callTcsApi("/agv/tcs/queryRobot", "get")
    const responseData = result.data
    const robotList = Array.isArray(responseData)
      ? responseData
      : Array.isArray(responseData?.result)
        ? responseData.result
        : []
    robotInfo.value = robotList[0] || null
    robotUpdatedAt.value = dateTimeValue(new Date())
    robotError.value = robotInfo.value ? "" : "未查询到AGV状态"
  } catch (error) {
    console.error("查询AGV状态失败:", error)
    robotError.value = error.message || "查询AGV状态失败"
    if (showError) ElMessage.error(robotError.value)
  } finally {
    robotLoading.value = false
  }
}

const openDetail = async (row) => {
  detailVisible.value = true
  detailLoading.value = true
  detailTask.value = null
  operationList.value = []
  try {
    const params = [["外部任务编号", row.外部任务编号]]
    const [detailRes, operationRes] = await Promise.all([
      proxy.ExecDatabase(createDbData("XD_TCS_AGV_任务_详情查询", params)),
      proxy.ExecDatabase(createDbData("XD_TCS_AGV_操作记录_任务查询", params))
    ])
    detailTask.value = detailRes.data?.[0] || row
    operationList.value = Array.isArray(operationRes.data) ? operationRes.data : []
  } catch (error) {
    console.error("加载AGV任务详情失败:", error)
    ElMessage.error("加载任务详情失败")
  } finally {
    detailLoading.value = false
  }
}

const isTrue = (value) => value === true || value === 1 || value === "1"

const statusText = (value) => {
  const item = statusOptions.find((option) => Number(option.value) === Number(value))
  return item?.label || "未知"
}

const statusTagType = (value) => {
  const types = { 0: "info", 1: "warning", 2: "success", 3: "info", 4: "danger", 5: "danger" }
  return types[Number(value)] || "info"
}

const logTypeText = (value) =>
  ({ INFO: "信息", WARNING: "警告", ERROR: "错误" })[String(value || "").toUpperCase()] ||
  value ||
  "-"

const logTypeTag = (value) =>
  ({ INFO: "info", WARNING: "warning", ERROR: "danger" })[String(value || "").toUpperCase()] ||
  "info"

const robotStatusText = (value) =>
  ({ 0: "空闲中", 1: "任务中", 2: "任务完成", 3: "任务失败", 4: "未连接" })[
    String(value)
  ] || `未知状态（${value ?? "-"}）`

const robotStatusTag = (value) =>
  ({ 0: "success", 1: "warning", 2: "success", 3: "danger", 4: "info" })[
    String(value)
  ] || "info"

const robotControlText = (value) =>
  ({ 1: "已使能", 2: "未使能" })[String(value)] || `未知（${value ?? "-"}）`

const robotControlTag = (value) =>
  ({ 1: "success", 2: "danger" })[String(value)] || "info"

const robotPositionText = (position) => {
  if (!position) return "未获取"
  const mesStation = mesStationDisplay(position)
  return mesStation === position ? position : `${mesStation}（TCS：${position}）`
}

const sourceText = (value) =>
  ({ PLC_AUTO: "PLC自动", MANUAL: "人工下发", RETRY: "整单重试" })[value] || value || "-"

const formatDateTime = (value) => {
  if (!value) return ""
  return String(value)
    .replace("T", " ")
    .replace(/\.\d+Z?$/, "")
    .replace(/Z$/, "")
}

const formatJson = (value) => {
  if (value === null || value === undefined || value === "") return "-"
  if (typeof value === "object") return JSON.stringify(value, null, 2)
  try {
    return JSON.stringify(JSON.parse(value), null, 2)
  } catch {
    return String(value)
  }
}

onMounted(() => {
  refreshAll(true)
  restartRefreshTimer()
})

onUnmounted(() => {
  if (refreshTimer) clearInterval(refreshTimer)
})
</script>

<style lang="scss" scoped>
.agv-task-page {
  min-height: calc(100vh - 70px);
  padding: 16px;
  color: #202124;
  background: #f2f4f7;
  box-sizing: border-box;
}

.agv-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 14px;

  h2 {
    margin: 0;
    font-size: 22px;
    line-height: 1.35;
    letter-spacing: 0;
  }

  p {
    margin: 4px 0 0;
    color: #6b7280;
    font-size: 13px;
  }
}

.header-actions,
.command-group {
  display: flex;
  align-items: center;
  gap: 10px;
}

.auto-refresh-label {
  color: #606266;
  font-size: 13px;
}

.config-alert {
  margin-bottom: 14px;
  border-radius: 6px;
}

.status-band {
  display: grid;
  grid-template-columns: repeat(6, minmax(140px, 1fr));
  min-height: 78px;
  margin-bottom: 12px;
  background: #fff;
  border: 1px solid #dfe3e8;
  border-radius: 6px;
}

.status-cell {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  min-width: 0;
  padding: 14px 18px;
  border-right: 1px solid #ebeef2;

  &:last-child {
    border-right: 0;
  }

  .status-label {
    color: #6b7280;
    font-size: 12px;
  }

  strong {
    overflow: hidden;
    color: #202124;
    font-size: 14px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.current-task-strip {
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: 46px;
  padding: 0 16px;
  margin-bottom: 12px;
  color: #303133;
  background: #fff8e8;
  border: 1px solid #e6a23c;
  border-radius: 6px;
  box-sizing: border-box;

  &.idle {
    background: #f0f9eb;
    border-color: #95d475;
  }
}

.current-task-title {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  font-weight: 600;
}

.task-code-link {
  overflow: hidden;
  max-width: 300px;
  padding: 0;
  color: #2563eb;
  font: inherit;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: transparent;
  border: 0;
  cursor: pointer;
}

.current-execution-label {
  color: #6b7280;
  font-size: 13px;
}

.command-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 14px;
  margin-bottom: 12px;
  background: #fff;
  border: 1px solid #dfe3e8;
  border-radius: 6px;
}

.danger-group {
  justify-content: flex-end;
}

.point-collapse {
  margin-bottom: 12px;
  background: #fff;
  border: 1px solid #dfe3e8;
  border-radius: 6px;

  :deep(.el-collapse-item__header) {
    height: 48px;
    padding: 0 16px;
    border-bottom-color: #ebeef2;
  }

  :deep(.el-collapse-item__wrap) {
    border-bottom: 0;
  }

  :deep(.el-collapse-item__content) {
    padding: 0 14px 14px;
  }
}

.collapse-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

.record-tabs {
  :deep(.el-tabs__header) {
    padding: 0 16px;
    margin: 0 0 12px;
    background: #fff;
    border: 1px solid #dfe3e8;
    border-radius: 6px;
  }

  :deep(.el-tabs__nav-wrap::after) {
    height: 1px;
  }

  :deep(.el-tabs__content) {
    overflow: visible;
  }
}

.task-list-section {
  padding: 16px;
  background: #fff;
  border: 1px solid #dfe3e8;
  border-radius: 6px;
}

.log-content {
  line-height: 1.55;
  white-space: normal;
  overflow-wrap: anywhere;
}

.section-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;

  > div {
    display: flex;
    align-items: baseline;
    gap: 10px;
  }

  h3 {
    margin: 0;
    font-size: 17px;
    letter-spacing: 0;
  }

  span {
    color: #909399;
    font-size: 12px;
  }
}

.filter-form {
  padding: 12px 12px 0;
  margin-bottom: 14px;
  background: #f7f8fa;
  border: 1px solid #ebeef2;
  border-radius: 4px;

  :deep(.el-form-item) {
    margin-right: 14px;
    margin-bottom: 12px;
  }
}

.pagination-row {
  display: flex;
  justify-content: flex-end;
  padding-top: 16px;
  overflow-x: auto;
}

.handle-form {
  margin-top: 18px;
}

.dispatch-warning {
  margin-bottom: 8px;
}

.detail-content {
  min-height: 240px;
}

.payload-section,
.operation-section {
  margin-top: 22px;

  h4 {
    margin: 16px 0 8px;
    font-size: 14px;
    letter-spacing: 0;
  }
}

pre {
  max-height: 280px;
  padding: 12px;
  margin: 0;
  overflow: auto;
  color: #1f2937;
  font-family: Consolas, "Courier New", monospace;
  font-size: 12px;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: #f7f8fa;
  border: 1px solid #dfe3e8;
  border-radius: 4px;
}

:deep(.agv-dialog) {
  max-width: calc(100vw - 32px);
}

:deep(.agv-detail-drawer) {
  max-width: 100vw;
}

@media (max-width: 1100px) {
  .status-band {
    grid-template-columns: repeat(3, minmax(150px, 1fr));
  }

  .status-cell:nth-child(3) {
    border-right: 0;
  }

  .status-cell:nth-child(-n + 3) {
    border-bottom: 1px solid #ebeef2;
  }
}

@media (max-width: 760px) {
  .agv-task-page {
    padding: 10px;
  }

  .agv-page-header,
  .command-bar,
  .current-task-strip {
    align-items: stretch;
    flex-direction: column;
  }

  .header-actions,
  .command-group {
    flex-wrap: wrap;
  }

  .status-band {
    grid-template-columns: 1fr 1fr;
  }

  .status-cell,
  .status-cell:nth-child(3) {
    border-right: 1px solid #ebeef2;
    border-bottom: 1px solid #ebeef2;
  }

  .status-cell:nth-child(even) {
    border-right: 0;
  }

  .status-cell:nth-last-child(-n + 2) {
    border-bottom: 0;
  }

  .current-task-strip {
    gap: 8px;
    padding: 12px;
  }

  .danger-group {
    justify-content: flex-start;
  }

  .filter-form :deep(.el-form-item) {
    display: flex;
    width: 100%;
    margin-right: 0;
  }

  .filter-form :deep(.el-form-item__content) {
    min-width: 0;
    flex: 1;
  }

  .filter-form :deep(.el-date-editor),
  .filter-form :deep(.el-select),
  .filter-form :deep(.el-input) {
    width: 100% !important;
  }
}
</style>
