<template>
  <div class="page-container">
    <!-- ========== PC 端 ========== -->
    <template v-if="!isMobile">
      <el-card shadow="hover" class="filter-card">
        <el-form :model="query" inline>
          <el-form-item label="任务链编号">
            <el-input v-model="query.code" placeholder="请输入" clearable style="width: 180px" />
          </el-form-item>
            <el-form-item label="状态">
            <el-select v-model="query.status" placeholder="全部" clearable style="width: 140px">
              <el-option v-for="(label, value) in chainStatusMap" :key="value" :label="label" :value="value" />
            </el-select>
          </el-form-item>
          <el-form-item label="类型">
            <el-select v-model="query.type" placeholder="全部" clearable style="width: 160px">
              <el-option v-for="(label, value) in typeMap" :key="value" :label="label" :value="value" />
            </el-select>
          </el-form-item>
          <el-form-item label="业务追踪号">
            <el-input v-model="query.businessNo" placeholder="请输入" clearable style="width: 180px" />
          </el-form-item>
          <el-form-item label="源容器">
            <el-input v-model="query.sourceContainer" placeholder="请输入" clearable style="width: 150px" />
          </el-form-item>
          <el-form-item label="目标编码">
            <el-input v-model="query.targetCode" placeholder="请输入" clearable style="width: 150px" />
          </el-form-item>
          <el-form-item label="创建时间">
            <el-date-picker
              v-model="dateRange"
              type="datetimerange"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              value-format="YYYY-MM-DD HH:mm:ss"
              style="width: 360px"
            />
            <el-button link type="primary" class="quick-date-btn" @click="setToday">今日</el-button>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">查询</el-button>
            <el-button @click="handleReset">重置</el-button>
          </el-form-item>
        </el-form>
      </el-card>

      <el-card shadow="hover" class="table-card">
        <template #header>
          <div class="card-header">
            <span>任务链列表</span>
            <div v-if="!isMonitorMode">
              <el-button type="success" size="small" @click="handleScan">手动扫描执行</el-button>
            </div>
          </div>
        </template>

        <el-table
          ref="tableRef"
          :data="tableData"
          stripe
          border
          v-loading="loading"
        >
          <el-table-column prop="code" label="任务链编号" min-width="170" show-overflow-tooltip />
          <el-table-column prop="type" label="类型" width="140">
            <template #default="{ row }">
              <el-tag size="small">{{ typeMap[row.type] || row.type }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" width="100">
            <template #default="{ row }">
              <el-tag v-bind="getChainStatusTag(row.status)" size="small">
                {{ chainStatusMap[row.status] || row.status }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="firstTaskVendor" label="首任务厂商" width="100" />
          <el-table-column prop="businessNo" label="业务追踪号" min-width="150" show-overflow-tooltip />
          <el-table-column prop="sourceContainer" label="源容器" width="130" show-overflow-tooltip />
          <el-table-column prop="targetLocation" label="目标库位" width="130" show-overflow-tooltip />
          <el-table-column prop="priority" label="优先级" width="80" align="center" />
          <el-table-column prop="elevatorId" label="提升机" width="80" align="center">
            <template #default="{ row }">
              {{ row.elevatorId ? `#${row.elevatorId}` : '-' }}
            </template>
          </el-table-column>
          <el-table-column prop="executionTime" label="执行时间" width="90" align="center">
            <template #default="{ row }">
              {{ row.executionTime ? `${row.executionTime}s` : '-' }}
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="创建时间" width="170" />
          <el-table-column prop="completeTime" label="完成时间" width="170">
            <template #default="{ row }">
              {{ row.completeTime || '-' }}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="140" fixed="right">
            <template #default="{ row }">
              <el-button text type="primary" size="small" @click="goDetail(row.code)">详情</el-button>
              <el-button
                v-if="!isMonitorMode && (row.status === 'CREATED' || row.status === 'READY')"
                text type="warning" size="small"
                @click="handleExecute(row)"
              >
                执行
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <div class="pagination-wrap">
          <el-pagination
            v-model:current-page="query.page"
            v-model:page-size="query.size"
            :total="total"
            :page-sizes="[10, 20, 50, 100, 500]"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="loadData"
            @current-change="loadData"
          />
        </div>
      </el-card>
    </template>

    <!-- ========== 移动端 ========== -->
    <template v-else>
      <!-- 搜索栏 -->
      <div class="m-search-bar">
        <el-input
          v-model="query.code"
          placeholder="搜索任务链编号"
          clearable
          :prefix-icon="Search"
          @keyup.enter="handleSearch"
          @clear="handleSearch"
        />
        <el-badge :value="activeFilterCount" :hidden="activeFilterCount === 0" :max="9">
          <el-button :icon="Filter" circle @click="filterDrawerVisible = true" />
        </el-badge>
      </div>

      <!-- 手动扫描执行 -->
      <el-button v-if="!isMonitorMode" type="success" size="small" class="m-scan-btn" @click="handleScan">
        手动扫描执行
      </el-button>

      <!-- 日期快筛 -->
      <div class="m-date-tabs">
        <span
          :class="['m-status-chip', { 'm-status-chip-active': isTodayFilter }]"
          @click="setToday"
        >今日</span>
        <span
          :class="['m-status-chip', { 'm-status-chip-active': !dateRange?.length }]"
          @click="clearDateRange"
        >全部</span>
      </div>

      <!-- 状态快筛 -->
      <div class="m-status-tabs">
        <span
          v-for="(label, value) in { '': '全部', ...chainStatusMap }"
          :key="value"
          :class="['m-status-chip', { 'm-status-chip-active': query.status === value }]"
          @click="onStatusChip(value as string)"
        >{{ label }}</span>
      </div>

      <!-- 卡片列表 -->
      <div v-loading="loading" class="m-card-list">
        <div
          v-for="row in tableData"
          :key="row.code"
          class="m-chain-card"
          @click="goDetail(row.code)"
        >
          <div class="m-chain-card-top">
            <span class="m-chain-code">{{ row.code }}</span>
            <el-tag v-bind="getChainStatusTag(row.status)" size="small">
              {{ chainStatusMap[row.status] || row.status }}
            </el-tag>
          </div>
          <div class="m-chain-card-body">
            <div class="m-chain-field">
              <span class="m-field-label">类型</span>
              <el-tag size="small" type="info">{{ typeMap[row.type] || row.type }}</el-tag>
            </div>
            <div v-if="row.sourceContainer" class="m-chain-field">
              <span class="m-field-label">源容器</span>
              <span class="m-field-value">{{ row.sourceContainer }}</span>
            </div>
            <div v-if="row.targetLocation" class="m-chain-field">
              <span class="m-field-label">目标库位</span>
              <span class="m-field-value">{{ row.targetLocation }}</span>
            </div>
            <div v-if="row.elevatorId" class="m-chain-field">
              <span class="m-field-label">提升机</span>
              <span class="m-field-value">#{{ row.elevatorId }}</span>
            </div>
          </div>
          <div class="m-chain-card-footer">
            <span class="m-chain-time">{{ row.createTime }}</span>
            <div class="m-chain-actions" @click.stop>
              <el-button
                v-if="!isMonitorMode && (row.status === 'CREATED' || row.status === 'READY')"
                type="warning"
                size="small"
                @click="handleExecute(row)"
              >
                执行
              </el-button>
              <el-button text type="primary" size="small" @click="goDetail(row.code)">
                详情 <el-icon><ArrowRight /></el-icon>
              </el-button>
            </div>
          </div>
        </div>

        <el-empty v-if="!loading && tableData.length === 0" description="暂无数据" />
      </div>

      <!-- 移动端分页 -->
      <div class="m-pagination">
        <el-pagination
          v-model:current-page="query.page"
          :total="total"
          :page-size="query.size"
          layout="prev, slot, next"
          small
          @current-change="loadData"
        >
          <span class="m-page-info">{{ query.page }} / {{ Math.max(Math.ceil(total / query.size), 1) }}</span>
        </el-pagination>
      </div>

      <!-- 筛选抽屉 -->
      <el-drawer
        v-model="filterDrawerVisible"
        title="筛选条件"
        direction="btt"
        size="auto"
        :with-header="true"
      >
        <el-form :model="query" label-position="top">
          <el-form-item label="创建时间">
            <div class="m-drawer-date-actions">
              <el-button :type="isTodayFilter ? 'primary' : 'default'" @click="setToday">今日</el-button>
              <el-button @click="clearDateRange">清空</el-button>
            </div>
          </el-form-item>
          <el-form-item label="任务链编号">
            <el-input v-model="query.code" placeholder="请输入" clearable />
          </el-form-item>
          <el-form-item label="类型">
            <el-select v-model="query.type" placeholder="全部" clearable style="width: 100%">
              <el-option v-for="(label, value) in typeMap" :key="value" :label="label" :value="value" />
            </el-select>
          </el-form-item>
          <el-form-item label="业务追踪号">
            <el-input v-model="query.businessNo" placeholder="请输入" clearable />
          </el-form-item>
          <el-form-item label="源容器">
            <el-input v-model="query.sourceContainer" placeholder="请输入" clearable />
          </el-form-item>
          <el-form-item label="目标编码">
            <el-input v-model="query.targetCode" placeholder="请输入" clearable />
          </el-form-item>
        </el-form>
        <div class="m-drawer-footer">
          <el-button @click="handleReset">重置</el-button>
          <el-button type="primary" @click="filterDrawerVisible = false; handleSearch()">确认筛选</el-button>
        </div>
      </el-drawer>
    </template>
  </div>
</template>

<script setup lang="ts">
defineOptions({ name: 'TaskChainList' })
import { dispatchExecute, dispatchScan, getChainPage, type TaskChainVO } from '@/api/task'
import { ElMessage, ElMessageBox, type TableInstance } from 'element-plus'
import { Search, Filter, ArrowRight } from '@element-plus/icons-vue'
import { computed, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useDevice } from '@/composables/useDevice'
import { chainStatusMap, getChainStatusTag } from '@/constants/chainStatus'
import { useUserStore } from '@/stores/user'

const { isMobile } = useDevice()
const userStore = useUserStore()
const isMonitorMode = computed(() => userStore.isMonitorMode())
const router = useRouter()
const tableRef = ref<TableInstance>()
const loading = ref(false)
const tableData = ref<TaskChainVO[]>([])
const total = ref(0)
const dateRange = ref<string[]>([])
const filterDrawerVisible = ref(false)

function onHeaderDblClick(e: MouseEvent) {
  const th = (e.target as HTMLElement).closest('th')
  if (!th || !tableRef.value) return
  const colId = Array.from(th.classList).find((c) => c.startsWith('el-table_'))
  if (!colId) return

  const el = tableRef.value.$el as HTMLElement
  const cells = el.querySelectorAll<HTMLElement>(`.el-table__body .${colId} .cell`)
  if (!cells.length) return

  const measure = document.createElement('span')
  measure.style.cssText = 'visibility:hidden;position:absolute;white-space:nowrap;'
  document.body.appendChild(measure)

  let maxWidth = 0
  cells.forEach((cell) => {
    const style = getComputedStyle(cell)
    measure.style.fontSize = style.fontSize
    measure.style.fontFamily = style.fontFamily
    measure.style.fontWeight = style.fontWeight
    measure.innerHTML = cell.innerHTML
    maxWidth = Math.max(maxWidth, measure.offsetWidth)
  })
  document.body.removeChild(measure)

  if (maxWidth > 0) {
    const columns = (tableRef.value as unknown as { store: { states: { columns: { value: { id: string; realWidth: number; width: number }[] } } } }).store.states.columns.value
    const col = columns.find((c) => c.id === colId)
    if (col) {
      const newWidth = Math.min(Math.max(maxWidth + 32, 80), 800)
      col.width = newWidth
      col.realWidth = newWidth
      nextTick(() => tableRef.value?.doLayout())
    }
  }
}

let headerEl: HTMLElement | null = null

onMounted(() => {
  nextTick(() => {
    if (tableRef.value) {
      headerEl = (tableRef.value.$el as HTMLElement).querySelector('.el-table__header-wrapper')
      headerEl?.addEventListener('dblclick', onHeaderDblClick)
    }
  })
})

onUnmounted(() => {
  headerEl?.removeEventListener('dblclick', onHeaderDblClick)
})

const query = reactive({
  page: 1,
  size: 10,
  code: '',
  status: '',
  type: '',
  businessNo: '',
  sourceContainer: '',
  targetCode: '',
})

const activeFilterCount = computed(() => {
  let n = 0
  if (query.type) n++
  if (query.businessNo) n++
  if (query.sourceContainer) n++
  if (query.targetCode) n++
  if (dateRange.value?.length) n++
  return n
})

const isTodayFilter = computed(() => {
  const range = dateRange.value
  if (!range?.length || range.length < 2) return false
  const today = new Date()
  const start = range[0]
  const end = range[1]
  const todayStr = today.toISOString().slice(0, 10)
  return start?.startsWith(todayStr) && end?.startsWith(todayStr)
})

function getTodayRange(): [string, string] {
  const d = new Date()
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  return [`${y}-${m}-${day} 00:00:00`, `${y}-${m}-${day} 23:59:59`]
}

function setToday() {
  dateRange.value = getTodayRange()
  handleSearch()
}

function clearDateRange() {
  dateRange.value = []
  handleSearch()
}

const typeMap: Record<string, string> = {
  INBOUND: '入库', QUICK_PALLET_INBOUND: '托盘快速入库',
  OUTBOUND: '出库', OUTBOUND_NEW: '拣货出库(新模版)',
  OUTBOUND_NO_WAIT: '出库(不等待)', OUTBOUND_NO_WAIT_NEW: '直出模式(新模版)', MOVE: '移库', MOVE_NEW: '移库(新模版)',
}

async function loadData() {
  loading.value = true
  try {
    const params = {
      ...query,
      startTime: dateRange.value?.[0] || undefined,
      endTime: dateRange.value?.[1] || undefined,
    }
    const res = await getChainPage(params)
    tableData.value = res.data.records || []
    if (res.data.total > 0) {
      total.value = res.data.total
    }
  } catch { /* handled by interceptor */ } finally {
    loading.value = false
  }
}

function handleSearch() {
  query.page = 1
  loadData()
}

function handleReset() {
  query.code = ''
  query.status = ''
  query.type = ''
  query.businessNo = ''
  query.sourceContainer = ''
  query.targetCode = ''
  dateRange.value = []
  handleSearch()
}

function onStatusChip(value: string) {
  query.status = value
  handleSearch()
}

function goDetail(code: string) {
  router.push(`/task/chain/${code}`)
}

async function handleScan() {
  try {
    const result = await ElMessageBox.prompt('请输入仓库编码', '手动扫描执行', {
      confirmButtonText: '执行',
      cancelButtonText: '取消',
      inputValue: 'WH01',
      inputPattern: /\S+/,
      inputErrorMessage: '仓库编码不能为空',
    })
    if (typeof result === 'object' && 'value' in result) {
      await dispatchScan(result.value)
      ElMessage.success('扫描执行已触发')
      loadData()
    }
  } catch { /* cancelled */ }
}

async function handleExecute(row: TaskChainVO) {
  try {
    await ElMessageBox.confirm(`确认手动执行任务链 ${row.code}？`, '确认', { type: 'warning' })
    await dispatchExecute(row.warehouse, row.code)
    ElMessage.success('执行已触发')
    loadData()
  } catch { /* cancelled */ }
}

onMounted(loadData)
</script>

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

/* ===== PC ===== */
.filter-card :deep(.el-card__body) {
  padding-bottom: 2px;
}

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

.pagination-wrap {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}

/* ===== 移动端 ===== */
.m-search-bar {
  display: flex;
  align-items: center;
  gap: 8px;
}

.m-scan-btn {
  width: 100%;
}

.m-status-tabs {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}

.m-status-tabs::-webkit-scrollbar {
  display: none;
}

.m-status-chip {
  flex-shrink: 0;
  padding: 4px 12px;
  border-radius: 14px;
  font-size: 12px;
  color: #606266;
  background: #f0f2f5;
  cursor: pointer;
  transition: all 0.2s;
  -webkit-tap-highlight-color: transparent;
}

.m-status-chip-active {
  background: #409eff;
  color: #fff;
}

.m-card-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 200px;
}

.m-chain-card {
  background: #fff;
  border-radius: 10px;
  padding: 14px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: box-shadow 0.2s;
}

.m-chain-card:active {
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12);
}

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

.m-chain-code {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 65%;
}

.m-chain-card-body {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-bottom: 10px;
}

.m-chain-field {
  display: flex;
  align-items: center;
  gap: 4px;
}

.m-field-label {
  font-size: 12px;
  color: #909399;
}

.m-field-value {
  font-size: 12px;
  color: #303133;
}

.m-chain-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #c0c4cc;
  font-size: 12px;
}

.m-chain-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.m-chain-time {
  color: #909399;
}

.m-pagination {
  display: flex;
  justify-content: center;
  padding: 4px 0;
}

.m-page-info {
  font-size: 13px;
  color: #606266;
  margin: 0 8px;
}

.m-drawer-footer {
  display: flex;
  gap: 12px;
  padding-top: 16px;
}

.m-drawer-footer .el-button {
  flex: 1;
}

.quick-date-btn {
  margin-left: 8px;
}

.m-date-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 8px;
}

.m-drawer-date-actions {
  display: flex;
  gap: 8px;
}
</style>
