<template>
  <div class="production-page app-container" v-loading="loading">
    <el-card shadow="never" class="page-head">
      <div class="page-head__row">
        <div class="page-title">
          <div class="page-title__main">生产任务</div>
          <div class="page-title__sub">任务清单 / 明细 / 回执</div>
        </div>
        <div class="page-actions">
          <el-button type="primary" @click="openAdd">新增任务</el-button>
          <el-button @click="loadTasks">刷新</el-button>
        </div>
      </div>
      <div class="page-head__row page-head__row--date">
        <div class="date-bar">
          <el-radio-group v-model="datePreset" size="small" @change="applyDatePreset">
            <el-radio-button label="today">今天</el-radio-button>
            <el-radio-button label="yesterday">昨天</el-radio-button>
            <el-radio-button label="last7">近7天</el-radio-button>
            <el-radio-button label="thisMonth">本月</el-radio-button>
            <el-radio-button label="custom">自定义</el-radio-button>
          </el-radio-group>
          <el-popover
            v-if="datePreset === 'custom'"
            v-model:visible="customPopoverOpen"
            placement="bottom-start"
            trigger="click"
            width="360"
          >
            <template #reference>
              <el-button size="small" plain class="custom-range-btn">{{ customRangeLabel }}</el-button>
            </template>
            <el-date-picker
              v-model="customRange"
              type="daterange"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              unlink-panels
              teleported
              style="width: 320px;"
              @change="onCustomRangePicked"
            />
          </el-popover>
        </div>
      </div>
      <div class="page-head__row page-head__row--filters">
        <el-form :inline="true" class="filter-form">
          <el-form-item label="状态">
            <el-select v-model="filters.status" placeholder="全部" clearable style="width: 140px;">
              <el-option label="进行中" value="1" />
              <el-option label="已完成" value="2" />
              <el-option label="已暂停" value="3" />
            </el-select>
          </el-form-item>
          <el-form-item label="关键词">
            <el-input v-model="filters.keyword" placeholder="任务名称/编号" clearable style="width: 240px;" />
          </el-form-item>
        </el-form>
        <div class="page-stats">
          <el-tag type="info" effect="light">全部 {{ taskList.length }}</el-tag>
          <el-tag type="success" effect="light" style="margin-left: 8px;">进行中 {{ runningCount }}</el-tag>
          <el-tag type="warning" effect="light" style="margin-left: 8px;">暂停 {{ pausedCount }}</el-tag>
          <el-tag type="danger" effect="light" style="margin-left: 8px;">完成 {{ finishedCount }}</el-tag>
        </div>
      </div>
    </el-card>

    <el-row :gutter="12">
      <el-col :span="6">
        <el-card shadow="never" class="left-card">
          <template #header>
            <div class="card-header">
              <span>任务清单</span>
              <div>
                <el-button type="primary" link @click="openAdd">新增</el-button>
                <el-button type="primary" link @click="loadTasks">刷新</el-button>
              </div>
            </div>
          </template>
          <div class="task-list">
            <el-empty v-if="!filteredTaskList.length" description="暂无任务" />
            <el-scrollbar v-else height="640px">
              <div
                v-for="t in filteredTaskList"
                :key="t.taskId"
                class="task-item"
                :class="{ active: t.taskId === selectedTaskId }"
                @click="selectTask(t.taskId)"
              >
                <div class="task-item__top">
                  <div class="task-item__title">{{ t.taskName || t.taskCode || ('任务' + t.taskId) }}</div>
                  <el-tag size="small" :type="statusTagType(t.status)" effect="light">{{ statusLabel(t.status) }}</el-tag>
                </div>
                <div class="task-item__sub">
                  <span>计划 {{ formatQty(t.planQty) }}</span>
                  <span style="margin-left: 10px;">已完 {{ formatQty(t.finishedQty) }}</span>
                  <span style="margin-left: 10px;">未完 {{ formatQty(t.unfinishedQty) }}</span>
                </div>
                <div class="task-item__meta">
                  <span v-if="t.planStartTime || t.planEndTime">计划 {{ formatTimeRange(t.planStartTime, t.planEndTime) }}</span>
                  <span v-if="t.createBy" style="margin-left: 10px;">创建 {{ t.createBy }}</span>
                  <span v-if="t.updateTime" style="margin-left: 10px;">更新 {{ formatTime(t.updateTime) }}</span>
                </div>
                <el-progress :percentage="taskProgressPercent(t)" :stroke-width="8" :show-text="false" />
              </div>
            </el-scrollbar>
          </div>
        </el-card>
      </el-col>

      <el-col :span="18">
        <el-card shadow="never" class="mb12">
          <template #header>
            <div class="card-header">
              <span>任务明细</span>
              <div v-if="selectedTask" class="card-header__right">
                <div class="card-meta">
                  <span class="meta-main">{{ selectedTask.taskName || selectedTask.taskCode || ('任务' + selectedTask.taskId) }}</span>
                  <el-tag size="small" :type="statusTagType(selectedTask.status)" effect="light" style="margin-left: 8px;">{{ statusLabel(selectedTask.status) }}</el-tag>
                </div>
                <el-button
                  v-if="String(selectedTask.status) === '1'"
                  size="small"
                  type="primary"
                  :loading="completeLoading"
                  @click="completeSelectedTask"
                >
                  完成任务
                </el-button>
              </div>
            </div>
          </template>
          <el-empty v-if="!selectedTaskId" description="请选择任务" />
          <el-table v-else :data="productRows" size="small" border stripe :header-cell-style="{ background: '#f5f7fa' }">
            <el-table-column label="产品" prop="productName" min-width="180" show-overflow-tooltip />
            <el-table-column label="规格" prop="spec" width="140" show-overflow-tooltip />
            <el-table-column label="型号" prop="model" width="140" show-overflow-tooltip />
            <el-table-column label="计划数量" prop="planQty" width="120" align="right">
              <template #default="scope">{{ formatQty(scope.row.planQty) }}</template>
            </el-table-column>
            <el-table-column label="已完成" prop="finishedQty" width="120" align="right">
              <template #default="scope">{{ formatQty(scope.row.finishedQty) }}</template>
            </el-table-column>
            <el-table-column label="不良" prop="badQty" width="120" align="right">
              <template #default="scope">{{ formatQty(scope.row.badQty) }}</template>
            </el-table-column>
            <el-table-column label="单位" prop="unit" width="90" />
          </el-table>
        </el-card>

        <el-card shadow="never">
          <template #header>
            <div class="card-header">
              <span>任务回执</span>
              <div v-if="selectedTask" class="card-meta">
                <span class="meta-sub">主材 / 辅材 / 产品概况</span>
              </div>
            </div>
          </template>
          <el-empty v-if="!selectedTaskId" description="请选择任务" />
          <el-tabs v-else type="border-card">
            <el-tab-pane label="主材">
              <el-table :data="mainMaterialRows" size="small" border stripe :header-cell-style="{ background: '#f5f7fa' }">
                <el-table-column label="名称" prop="materialName" min-width="180" show-overflow-tooltip />
                <el-table-column label="计划" prop="planQty" width="120" align="right">
                  <template #default="scope">{{ formatQty(scope.row.planQty) }}</template>
                </el-table-column>
                <el-table-column label="已用" prop="usedQty" width="120" align="right">
                  <template #default="scope">{{ formatQty(scope.row.usedQty) }}</template>
                </el-table-column>
                <el-table-column label="单位" prop="unit" width="90" />
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="辅材">
              <el-table :data="auxMaterialRows" size="small" border stripe :header-cell-style="{ background: '#f5f7fa' }">
                <el-table-column label="名称" prop="materialName" min-width="180" show-overflow-tooltip />
                <el-table-column label="计划" prop="planQty" width="120" align="right">
                  <template #default="scope">{{ formatQty(scope.row.planQty) }}</template>
                </el-table-column>
                <el-table-column label="已用" prop="usedQty" width="120" align="right">
                  <template #default="scope">{{ formatQty(scope.row.usedQty) }}</template>
                </el-table-column>
                <el-table-column label="单位" prop="unit" width="90" />
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="产品概况">
              <el-table :data="productRows" size="small" border stripe :header-cell-style="{ background: '#f5f7fa' }">
                <el-table-column label="产品" prop="productName" min-width="180" show-overflow-tooltip />
                <el-table-column label="规格/型号" min-width="200">
                  <template #default="scope">
                    {{ (scope.row.spec || '-') + ' / ' + (scope.row.model || '-') }}
                  </template>
                </el-table-column>
                <el-table-column label="计划" prop="planQty" width="120" align="right">
                  <template #default="scope">{{ formatQty(scope.row.planQty) }}</template>
                </el-table-column>
                <el-table-column label="已完成" prop="finishedQty" width="120" align="right">
                  <template #default="scope">{{ formatQty(scope.row.finishedQty) }}</template>
                </el-table-column>
                <el-table-column label="不良" prop="badQty" width="120" align="right">
                  <template #default="scope">{{ formatQty(scope.row.badQty) }}</template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </el-col>
    </el-row>

    <el-dialog v-model="addOpen" title="新增生产任务" width="1100px" top="5vh" append-to-body>
      <el-form ref="addFormRef" :model="addForm" :rules="addRules" label-width="100px">
        <el-row :gutter="12">
          <el-col :span="8">
            <el-form-item label="任务编号" prop="taskCode">
              <el-input v-model="addForm.taskCode" placeholder="可不填" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="任务名称" prop="taskName">
              <el-input v-model="addForm.taskName" placeholder="请输入任务名称" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="状态" prop="status">
              <el-select v-model="addForm.status" placeholder="请选择">
                <el-option label="进行中" value="1" />
                <el-option label="已完成" value="2" />
                <el-option label="已暂停" value="3" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="计划开始" prop="planStartTime">
              <el-date-picker v-model="addForm.planStartTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" style="width: 100%;" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="计划结束" prop="planEndTime">
              <el-date-picker v-model="addForm.planEndTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" style="width: 100%;" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="备注" prop="remark">
              <el-input v-model="addForm.remark" type="textarea" :rows="2" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <el-divider content-position="left">生产产品明细</el-divider>
      <div style="margin-bottom: 8px;">
        <el-button type="primary" @click="addProductLine">新增产品行</el-button>
      </div>
      <el-table :data="addProducts" border size="small" :header-cell-style="{ background: '#f5f7fa' }">
        <el-table-column label="产品" min-width="220">
          <template #default="scope">
            <el-select v-model="scope.row.productId" filterable clearable placeholder="请选择" style="width: 100%;" @change="onProductPicked(scope.row)">
              <el-option v-for="p in productOptions" :key="p.productId" :label="p.productName" :value="p.productId" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="计划数量" width="140" align="right">
          <template #default="scope">
            <el-input-number v-model="scope.row.planQty" :min="0" :precision="4" controls-position="right" style="width: 120px;" />
          </template>
        </el-table-column>
        <el-table-column label="单位" width="140">
          <template #default="scope">
            <el-input v-model="scope.row.unit" placeholder="单位" />
          </template>
        </el-table-column>
        <el-table-column label="备注" min-width="200">
          <template #default="scope">
            <el-input v-model="scope.row.remark" placeholder="备注" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="90" align="center">
          <template #default="scope">
            <el-button type="danger" link @click="removeProductLine(scope.$index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <template #footer>
        <el-button @click="addOpen = false">取消</el-button>
        <el-button type="primary" :loading="addSaving" @click="submitAdd">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="Production">
import { computed, onMounted, ref } from 'vue'
import { addProductionTask, completeProductionTask, getProductionTask, listProductionTask } from '@/api/mes/productionTask'
import { listProductBase } from '@/api/mat/product'
import { ElMessage, ElMessageBox } from 'element-plus'

const loading = ref(false)
const taskList = ref([])
const selectedTaskId = ref(null)
const productRows = ref([])
const materialRows = ref([])
const datePreset = ref('today')
const customRange = ref([])
const customPopoverOpen = ref(false)
const filters = ref({
  status: '1',
  keyword: '',
  beginTime: '',
  endTime: ''
})

const addOpen = ref(false)
const addSaving = ref(false)
const completeLoading = ref(false)
const addFormRef = ref()
const addForm = ref({
  taskCode: '',
  taskName: '',
  status: '1',
  planStartTime: '',
  planEndTime: '',
  remark: ''
})
const addRules = {
  taskName: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }]
}

const productOptions = ref([])
const addProducts = ref([])

function toNumber(v) {
  const n = Number(v)
  return Number.isFinite(n) ? n : 0
}

function formatQty(v) {
  return toNumber(v).toFixed(2)
}

function normalizeRole(v) {
  return String(v || '').toLowerCase()
}

function formatTime(v) {
  if (!v) return '-'
  if (v instanceof Date) {
    return formatDateTime(v).slice(0, 16)
  }
  const s = String(v)
  if (s.length >= 16) return s.slice(0, 16)
  return s
}

function formatTimeRange(start, end) {
  const a = start ? formatTime(start) : '-'
  const b = end ? formatTime(end) : '-'
  return `${a} ~ ${b}`
}

function pad2(n) {
  return String(n).padStart(2, '0')
}

function formatDateTime(dt) {
  const d = dt instanceof Date ? dt : new Date(dt)
  return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`
}

function startOfDay(d) {
  const x = new Date(d)
  x.setHours(0, 0, 0, 0)
  return x
}

function endOfDay(d) {
  const x = new Date(d)
  x.setHours(23, 59, 59, 999)
  return x
}

function addDays(d, n) {
  const x = new Date(d)
  x.setDate(x.getDate() + n)
  return x
}

function startOfMonth(d) {
  const x = new Date(d)
  x.setDate(1)
  x.setHours(0, 0, 0, 0)
  return x
}

function applyDatePreset() {
  const now = new Date()
  let begin = null
  let end = null
  const p = String(datePreset.value || '')
  if (p === 'today') {
    begin = startOfDay(now)
    end = endOfDay(now)
  } else if (p === 'yesterday') {
    const y = addDays(now, -1)
    begin = startOfDay(y)
    end = endOfDay(y)
  } else if (p === 'last7') {
    begin = startOfDay(addDays(now, -6))
    end = endOfDay(now)
  } else if (p === 'thisMonth') {
    begin = startOfMonth(now)
    end = endOfDay(now)
  } else if (p === 'custom') {
    if (!customRange.value || customRange.value.length !== 2) {
      const b = startOfDay(now)
      const e = endOfDay(now)
      customRange.value = [formatDateTime(b).slice(0, 10), formatDateTime(e).slice(0, 10)]
      filters.value.beginTime = formatDateTime(b)
      filters.value.endTime = formatDateTime(e)
      loadTasks()
    }
    customPopoverOpen.value = true
    return
  }

  if (begin && end) {
    filters.value.beginTime = formatDateTime(begin)
    filters.value.endTime = formatDateTime(end)
    loadTasks()
  }
}

function applyCustomRange(v) {
  if (!v || v.length !== 2) return
  datePreset.value = 'custom'
  const begin = startOfDay(new Date(v[0]))
  const end = endOfDay(new Date(v[1]))
  filters.value.beginTime = formatDateTime(begin)
  filters.value.endTime = formatDateTime(end)
  loadTasks()
}

const customRangeLabel = computed(() => {
  const v = customRange.value
  if (Array.isArray(v) && v.length === 2 && v[0] && v[1]) {
    return `${v[0]} ~ ${v[1]}`
  }
  return '选择日期范围'
})

function onCustomRangePicked(v) {
  applyCustomRange(v)
  customPopoverOpen.value = false
}

function statusLabel(v) {
  const s = String(v || '')
  if (s === '1') return '进行中'
  if (s === '2') return '已完成'
  if (s === '3') return '已暂停'
  return s || '-'
}

function statusTagType(v) {
  const s = String(v || '')
  if (s === '1') return 'success'
  if (s === '2') return 'danger'
  if (s === '3') return 'warning'
  return 'info'
}

function taskProgressPercent(t) {
  const plan = toNumber(t && t.planQty)
  const finished = toNumber(t && t.finishedQty)
  if (plan <= 0) return 0
  const p = Math.round((finished / plan) * 100)
  return Math.max(0, Math.min(100, p))
}

function selectTask(taskId) {
  selectedTaskId.value = taskId
  loading.value = true
  return getProductionTask(taskId)
    .then((res) => {
      const data = res && res.data ? res.data : {}
      productRows.value = Array.isArray(data.products) ? data.products : []
      materialRows.value = Array.isArray(data.materials) ? data.materials : []
    })
    .finally(() => {
      loading.value = false
    })
}

const mainMaterialRows = computed(() => (materialRows.value || []).filter((r) => normalizeRole(r && r.materialRole) === 'main'))
const auxMaterialRows = computed(() => (materialRows.value || []).filter((r) => normalizeRole(r && r.materialRole) === 'aux'))

const selectedTask = computed(() => (taskList.value || []).find((t) => String(t.taskId) === String(selectedTaskId.value)) || null)
const runningCount = computed(() => (taskList.value || []).filter((t) => String(t && t.status) === '1').length)
const finishedCount = computed(() => (taskList.value || []).filter((t) => String(t && t.status) === '2').length)
const pausedCount = computed(() => (taskList.value || []).filter((t) => String(t && t.status) === '3').length)

const filteredTaskList = computed(() => {
  const list = Array.isArray(taskList.value) ? taskList.value : []
  const st = String(filters.value && filters.value.status ? filters.value.status : '')
  const kw = String(filters.value && filters.value.keyword ? filters.value.keyword : '').trim().toLowerCase()
  return list.filter((t) => {
    if (st && String(t && t.status) !== st) return false
    if (kw) {
      const a = String(t && t.taskName ? t.taskName : '').toLowerCase()
      const b = String(t && t.taskCode ? t.taskCode : '').toLowerCase()
      if (!a.includes(kw) && !b.includes(kw)) return false
    }
    return true
  })
})

function loadTasks() {
  loading.value = true
  const q = {
    pageNum: 1,
    pageSize: 9999,
    status: filters.value && filters.value.status ? filters.value.status : undefined,
    beginTime: filters.value && filters.value.beginTime ? filters.value.beginTime : undefined,
    endTime: filters.value && filters.value.endTime ? filters.value.endTime : undefined
  }
  return listProductionTask(q)
    .then((res) => {
      const rows = (res && res.rows) ? res.rows : []
      taskList.value = rows
      if (!selectedTaskId.value && taskList.value.length) {
        const first = filteredTaskList.value && filteredTaskList.value.length ? filteredTaskList.value[0] : taskList.value[0]
        return selectTask(first.taskId)
      }
      if (selectedTaskId.value) {
        const hit = (taskList.value || []).some((t) => t.taskId === selectedTaskId.value)
        if (hit) return selectTask(selectedTaskId.value)
      }
    })
    .finally(() => {
      loading.value = false
    })
}

function openAdd() {
  addOpen.value = true
  addForm.value = {
    taskCode: '',
    taskName: '',
    status: '1',
    planStartTime: '',
    planEndTime: '',
    remark: ''
  }
  addProducts.value = []
  addProductLine()
  ensureProductOptions()
}

function ensureProductOptions() {
  if (productOptions.value && productOptions.value.length) return
  listProductBase({ pageNum: 1, pageSize: 1000 }).then((res) => {
    productOptions.value = (res && res.rows) ? res.rows : []
  })
}

function addProductLine() {
  addProducts.value.push({ productId: null, planQty: 0, unit: '', remark: '' })
}

function removeProductLine(idx) {
  addProducts.value.splice(idx, 1)
}

function onProductPicked(row) {
  if (!row || !row.productId) return
  const hit = (productOptions.value || []).find((p) => String(p.productId) === String(row.productId))
  if (hit && !row.unit) {
    row.unit = ''
  }
}

function mergeProductLines(lines) {
  const list = Array.isArray(lines) ? lines : []
  const map = new Map()
  list.forEach((p) => {
    if (!p || p.productId == null) return
    const key = String(p.productId)
    const planQty = toNumber(p.planQty)
    if (!map.has(key)) {
      map.set(key, {
        productId: p.productId,
        planQty,
        unit: p.unit || '',
        remark: p.remark || ''
      })
      return
    }
    const hit = map.get(key)
    hit.planQty = toNumber(hit.planQty) + planQty
    if (!hit.unit && p.unit) hit.unit = p.unit
    if (!hit.remark && p.remark) hit.remark = p.remark
  })
  return Array.from(map.values())
}

function submitAdd() {
  if (!addFormRef.value) return
  addFormRef.value.validate((valid) => {
    if (!valid) return
    const task = Object.assign({}, addForm.value)
    const products = mergeProductLines(addProducts.value).map((p) => ({
      productId: p.productId,
      planQty: p.planQty || 0,
      finishedQty: 0,
      badQty: 0,
      unit: p.unit || '',
      remark: p.remark || ''
    }))

    addSaving.value = true
    addProductionTask({ task, products })
      .then((res) => {
        const taskId = res && res.data ? res.data : null
        ElMessage.success('已新增')
        addOpen.value = false
        return loadTasks().then(() => {
          if (taskId != null) {
            selectedTaskId.value = taskId
            return selectTask(taskId)
          }
        })
      })
      .finally(() => {
        addSaving.value = false
      })
  })
}

function completeSelectedTask() {
  const task = selectedTask.value
  const taskId = selectedTaskId.value
  if (!task || taskId == null) return
  completeLoading.value = true
  return ElMessageBox.confirm('完成后将根据产品配方自动生成主材/辅材回执，是否继续？', '确认完成', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => completeProductionTask(taskId))
    .then(() => {
      ElMessage.success('已完成')
      return loadTasks().then(() => selectTask(taskId))
    })
    .catch((e) => {
      const s = String(e || '')
      if (s && s !== 'cancel' && s !== 'close') {
        ElMessage.error('操作失败')
      }
    })
    .finally(() => {
      completeLoading.value = false
    })
}

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

<style scoped>
.production-page {
  padding: 0;
}

.production-page :deep(.el-card) {
  border-radius: 10px;
}

.production-page :deep(.el-card__header) {
  background: #fafafa;
}

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

.card-header__right {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.card-meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 0;
}

.meta-main {
  max-width: 520px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #303133;
  font-weight: 700;
}

.meta-sub {
  color: #909399;
  font-size: 12px;
}

.page-head {
  margin-bottom: 12px;
}

.page-head__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.page-head__row--filters {
  margin-top: 10px;
}

.page-head__row--date {
  margin-top: 10px;
}

.date-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  flex-wrap: wrap;
}

.custom-range-btn {
  min-width: 180px;
  justify-content: flex-start;
}

.page-title__main {
  font-size: 18px;
  font-weight: 800;
  color: #303133;
}

.page-title__sub {
  margin-top: 2px;
  font-size: 12px;
  color: #909399;
}

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

.filter-form :deep(.el-form-item) {
  margin-bottom: 0;
}

.page-stats {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.task-item {
  padding: 10px 10px;
  border: 1px solid var(--el-border-color-light);
  border-radius: 6px;
  margin-bottom: 10px;
  cursor: pointer;
  background: #fff;
  transition: all 0.15s ease;
}

.task-item:hover {
  border-color: rgba(64, 158, 255, 0.55);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06);
}

.task-item.active {
  border-color: #409eff;
  background: rgba(64, 158, 255, 0.08);
}

.task-item__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.task-item__title {
  font-size: 14px;
  font-weight: 700;
  color: #303133;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.task-item__sub {
  margin-top: 6px;
  font-size: 12px;
  color: #909399;
  margin-bottom: 8px;
}

.task-item__meta {
  margin-top: -2px;
  margin-bottom: 8px;
  font-size: 12px;
  color: #c0c4cc;
}

.mb12 {
  margin-bottom: 12px;
}

</style>
