import { Button, Card, Form, Select, Space, Table, Tag, Toast, Typography } from '@douyinfe/semi-ui';
import { useEffect, useState } from 'react';
import { api } from '../api/client';
import type { DailyMileageRow, MileageSummary, OnlineStatisticsSummary, OnlineVehicleStatusRow } from '../api/types';
import { PageHeader } from '../components/PageHeader';
import { buildAppHash } from '../domain/appRoute';
import { buildCsv, downloadCsv, type CsvColumn } from '../domain/csvExport';

const emptySummary: MileageSummary = {
  vehicleCount: 0,
  recordCount: 0,
  sourceCount: 0,
  totalMileageKm: 0,
  averageMileagePerVin: 0
};

function numberOrZero(value: unknown) {
  const numeric = Number(value);
  return Number.isFinite(numeric) ? numeric : 0;
}

function normalizeMileageSummary(summary?: Partial<MileageSummary> | null): MileageSummary {
  return {
    ...emptySummary,
    ...(summary ?? {}),
    vehicleCount: numberOrZero(summary?.vehicleCount),
    recordCount: numberOrZero(summary?.recordCount),
    sourceCount: numberOrZero(summary?.sourceCount),
    totalMileageKm: numberOrZero(summary?.totalMileageKm),
    averageMileagePerVin: numberOrZero(summary?.averageMileagePerVin)
  };
}

const emptyOnlineSummary: OnlineStatisticsSummary = {
  vehicleCount: 0,
  onlineVehicleCount: 0,
  offlineVehicleCount: 0,
  onlineRatePercent: 0,
  redisOnlineKeys: null,
  protocolStats: [],
  evidence: ''
};

function mileageParams(values: Record<string, string>, pageSize?: number, offset?: number) {
  const params = new URLSearchParams();
  if (pageSize != null) params.set('limit', String(pageSize));
  if (offset != null) params.set('offset', String(offset));
  if (values?.keyword) params.set('keyword', values.keyword);
  if (values?.protocol) params.set('protocol', values.protocol);
  if (values?.dateFrom) params.set('dateFrom', values.dateFrom);
  if (values?.dateTo) params.set('dateTo', values.dateTo);
  return params;
}

function formatKm(value: number) {
  return Number.isFinite(value) ? value.toLocaleString(undefined, { maximumFractionDigits: 1 }) : '0';
}

function formatPercent(value: number) {
  return Number.isFinite(value) ? `${value.toLocaleString(undefined, { maximumFractionDigits: 1 })}%` : '0%';
}

function formatOfflineDuration(minutes?: number | null) {
  if (minutes == null || !Number.isFinite(Number(minutes))) return '-';
  const value = Math.max(0, Number(minutes));
  if (value < 60) return `${value.toLocaleString()} 分钟`;
  const hours = Math.floor(value / 60);
  const rest = Math.round(value % 60);
  return rest > 0 ? `${hours.toLocaleString()} 小时 ${rest} 分钟` : `${hours.toLocaleString()} 小时`;
}

function canOpenVehicle(vin?: string) {
  const value = vin?.trim();
  return Boolean(value && value !== 'unknown');
}

function nextDate(value: string) {
  const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
  if (!match) return '';
  const date = new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3]) + 1));
  return date.toISOString().slice(0, 10);
}

function mileageActionRecommendation(row: DailyMileageRow) {
  if (row.anomalySeverity) {
    return {
      label: '核对里程来源',
      color: 'orange' as const,
      detail: '日里程异常，优先核对当天首末总里程、来源断链和补传数据。'
    };
  }
  return {
    label: '可用于日报统计',
    color: 'green' as const,
    detail: '该日里程未发现异常，可进入车辆服务查看统计依据。'
  };
}

function mergeInitialFilters(initialVin: string, initialProtocol?: string, initialFilters: Record<string, string> = {}) {
  return {
    keyword: initialVin,
    protocol: initialProtocol ?? '',
    ...initialFilters
  };
}

function groupMileageByDate(rows: DailyMileageRow[]) {
  const bucket = new Map<string, number>();
  rows.forEach((row) => {
    bucket.set(row.date || '-', (bucket.get(row.date || '-') ?? 0) + row.dailyMileageKm);
  });
  return [...bucket.entries()]
    .map(([date, value]) => ({ date, value }))
    .sort((a, b) => a.date.localeCompare(b.date));
}

function groupMileageBySource(rows: DailyMileageRow[]) {
  const bucket = new Map<string, number>();
  rows.forEach((row) => {
    bucket.set(row.source || 'UNKNOWN', (bucket.get(row.source || 'UNKNOWN') ?? 0) + row.dailyMileageKm);
  });
  return [...bucket.entries()]
    .map(([source, value]) => ({ source, value }))
    .sort((a, b) => b.value - a.value);
}

function maxMileageRow(rows: DailyMileageRow[]) {
  return rows.reduce<DailyMileageRow | undefined>((max, row) => {
    if (!max || row.dailyMileageKm > max.dailyMileageKm) return row;
    return max;
  }, undefined);
}

const mileageExportColumns: CsvColumn<DailyMileageRow>[] = [
  { title: '日期', value: (row) => row.date },
  { title: 'VIN', value: (row) => row.vin },
  { title: '车牌', value: (row) => row.plate },
  { title: '来源', value: (row) => row.source },
  { title: '起始里程km', value: (row) => row.startMileageKm },
  { title: '结束里程km', value: (row) => row.endMileageKm },
  { title: '日里程km', value: (row) => row.dailyMileageKm },
  { title: '异常', value: (row) => row.anomalySeverity || '正常' }
];

function exportFileName(filters: Record<string, string>) {
  const keyword = filters.keyword?.trim() || 'all';
  const protocol = filters.protocol?.trim() || 'all-source';
  return `daily-mileage-${keyword}-${protocol}.csv`;
}

function appURL(hash: string) {
  return `${window.location.origin}${window.location.pathname}${hash}`;
}

function mileageSummaryText({
  filters,
  summary,
  pageMileageTotal,
  anomalyCount,
  peakMileage,
  statisticsURL,
  vehicleURL
}: {
  filters: Record<string, string>;
  summary: MileageSummary;
  pageMileageTotal: number;
  anomalyCount: number;
  peakMileage?: DailyMileageRow;
  statisticsURL: string;
  vehicleURL?: string;
}) {
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  const dateFrom = filters.dateFrom?.trim();
  const dateTo = filters.dateTo?.trim();
  const dateRange = dateFrom || dateTo ? `${dateFrom || '-'} 至 ${dateTo || '-'}` : '全部日期';
  const peak = peakMileage
    ? `${peakMileage.plate || peakMileage.vin} / ${peakMileage.date} / ${formatKm(peakMileage.dailyMileageKm)} km`
    : '-';
  return [
    '【里程统计摘要】',
    `车辆范围：${keyword}`,
    `数据通道：${protocol}`,
    `日期范围：${dateRange}`,
    `统计车辆：${summary.vehicleCount.toLocaleString()}，记录：${summary.recordCount.toLocaleString()}，来源：${summary.sourceCount.toLocaleString()}`,
    `累计里程：${formatKm(summary.totalMileageKm)} km`,
    `单车平均：${formatKm(summary.averageMileagePerVin)} km`,
    `当前页里程：${formatKm(pageMileageTotal)} km`,
    `异常记录：${anomalyCount.toLocaleString()}`,
    `最大单日：${peak}`,
    '里程口径：区间总值等于各日里程之和',
    `里程统计：${statisticsURL}`,
    ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
  ].join('\n');
}

function mileageDeliveryPackageText({
  filters,
  summary,
  pageMileageTotal,
  pageCoverageRate,
  anomalyCount,
  closureStatus,
  closureDeltaKm,
  confidenceStatus,
  publishAuditConclusion,
  onlineSummary,
  peakMileage,
  statisticsURL,
  vehicleURL
}: {
  filters: Record<string, string>;
  summary: MileageSummary;
  pageMileageTotal: number;
  pageCoverageRate: number;
  anomalyCount: number;
  closureStatus: string;
  closureDeltaKm?: number;
  confidenceStatus: string;
  publishAuditConclusion: string;
  onlineSummary: OnlineStatisticsSummary;
  peakMileage?: DailyMileageRow;
  statisticsURL: string;
  vehicleURL?: string;
}) {
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  const dateFrom = filters.dateFrom?.trim();
  const dateTo = filters.dateTo?.trim();
  const dateRange = dateFrom || dateTo ? `${dateFrom || '-'} 至 ${dateTo || '-'}` : '全部日期';
  const peak = peakMileage
    ? `${peakMileage.plate || peakMileage.vin} / ${peakMileage.date} / ${formatKm(peakMileage.dailyMileageKm)} km`
    : '-';
  const deliveryState = publishAuditConclusion === '可发布' && confidenceStatus === '可用于 BI'
    ? '可交付'
    : publishAuditConclusion === '阻断发布' ? '暂缓交付' : '复核后交付';
  return [
    '【客户里程复核交付包】',
    `交付状态：${deliveryState}`,
    `车辆范围：${keyword}`,
    `数据通道：${protocol}`,
    `日期范围：${dateRange}`,
    `累计里程：${formatKm(summary.totalMileageKm)} km`,
    `当前页明细合计：${formatKm(pageMileageTotal)} km`,
    `闭合状态：${closureStatus}${closureDeltaKm == null ? '' : `，差值 ${formatKm(Math.abs(closureDeltaKm))} km`}`,
    `记录覆盖率：${formatPercent(pageCoverageRate)}`,
    `异常记录：${anomalyCount.toLocaleString()}`,
    `最大单日：${peak}`,
    `在线影响：${onlineSummary.onlineVehicleCount.toLocaleString()} 在线 / ${onlineSummary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(onlineSummary.onlineRatePercent)}`,
    `发布判断：${publishAuditConclusion}`,
    `可信度：${confidenceStatus}`,
    '里程口径：日里程按首末总里程差值计算，区间总值应等于每日里程之和',
    `里程统计：${statisticsURL}`,
    `轨迹复核：${appURL(buildAppHash({ page: 'history', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}) } }))}`,
    `历史明细：${appURL(buildAppHash({ page: 'history-query', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}), tab: 'raw', includeFields: 'true' } }))}`,
    ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
  ].join('\n');
}

function mileageCustomerDecisionText({
  filters,
  summary,
  pageMileageTotal,
  pageCoverageRate,
  anomalyCount,
  closureStatus,
  closureDeltaKm,
  confidenceStatus,
  publishAuditConclusion,
  onlineSummary,
  peakMileage,
  statisticsURL,
  vehicleURL
}: {
  filters: Record<string, string>;
  summary: MileageSummary;
  pageMileageTotal: number;
  pageCoverageRate: number;
  anomalyCount: number;
  closureStatus: string;
  closureDeltaKm?: number;
  confidenceStatus: string;
  publishAuditConclusion: string;
  onlineSummary: OnlineStatisticsSummary;
  peakMileage?: DailyMileageRow;
  statisticsURL: string;
  vehicleURL?: string;
}) {
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  const dateFrom = filters.dateFrom?.trim();
  const dateTo = filters.dateTo?.trim();
  const dateRange = dateFrom || dateTo ? `${dateFrom || '-'} 至 ${dateTo || '-'}` : '全部日期';
  const deliveryState = publishAuditConclusion === '可发布' && confidenceStatus === '可用于 BI'
    ? '可交付'
    : publishAuditConclusion === '阻断发布' ? '暂缓交付' : '复核后交付';
  const peak = peakMileage
    ? `${peakMileage.plate || peakMileage.vin} / ${peakMileage.date} / ${formatKm(peakMileage.dailyMileageKm)} km`
    : '-';
  return [
    '【客户里程决策说明】',
    `决策结论：${deliveryState}`,
    `车辆范围：${keyword}`,
    `数据通道：${protocol}`,
    `时间范围：${dateRange}`,
    `区间总里程：${formatKm(summary.totalMileageKm)} km`,
    `当前明细合计：${formatKm(pageMileageTotal)} km`,
    `区间闭合：${closureStatus}${closureDeltaKm == null ? '，当前为分页抽样' : `，差值 ${formatKm(Math.abs(closureDeltaKm))} km`}`,
    `记录覆盖：${formatPercent(pageCoverageRate)}`,
    `异常记录：${anomalyCount.toLocaleString()} 条`,
    `最高单日：${peak}`,
    `在线影响：${onlineSummary.onlineVehicleCount.toLocaleString()} 在线 / ${onlineSummary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(onlineSummary.onlineRatePercent)}`,
    `BI发布判断：${publishAuditConclusion}`,
    '',
    '客户判断路径：',
    '1. 先看区间闭合：区间总值必须等于每日里程之和。',
    '2. 再看记录覆盖：发布前需要覆盖全量明细或导出全量。',
    '3. 再看异常记录：异常日必须回看轨迹和历史明细。',
    '4. 最后看在线影响：离线车辆会影响当天里程解释。',
    `里程统计：${statisticsURL}`,
    `轨迹复核：${appURL(buildAppHash({ page: 'history', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}) } }))}`,
    `历史明细：${appURL(buildAppHash({ page: 'history-query', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}), tab: 'raw', includeFields: 'true' } }))}`,
    ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
  ].join('\n');
}

function mileageReconciliationControlText({
  filters,
  summary,
  pageMileageTotal,
  closureStatus,
  closureDeltaKm,
  anomalyCount,
  pageCoverageRate,
  onlineSummary,
  peakMileage,
  statisticsURL,
  vehicleURL
}: {
  filters: Record<string, string>;
  summary: MileageSummary;
  pageMileageTotal: number;
  closureStatus: string;
  closureDeltaKm?: number;
  anomalyCount: number;
  pageCoverageRate: number;
  onlineSummary: OnlineStatisticsSummary;
  peakMileage?: DailyMileageRow;
  statisticsURL: string;
  vehicleURL?: string;
}) {
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  const dateFrom = filters.dateFrom?.trim();
  const dateTo = filters.dateTo?.trim();
  const dateRange = dateFrom || dateTo ? `${dateFrom || '-'} 至 ${dateTo || '-'}` : '全部日期';
  const peak = peakMileage
    ? `${peakMileage.plate || peakMileage.vin} / ${peakMileage.date} / ${formatKm(peakMileage.dailyMileageKm)} km`
    : '-';
  return [
    '【客户里程对账总控包】',
    `服务链路：区间里程 -> 每日闭合 -> 轨迹证明 -> 报表导出`,
    `对账范围：${keyword} / ${protocol} / ${dateRange}`,
    `区间里程：${formatKm(summary.totalMileageKm)} km`,
    `明细合计：${formatKm(pageMileageTotal)} km`,
    `闭合状态：${closureStatus}${closureDeltaKm == null ? '' : `，差值 ${formatKm(Math.abs(closureDeltaKm))} km`}`,
    `异常记录：${anomalyCount.toLocaleString()} 条`,
    `覆盖率：${formatPercent(pageCoverageRate)}`,
    `在线影响：${onlineSummary.onlineVehicleCount.toLocaleString()} 在线 / ${onlineSummary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(onlineSummary.onlineRatePercent)}`,
    `轨迹证明：${peak}`,
    `里程统计：${statisticsURL}`,
    `报表导出：${statisticsURL}`,
    `轨迹回放：${appURL(buildAppHash({ page: 'history', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}) } }))}`,
    `历史明细：${appURL(buildAppHash({ page: 'history-query', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}), tab: 'raw', includeFields: 'true' } }))}`,
    ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
  ].join('\n');
}

function mileageBIPublishText({
  filters,
  summary,
  pageMileageTotal,
  pageCoverageRate,
  anomalyCount,
  closureStatus,
  closureDeltaKm,
  confidenceStatus,
  sourceConsistencyText,
  statisticsURL,
  vehicleURL
}: {
  filters: Record<string, string>;
  summary: MileageSummary;
  pageMileageTotal: number;
  pageCoverageRate: number;
  anomalyCount: number;
  closureStatus: string;
  closureDeltaKm?: number;
  confidenceStatus: string;
  sourceConsistencyText: string;
  statisticsURL: string;
  vehicleURL?: string;
}) {
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  const dateFrom = filters.dateFrom?.trim();
  const dateTo = filters.dateTo?.trim();
  const dateRange = dateFrom || dateTo ? `${dateFrom || '-'} 至 ${dateTo || '-'}` : '全部日期';
  const publishable = confidenceStatus === '可用于 BI' && closureStatus === '闭合通过';
  return [
    '【BI里程发布口径】',
    `发布结论：${publishable ? '可发布' : '需复核后发布'}`,
    `车辆范围：${keyword}`,
    `数据通道：${protocol}`,
    `日期范围：${dateRange}`,
    `里程口径：日里程按首末总里程差值计算，区间总值等于每日里程之和`,
    `累计里程：${formatKm(summary.totalMileageKm)} km`,
    `明细合计：${formatKm(pageMileageTotal)} km`,
    `闭合状态：${closureStatus}${closureDeltaKm == null ? '' : `，差值 ${formatKm(Math.abs(closureDeltaKm))} km`}`,
    `记录覆盖率：${formatPercent(pageCoverageRate)}`,
    `异常记录：${anomalyCount.toLocaleString()}`,
    `通道一致性：${sourceConsistencyText}`,
    `统计车辆：${summary.vehicleCount.toLocaleString()}，记录：${summary.recordCount.toLocaleString()}，来源：${summary.sourceCount.toLocaleString()}`,
    `发布风险：${publishable ? '当前筛选范围闭合且无异常记录' : '存在分页未全量、异常记录或闭合差值，需要先复核轨迹和历史明细'}`,
    `里程统计：${statisticsURL}`,
    ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
  ].join('\n');
}

function statisticsImpactText({
  filters,
  summary,
  onlineSummary,
  closureStatus,
  confidenceStatus,
  anomalyCount,
  pageCoverageRate,
  publishAuditConclusion,
  statisticsURL,
  vehicleURL
}: {
  filters: Record<string, string>;
  summary: MileageSummary;
  onlineSummary: OnlineStatisticsSummary;
  closureStatus: string;
  confidenceStatus: string;
  anomalyCount: number;
  pageCoverageRate: number;
  publishAuditConclusion: string;
  statisticsURL: string;
  vehicleURL?: string;
}) {
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  const dateFrom = filters.dateFrom?.trim();
  const dateTo = filters.dateTo?.trim();
  const dateRange = dateFrom || dateTo ? `${dateFrom || '-'} 至 ${dateTo || '-'}` : '全部日期';
  return [
    '【统计影响范围】',
    `车辆范围：${keyword}`,
    `数据通道：${protocol}`,
    `日期范围：${dateRange}`,
    `影响车辆：${summary.vehicleCount.toLocaleString()} 辆`,
    `统计记录：${summary.recordCount.toLocaleString()} 条`,
    `累计里程：${formatKm(summary.totalMileageKm)} km`,
    `在线状态：${onlineSummary.onlineVehicleCount.toLocaleString()} 在线 / ${onlineSummary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(onlineSummary.onlineRatePercent)}`,
    `闭合状态：${closureStatus}`,
    `发布判断：${publishAuditConclusion}`,
    `可信度：${confidenceStatus}`,
    `异常记录：${anomalyCount.toLocaleString()}`,
    `当前页覆盖：${formatPercent(pageCoverageRate)}`,
    `业务影响：${publishAuditConclusion === '可发布' ? '当前统计范围可进入运营和BI口径' : '当前统计范围需要先复核轨迹、历史明细和离线车辆影响'}`,
    `里程统计：${statisticsURL}`,
    ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
  ].join('\n');
}

type MileagePublishAuditItem = {
  key: string;
  label: string;
  status: 'pass' | 'review' | 'blocked';
  value: string;
  detail: string;
  action: string;
};

function auditStatusColor(status: MileagePublishAuditItem['status']): 'green' | 'orange' | 'red' {
  if (status === 'pass') return 'green';
  if (status === 'blocked') return 'red';
  return 'orange';
}

function auditStatusLabel(status: MileagePublishAuditItem['status']) {
  if (status === 'pass') return '通过';
  if (status === 'blocked') return '阻断';
  return '复核';
}

function mileagePublishAuditReport({
  filters,
  items,
  summary,
  statisticsURL,
  vehicleURL
}: {
  filters: Record<string, string>;
  items: MileagePublishAuditItem[];
  summary: MileageSummary;
  statisticsURL: string;
  vehicleURL?: string;
}) {
  const blocked = items.filter((item) => item.status === 'blocked').length;
  const review = items.filter((item) => item.status === 'review').length;
  const pass = items.filter((item) => item.status === 'pass').length;
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  return [
    '【统计发布审计】',
    `发布结论：${blocked > 0 ? '阻断发布' : review > 0 ? '复核后发布' : '可发布'}`,
    `车辆范围：${keyword}`,
    `数据通道：${protocol}`,
    `统计规模：${summary.vehicleCount.toLocaleString()} 车 / ${summary.recordCount.toLocaleString()} 条 / ${summary.sourceCount.toLocaleString()} 数据通道`,
    `审计结果：通过 ${pass.toLocaleString()} / 复核 ${review.toLocaleString()} / 阻断 ${blocked.toLocaleString()}`,
    '',
    ...items.map((item, index) => [
      `${index + 1}. [${auditStatusLabel(item.status)}] ${item.label}：${item.value}`,
      `   说明：${item.detail}`,
      `   动作：${item.action}`
    ].join('\n')),
    '',
    `里程统计：${statisticsURL}`,
    ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
  ].join('\n');
}

function mileageEvidencePackageText(row: DailyMileageRow) {
  const dateFrom = row.date?.trim() ?? '';
  const dateTo = nextDate(dateFrom);
  const evidenceFilters = {
    ...(dateFrom ? { dateFrom } : {}),
    ...(dateTo ? { dateTo } : {})
  };
  const vehicle = row.plate?.trim() ? `${row.plate.trim()} / ${row.vin}` : row.vin;
  return [
    '【里程异常复核包】',
    `车辆：${vehicle}`,
    `数据通道：${row.source || '未知通道'}`,
    `统计日期：${row.date || '-'}`,
    `起始里程：${formatKm(row.startMileageKm)} km`,
    `结束里程：${formatKm(row.endMileageKm)} km`,
    `日里程：${formatKm(row.dailyMileageKm)} km`,
    `异常等级：${row.anomalySeverity || '正常'}`,
    `处置建议：${mileageActionRecommendation(row).detail}`,
    `车辆服务：${appURL(buildAppHash({ page: 'detail', keyword: row.vin, protocol: row.source }))}`,
    `轨迹证据：${appURL(buildAppHash({ page: 'history', keyword: row.vin, protocol: row.source, filters: evidenceFilters }))}`,
    `历史明细：${appURL(buildAppHash({ page: 'history-query', keyword: row.vin, protocol: row.source, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
    `里程统计：${appURL(buildAppHash({ page: 'mileage', keyword: row.vin, protocol: row.source, filters: evidenceFilters }))}`
  ].join('\n');
}

function onlineStatusHandoffText({
  filters,
  summary,
  rows,
  total
}: {
  filters: Record<string, string>;
  summary: OnlineStatisticsSummary;
  rows: OnlineVehicleStatusRow[];
  total: number;
}) {
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  const handoffRows = Array.isArray(rows) ? rows : [];
  const offlineRows = handoffRows.filter((row) => !row.online);
  const protocolStats = Array.isArray(summary.protocolStats) ? summary.protocolStats : [];
  const protocolLines = protocolStats.length > 0
    ? protocolStats.map((item) => `${item.protocol} ${item.online.toLocaleString()}/${item.total.toLocaleString()}`).join('；')
    : '-';
  return [
    '【车辆在线状态说明】',
    `车辆范围：${keyword}`,
    `数据通道：${protocol}`,
    `在线概览：${summary.onlineVehicleCount.toLocaleString()} 在线 / ${summary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(summary.onlineRatePercent)}`,
    `Redis 在线 Key：${summary.redisOnlineKeys == null ? '-' : summary.redisOnlineKeys.toLocaleString()}`,
    `来源在线：${protocolLines}`,
    `统计证据：${summary.evidence || '-'}`,
    `当前页离线：${offlineRows.length.toLocaleString()} 辆 / 当前筛选 ${total.toLocaleString()} 辆`,
    '',
    '离线车辆：',
    ...(offlineRows.length > 0 ? offlineRows.map((row, index) => [
      `${index + 1}. ${row.plate || '-'} / ${row.vin || '-'} / ${row.oem || '-'}`,
      `   离线时长：${formatOfflineDuration(row.offlineDurationMinutes)}；最后上报：${row.lastSeen || '-'}`,
      `   来源覆盖：${row.onlineSourceCount}/${row.sourceCount}；来源：${(row.protocols ?? []).join('、') || '-'}`,
      `   车辆服务：${appURL(buildAppHash({ page: 'detail', keyword: row.vin, protocol: filters.protocol?.trim() || row.protocols?.[0] || '' }))}`,
      `   实时监控：${appURL(buildAppHash({ page: 'realtime', keyword: row.vin, protocol: filters.protocol?.trim() || row.protocols?.[0] || '' }))}`
    ].join('\n')) : ['当前页暂无离线车辆'])
  ].join('\n');
}

function onlineOperationsReportText({
  filters,
  summary,
  onlineRows,
  total,
  statisticsURL,
  vehicleURL
}: {
  filters: Record<string, string>;
  summary: OnlineStatisticsSummary;
  onlineRows: OnlineVehicleStatusRow[];
  total: number;
  statisticsURL: string;
  vehicleURL?: string;
}) {
  const keyword = filters.keyword?.trim() || '全部车辆';
  const protocol = filters.protocol?.trim() || '全部数据通道';
  const protocolStats = Array.isArray(summary.protocolStats) ? summary.protocolStats : [];
  const offlineRows = onlineRows.filter((row) => !row.online);
  const longestOffline = offlineRows.reduce<OnlineVehicleStatusRow | undefined>((current, row) => {
    if (!current) return row;
    return Number(row.offlineDurationMinutes ?? 0) > Number(current.offlineDurationMinutes ?? 0) ? row : current;
  }, undefined);
  return [
    '【在线影响评估】',
    `车辆范围：${keyword}`,
    `数据通道：${protocol}`,
    `在线概览：${summary.onlineVehicleCount.toLocaleString()} 在线 / ${summary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(summary.onlineRatePercent)}`,
    `Redis 在线 Key：${summary.redisOnlineKeys == null ? '-' : summary.redisOnlineKeys.toLocaleString()}`,
    `统计证据：${summary.evidence || '-'}`,
    `当前页车辆：${onlineRows.length.toLocaleString()} / 当前筛选 ${total.toLocaleString()}`,
    `当前页离线：${offlineRows.length.toLocaleString()}`,
    `最长离线：${longestOffline ? `${longestOffline.plate || longestOffline.vin} / ${formatOfflineDuration(longestOffline.offlineDurationMinutes)} / ${longestOffline.lastSeen || '-'}` : '-'}`,
    '',
    '来源在线：',
    ...(protocolStats.length > 0 ? protocolStats.map((item, index) => {
      const rate = item.total > 0 ? (item.online / item.total) * 100 : 0;
      return `${index + 1}. ${item.protocol}：${item.online.toLocaleString()}/${item.total.toLocaleString()}，在线率 ${formatPercent(rate)}`;
    }) : ['暂无来源在线统计']),
    '',
    '处置建议：',
    '1. 在线率下降时先检查实时在线状态、数据接入和最后上报时间',
    '2. 离线车辆优先打开车辆服务，核对实时、轨迹、历史明细和告警记录',
    '3. 统计发布前确认离线车辆是否影响当日里程和区间闭合',
    `里程统计：${statisticsURL}`,
    ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
  ].join('\n');
}

async function copyText(value: string, label: string) {
  const text = value.trim();
  if (!text) {
    Toast.warning(`${label}为空`);
    return;
  }
  try {
    await navigator.clipboard.writeText(text);
    Toast.success(`已复制${label}`);
  } catch {
    Toast.error(`复制${label}失败`);
  }
}

export function Mileage({
  initialVin,
  initialProtocol,
  initialFilters = {},
  onFiltersChange,
  onOpenVehicle,
  onOpenHistory,
  onOpenRaw
}: {
  initialVin: string;
  initialProtocol?: string;
  initialFilters?: Record<string, string>;
  onFiltersChange?: (filters: Record<string, string>) => void;
  onOpenVehicle: (vin: string, protocol?: string) => void;
  onOpenHistory?: (filters: Record<string, string>) => void;
  onOpenRaw?: (filters: Record<string, string>) => void;
}) {
  const [rows, setRows] = useState<DailyMileageRow[]>([]);
  const [onlineRows, setOnlineRows] = useState<OnlineVehicleStatusRow[]>([]);
  const [summary, setSummary] = useState<MileageSummary>(emptySummary);
  const [onlineSummary, setOnlineSummary] = useState<OnlineStatisticsSummary>(emptyOnlineSummary);
  const [loading, setLoading] = useState(true);
  const [onlineLoading, setOnlineLoading] = useState(true);
  const [summaryLoading, setSummaryLoading] = useState(true);
  const [filters, setFilters] = useState<Record<string, string>>(mergeInitialFilters(initialVin, initialProtocol, initialFilters));
  const [pagination, setPagination] = useState({ currentPage: 1, pageSize: 20, total: 0 });
  const [onlinePagination, setOnlinePagination] = useState({ currentPage: 1, pageSize: 10, total: 0 });
  const currentVehicleKeyword = filters.keyword?.trim() ?? '';
  const currentProtocol = filters.protocol?.trim() ?? '';
  const dateSeries = groupMileageByDate(rows);
  const sourceSeries = groupMileageBySource(rows);
  const anomalyRows = rows.filter((row) => row.anomalySeverity);
  const peakMileage = maxMileageRow(rows);
  const pageMileageTotal = rows.reduce((total, row) => total + row.dailyMileageKm, 0);
  const anomalyRate = rows.length > 0 ? (anomalyRows.length / rows.length) * 100 : 0;
  const peakMileageShare = pageMileageTotal > 0 && peakMileage ? (peakMileage.dailyMileageKm / pageMileageTotal) * 100 : 0;
  const pageCoverageRate = summary.recordCount > 0 ? (rows.length / summary.recordCount) * 100 : 0;
  const hasFullMileagePage = summary.recordCount > 0 && rows.length === summary.recordCount;
  const closureDeltaKm = hasFullMileagePage ? summary.totalMileageKm - pageMileageTotal : undefined;
  const closurePassed = closureDeltaKm != null && Math.abs(closureDeltaKm) < 0.01;
  const closureStatus = closureDeltaKm == null ? '分页抽样' : closurePassed ? '闭合通过' : '闭合异常';
  const closureStatusColor = closurePassed ? 'green' as const : closureDeltaKm == null ? 'grey' as const : 'orange' as const;
  const closureActionText = closureDeltaKm == null
    ? '当前页未覆盖全量记录，请翻页、导出或缩小筛选范围后核验。'
    : closurePassed
      ? '当前筛选范围汇总总里程与明细合计一致，可作为统计证据。'
      : '汇总总里程与明细合计不一致，请核对分页、来源和异常记录。';
  const confidenceStatus = anomalyRows.length > 0 || pageCoverageRate < 100 ? '需复核' : '可用于 BI';
  const confidenceColor = confidenceStatus === '可用于 BI' ? 'green' as const : 'orange' as const;
  const currentEvidenceText = `${summary.vehicleCount.toLocaleString()} 车 / ${summary.sourceCount.toLocaleString()} 数据通道 / ${rows.length.toLocaleString()} 条明细`;
  const sourceConsistencyText = summary.sourceCount > 1 ? '可做跨通道核对' : summary.sourceCount === 1 ? '单通道车辆需关注' : '等待数据通道';
  const onlineVehicleCount = Number(onlineSummary.onlineVehicleCount ?? 0);
  const offlineVehicleCount = Number(onlineSummary.offlineVehicleCount ?? 0);
  const onlineRatePercent = Number(onlineSummary.onlineRatePercent ?? 0);
  const redisOnlineKeyText = onlineSummary.redisOnlineKeys == null ? '' : `Redis 在线 ${onlineSummary.redisOnlineKeys.toLocaleString()} key`;
  const onlineStatsDetail = [
    `在线 ${onlineVehicleCount.toLocaleString()} 车`,
    `离线 ${offlineVehicleCount.toLocaleString()} 车`,
    redisOnlineKeyText,
    onlineSummary.evidence
  ].filter(Boolean).join('，');
  const onlineProtocolStats = Array.isArray(onlineSummary.protocolStats) ? onlineSummary.protocolStats : [];
  const topOfflineRow = onlineRows.filter((row) => !row.online).reduce<OnlineVehicleStatusRow | undefined>((current, row) => {
    if (!current) return row;
    return Number(row.offlineDurationMinutes ?? 0) > Number(current.offlineDurationMinutes ?? 0) ? row : current;
  }, undefined);
  const publishAuditItems: MileagePublishAuditItem[] = [
    {
      key: 'closure',
      label: '区间闭合',
      status: closureDeltaKm == null ? 'review' : closurePassed ? 'pass' : 'blocked',
      value: closureStatus,
      detail: closureDeltaKm == null ? '当前分页未覆盖全量记录，无法直接证明区间总值等于每日之和。' : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
      action: closurePassed ? '保留当前统计证据，可继续审计异常和来源。' : '缩小筛选范围、翻页或导出后重新核验闭合。'
    },
    {
      key: 'coverage',
      label: '记录覆盖',
      status: pageCoverageRate >= 100 ? 'pass' : summary.recordCount > rows.length ? 'review' : 'pass',
      value: formatPercent(pageCoverageRate),
      detail: `${rows.length.toLocaleString()} / ${summary.recordCount.toLocaleString()} 条明细在当前页。`,
      action: pageCoverageRate >= 100 ? '当前明细已覆盖统计范围。' : '发布前需要导出或拉齐全量明细。'
    },
    {
      key: 'anomaly',
      label: '异常记录',
      status: anomalyRows.length > 0 ? 'review' : 'pass',
      value: anomalyRows.length.toLocaleString(),
      detail: anomalyRows.length > 0 ? '存在日里程异常标记，需核对首末总里程、补传和断链。' : '当前筛选范围未发现异常里程记录。',
      action: anomalyRows.length > 0 ? '优先打开异常行的轨迹和历史明细复核。' : '继续检查通道一致性和在线状态。'
    },
    {
      key: 'source',
      label: '通道一致性',
      status: summary.sourceCount > 1 ? 'pass' : summary.sourceCount === 1 ? 'review' : 'blocked',
      value: sourceConsistencyText,
      detail: summary.sourceCount > 1 ? '可使用多通道交叉验证车辆统计。' : summary.sourceCount === 1 ? '只有单一通道，统计可用但可信度低于多通道。' : '当前统计缺少数据通道。',
      action: summary.sourceCount > 1 ? '保留通道贡献作为审计附件。' : '核对 32960、808、MQTT 是否有缺失通道。'
    },
    {
      key: 'online',
      label: '在线证据',
      status: onlineVehicleCount > 0 ? 'pass' : offlineVehicleCount > 0 ? 'review' : 'review',
      value: `${onlineVehicleCount.toLocaleString()} 在线 / ${offlineVehicleCount.toLocaleString()} 离线`,
      detail: onlineStatsDetail || '等待在线统计证据。',
      action: onlineVehicleCount > 0 ? '实时在线证据可辅助统计发布。' : '统计发布前建议检查离线时长和平台转发状态。'
    }
  ];
  const publishBlockedCount = publishAuditItems.filter((item) => item.status === 'blocked').length;
  const publishReviewCount = publishAuditItems.filter((item) => item.status === 'review').length;
  const publishAuditConclusion = publishBlockedCount > 0 ? '阻断发布' : publishReviewCount > 0 ? '复核后发布' : '可发布';
  const publishAuditColor = publishBlockedCount > 0 ? 'red' as const : publishReviewCount > 0 ? 'orange' as const : 'green' as const;
  const statisticsImpactColor = publishAuditColor;
  const statisticsImpactLevel = publishAuditConclusion === '可发布' ? '可交付报表' : publishAuditConclusion === '阻断发布' ? '发布阻断' : '影响待复核';
  const mileageDeliveryState = publishAuditConclusion === '可发布' && confidenceStatus === '可用于 BI'
    ? '可交付'
    : publishAuditConclusion === '阻断发布' ? '暂缓交付' : '复核后交付';
  const mileageDeliveryColor = mileageDeliveryState === '可交付' ? 'green' as const : mileageDeliveryState === '暂缓交付' ? 'red' as const : 'orange' as const;
  const statisticsImpactItems = [
    {
      label: '影响车辆',
      value: `${summary.vehicleCount.toLocaleString()} 辆`,
      detail: `${onlineVehicleCount.toLocaleString()} 在线 / ${offlineVehicleCount.toLocaleString()} 离线`,
      color: offlineVehicleCount > 0 ? 'orange' as const : 'green' as const
    },
    {
      label: '统计规模',
      value: `${summary.recordCount.toLocaleString()} 条`,
      detail: `${summary.sourceCount.toLocaleString()} 个来源，累计 ${formatKm(summary.totalMileageKm)} km`,
      color: summary.recordCount > 0 ? 'blue' as const : 'grey' as const
    },
    {
      label: '闭合影响',
      value: closureStatus,
      detail: closureActionText,
      color: closureStatusColor
    },
    {
      label: '异常影响',
      value: `${anomalyRows.length.toLocaleString()} 条`,
      detail: anomalyRows.length > 0 ? '异常会影响客户报表和 BI 口径，需要回到证据复核。' : '当前明细未命中异常标记。',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const
    },
    {
      label: '发布判断',
      value: publishAuditConclusion,
      detail: publishAuditConclusion === '可发布' ? '统计范围闭合且审计项通过。' : '发布前需要补齐审计项证据。',
      color: publishAuditColor
    }
  ];
  const mileageDecisionItems = [
    {
      label: '交付结论',
      value: mileageDeliveryState,
      detail: mileageDeliveryState === '可交付' ? '可进入客户查询、BI发布和报表交付。' : mileageDeliveryState === '暂缓交付' ? '存在阻断项，先完成证据复核。' : '需补齐闭合、覆盖、异常或在线证据后交付。',
      color: mileageDeliveryColor,
      action: '复制决策',
      onClick: () => copyMileageDecision()
    },
    {
      label: '区间闭合',
      value: closureStatus,
      detail: closureDeltaKm == null ? '当前页是分页抽样，发布前请拉齐全量明细。' : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
      color: closureStatusColor,
      action: '统计摘要',
      onClick: () => copyStatisticsSummary()
    },
    {
      label: '覆盖率',
      value: formatPercent(pageCoverageRate),
      detail: `${rows.length.toLocaleString()} / ${summary.recordCount.toLocaleString()} 条记录，交付前建议覆盖全量。`,
      color: pageCoverageRate >= 100 ? 'green' as const : pageCoverageRate >= 60 ? 'orange' as const : 'red' as const,
      action: '导出明细',
      onClick: () => exportMileage()
    },
    {
      label: '异常复核',
      value: `${anomalyRows.length.toLocaleString()} 条`,
      detail: anomalyRows[0] ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date} 需要回看轨迹。` : '当前明细未命中异常标记。',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      action: '异常明细',
      onClick: () => anomalyRows[0] ? copyMileageEvidence(anomalyRows[0]) : copyMileageDecision()
    },
    {
      label: '在线影响',
      value: formatPercent(onlineRatePercent),
      detail: `${onlineVehicleCount.toLocaleString()} 在线 / ${offlineVehicleCount.toLocaleString()} 离线。`,
      color: onlineRatePercent >= 90 ? 'green' as const : onlineRatePercent >= 60 ? 'orange' as const : 'red' as const,
      action: '在线态势',
      onClick: () => copyOnlineOperationsReport()
    }
  ];
  const maxDateMileage = Math.max(...dateSeries.map((item) => item.value), 0);
  const maxSourceMileage = Math.max(...sourceSeries.map((item) => item.value), 0);
  const filterSummary = [
    currentVehicleKeyword ? `车辆：${currentVehicleKeyword}` : '',
    currentProtocol ? `数据通道：${currentProtocol}` : '',
    filters.dateFrom?.trim() ? `开始日期：${filters.dateFrom.trim()}` : '',
    filters.dateTo?.trim() ? `结束日期：${filters.dateTo.trim()}` : ''
  ].filter(Boolean);
  const mileageRangeText = filters.dateFrom?.trim() || filters.dateTo?.trim()
    ? `${filters.dateFrom?.trim() || '-'} 至 ${filters.dateTo?.trim() || '-'}`
    : '全部日期';
  const mileageCustomerKpis = [
    {
      label: '区间总里程',
      value: `${formatKm(summary.totalMileageKm)} km`,
      color: 'blue' as const,
      detail: `范围：${mileageRangeText}`
    },
    {
      label: '统计车辆',
      value: `${summary.vehicleCount.toLocaleString()} 辆`,
      color: summary.vehicleCount > 0 ? 'green' as const : 'grey' as const,
      detail: `${summary.recordCount.toLocaleString()} 条日里程记录`
    },
    {
      label: '异常记录',
      value: anomalyRows.length.toLocaleString(),
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      detail: anomalyRows.length > 0 ? '建议先核对轨迹和历史明细' : '当前页未发现异常'
    },
    {
      label: '在线影响',
      value: formatPercent(onlineRatePercent),
      color: onlineRatePercent >= 90 ? 'green' as const : onlineRatePercent >= 60 ? 'orange' as const : 'red' as const,
      detail: `${onlineVehicleCount.toLocaleString()} 在线 / ${offlineVehicleCount.toLocaleString()} 离线`
    }
  ];
  const mileageCustomerWorkbenchItems = [
    {
      label: '区间里程',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `${summary.vehicleCount.toLocaleString()} 辆车，${mileageRangeText}。`,
      color: 'blue' as const,
      action: '复制摘要',
      disabled: false,
      onClick: () => copyStatisticsSummary()
    },
    {
      label: '每日闭合',
      value: closureStatus,
      detail: closureDeltaKm == null ? `当前页覆盖 ${formatPercent(pageCoverageRate)}，发布前需要拉齐全量。` : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
      color: closureStatusColor,
      action: '发布审计',
      disabled: false,
      onClick: () => copyPublishAudit()
    },
    {
      label: '轨迹回放',
      value: peakMileage?.date || mileageRangeText,
      detail: peakMileage ? `${peakMileage.plate || peakMileage.vin} 最大单日 ${formatKm(peakMileage.dailyMileageKm)} km。` : '选择车辆后用同一时间窗回放轨迹。',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      action: '回放轨迹',
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => {
        if (peakMileage) {
          openMileageEvidence(peakMileage);
          return;
        }
        onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' });
      }
    },
    {
      label: '历史导出',
      value: `${rows.length.toLocaleString()} 条`,
      detail: `当前页覆盖 ${formatPercent(pageCoverageRate)}，用于客户对账和 BI 复核。`,
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      action: '导出明细',
      disabled: rows.length === 0,
      onClick: () => exportMileage()
    },
    {
      label: '告警通知',
      value: `${offlineVehicleCount.toLocaleString()} 离线`,
      detail: offlineVehicleCount > 0 ? '离线会影响定位、里程解释和客户通知。' : '当前在线状态未形成主要统计风险。',
      color: offlineVehicleCount > 0 ? 'orange' as const : 'green' as const,
      action: '在线态势',
      disabled: false,
      onClick: () => copyOnlineOperationsReport()
    }
  ];
  const mileageConclusionItems = [
    {
      label: '区间累计',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `${summary.vehicleCount.toLocaleString()} 辆车，${mileageRangeText}`,
      color: 'blue' as const,
      onClick: () => copyStatisticsSummary()
    },
    {
      label: '明细合计',
      displayLabel: '当前明细',
      value: `${formatKm(pageMileageTotal)} km`,
      detail: `${rows.length.toLocaleString()} 条当前页明细，覆盖 ${formatPercent(pageCoverageRate)}`,
      color: pageCoverageRate >= 100 ? 'green' as const : 'orange' as const,
      onClick: () => exportMileage()
    },
    {
      label: '异常记录',
      value: `${anomalyRows.length.toLocaleString()} 条`,
      detail: anomalyRows[0] ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date}` : '当前页未发现异常',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      onClick: () => anomalyRows[0] ? copyMileageEvidence(anomalyRows[0]) : copyMileageDecision()
    },
    {
      label: '在线影响',
      value: `${offlineVehicleCount.toLocaleString()} 离线`,
      detail: `${onlineVehicleCount.toLocaleString()} 在线，在线率 ${formatPercent(onlineRatePercent)}`,
      color: offlineVehicleCount > 0 ? 'orange' as const : 'green' as const,
      onClick: () => copyOnlineOperationsReport()
    }
  ];
  const mileageConclusionActions = [
    {
      label: '复制结论',
      action: '复制摘要',
      color: 'blue' as const,
      disabled: false,
      onClick: () => copyMileageDeliveryPackage()
    },
    {
      label: '轨迹复核',
      action: '轨迹回放',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })
    },
    {
      label: '导出明细',
      action: '导出CSV',
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      disabled: rows.length === 0,
      onClick: () => exportMileage()
    },
    {
      label: '告警通知',
      action: '在线态势',
      color: offlineVehicleCount > 0 ? 'orange' as const : 'green' as const,
      disabled: false,
      onClick: () => copyOnlineOperationsReport()
    }
  ];
  const mileageCustomerActions = [
    {
      label: '导出当前明细',
      disabled: rows.length === 0,
      action: () => exportMileage()
    },
    {
      label: '查看轨迹',
      disabled: !currentVehicleKeyword || !onOpenHistory,
      action: () => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })
    },
    {
      label: '查看历史明细',
      disabled: !currentVehicleKeyword || !onOpenRaw,
      action: () => onOpenRaw?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '', includeFields: 'true' })
    },
    {
      label: '车辆档案',
      disabled: !currentVehicleKeyword,
      action: () => onOpenVehicle(currentVehicleKeyword, currentProtocol)
    }
  ];
  const mileageCustomerQuerySteps = [
    {
      step: '01',
      title: '选择范围',
      value: currentVehicleKeyword || '全部车辆',
      detail: `时间范围 ${mileageRangeText}，数据通道 ${currentProtocol || '全部数据通道'}。`,
      action: '调整筛选',
      color: currentVehicleKeyword ? 'green' as const : 'blue' as const,
      disabled: false,
      onClick: () => {
        const input = document.querySelector<HTMLInputElement>('input[name="keyword"]');
        input?.focus();
      }
    },
    {
      step: '02',
      title: '区间里程',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `${summary.vehicleCount.toLocaleString()} 辆车，${summary.recordCount.toLocaleString()} 条日里程记录。`,
      action: '复制摘要',
      color: 'blue' as const,
      disabled: false,
      onClick: () => copyStatisticsSummary()
    },
    {
      step: '03',
      title: '发布判断',
      value: publishAuditConclusion,
      detail: `闭合 ${closureStatus}，覆盖 ${formatPercent(pageCoverageRate)}。`,
      action: '发布审计',
      color: publishAuditColor,
      disabled: false,
      onClick: () => copyPublishAudit()
    },
    {
      step: '04',
      title: '复核证据',
      value: anomalyRows.length > 0 ? `${anomalyRows.length.toLocaleString()} 异常` : '轨迹/原始',
      detail: anomalyRows.length > 0 ? '异常日优先回看轨迹和历史明细。' : '可从同一时间窗进入轨迹和历史明细。',
      action: '轨迹复核',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })
    },
    {
      step: '05',
      title: '明细导出',
      value: `${rows.length.toLocaleString()} 当前页`,
      detail: '导出明细并附带里程口径，支撑 BI 核对、客户复盘和报表交付。',
      action: '导出明细',
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      disabled: rows.length === 0,
      onClick: () => exportMileage()
    }
  ];
  const mileageReconciliationConclusionItems = [
    {
      label: '区间总里程',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `${summary.vehicleCount.toLocaleString()} 辆车，${mileageRangeText}。`,
      action: '复制摘要',
      color: 'blue' as const,
      disabled: false,
      onClick: () => copyStatisticsSummary()
    },
    {
      label: '闭合状态',
      value: closureStatus,
      detail: closureActionText,
      action: '发布审计',
      color: closureStatusColor,
      disabled: false,
      onClick: () => copyPublishAudit()
    },
    {
      label: '异常记录',
      value: `${anomalyRows.length.toLocaleString()} 条`,
      detail: anomalyRows[0]
        ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date}`
        : '当前明细没有异常标记。',
      action: '复制决策',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      disabled: false,
      onClick: () => copyMileageDecision()
    },
    {
      label: '下一步',
      value: mileageDeliveryState,
      detail: mileageDeliveryState === '可交付' ? '可以进入客户交付、BI复核或导出。' : '先补齐闭合、覆盖、异常或在线影响证据。',
      action: '查看证据',
      color: mileageDeliveryColor,
      disabled: !currentVehicleKeyword || (!onOpenHistory && !onOpenRaw),
      onClick: () => {
        if (currentVehicleKeyword && onOpenHistory) {
          onOpenHistory({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' });
          return;
        }
        if (currentVehicleKeyword && onOpenRaw) {
          onOpenRaw({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '', includeFields: 'true' });
          return;
        }
        copyMileageDeliveryPackage();
      }
    }
  ];
  const mileageDeliveryNavigation = [
    {
      title: '确认里程口径',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `范围 ${mileageRangeText}，闭合状态 ${closureStatus}，发布判断 ${publishAuditConclusion}。`,
      action: '复制统计摘要',
      color: publishAuditColor,
      disabled: false,
      onClick: () => copyStatisticsSummary()
    },
    {
      title: '回放里程轨迹',
      value: currentVehicleKeyword || '请选择车辆',
      detail: '用同一车辆和时间窗回看位置、速度、停驶和里程断点。',
      action: '轨迹复核',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })
    },
    {
      title: '导出明细证据',
      value: `${rows.length.toLocaleString()} 条当前页`,
      detail: `覆盖 ${formatPercent(pageCoverageRate)}，用于客户复盘、BI 核对和报表附件。`,
      action: '导出CSV',
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      disabled: rows.length === 0,
      onClick: () => exportMileage()
    },
    {
      title: '发送交付结论',
      value: mileageDeliveryState,
      detail: mileageDeliveryState === '可交付' ? '复制交付包后可直接发给客户或BI使用。' : '交付前需要补齐闭合、异常、覆盖或在线影响说明。',
      action: '复制交付包',
      color: mileageDeliveryColor,
      disabled: false,
      onClick: () => copyMileageDeliveryPackage()
    }
  ];
  const mileageAcceptanceItems = [
    {
      label: '范围确认',
      value: currentVehicleKeyword || '全部车辆',
      detail: `${mileageRangeText} / ${currentProtocol || '全部数据通道'}`,
      color: currentVehicleKeyword ? 'blue' as const : 'orange' as const,
      disabled: false,
      onClick: () => copyStatisticsSummary()
    },
    {
      label: '区间闭合',
      value: closureStatus,
      detail: closureDeltaKm == null ? '当前为分页抽样，交付前需要拉齐全量明细。' : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
      color: closureStatusColor,
      disabled: false,
      onClick: () => copyPublishAudit()
    },
    {
      label: '明细覆盖',
      value: formatPercent(pageCoverageRate),
      detail: `${rows.length.toLocaleString()} / ${summary.recordCount.toLocaleString()} 条记录，覆盖全量后再交付更稳。`,
      color: pageCoverageRate >= 100 ? 'green' as const : 'orange' as const,
      disabled: rows.length === 0,
      onClick: () => exportMileage()
    },
    {
      label: '异常复核',
      value: `${anomalyRows.length.toLocaleString()} 条`,
      detail: anomalyRows[0] ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date} 优先回放。` : '当前明细未发现异常日里程。',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      disabled: false,
      onClick: () => anomalyRows[0] ? openMileageEvidence(anomalyRows[0]) : copyMileageDecision()
    },
    {
      label: '在线影响',
      value: `${offlineVehicleCount.toLocaleString()} 离线`,
      detail: offlineVehicleCount > 0 ? '离线车辆会影响当日解释和客户通知。' : '在线状态未形成主要统计风险。',
      color: offlineVehicleCount > 0 ? 'orange' as const : 'green' as const,
      disabled: false,
      onClick: () => copyOnlineOperationsReport()
    }
  ];
  const mileageAcceptanceActions = [
    {
      label: '复制验收',
      action: '交付说明',
      color: mileageDeliveryColor,
      disabled: false,
      onClick: () => copyMileageDeliveryPackage()
    },
    {
      label: '复核轨迹',
      action: '轨迹',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })
    },
    {
      label: '导出明细',
      action: 'CSV',
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      disabled: rows.length === 0,
      onClick: () => exportMileage()
    }
  ];

  const loadSummary = (values: Record<string, string> = filters) => {
    setSummaryLoading(true);
    api.mileageSummary(mileageParams(values))
      .then((nextSummary) => setSummary(normalizeMileageSummary(nextSummary)))
      .catch((error: Error) => Toast.error(error.message))
      .finally(() => setSummaryLoading(false));
    api.onlineStatisticsSummary(mileageParams(values))
      .then((nextSummary) => setOnlineSummary({
        ...emptyOnlineSummary,
        ...(nextSummary ?? {}),
        protocolStats: Array.isArray(nextSummary?.protocolStats) ? nextSummary.protocolStats : []
      }))
      .catch((error: Error) => Toast.error(error.message));
  };

  const load = (values: Record<string, string> = filters, page = pagination.currentPage, pageSize = pagination.pageSize) => {
    setLoading(true);
    api.dailyMileage(mileageParams(values, pageSize, (page - 1) * pageSize))
      .then((nextPage) => {
        setRows(Array.isArray(nextPage.items) ? nextPage.items : []);
        setPagination({ currentPage: page, pageSize, total: nextPage.total });
      })
      .catch((error: Error) => Toast.error(error.message))
      .finally(() => setLoading(false));
  };

  const loadOnlineRows = (values: Record<string, string> = filters, page = onlinePagination.currentPage, pageSize = onlinePagination.pageSize) => {
    setOnlineLoading(true);
    api.onlineVehicleStatuses(mileageParams(values, pageSize, (page - 1) * pageSize))
      .then((nextPage) => {
        setOnlineRows(Array.isArray(nextPage.items) ? nextPage.items : []);
        setOnlinePagination({ currentPage: page, pageSize, total: nextPage.total });
      })
      .catch((error: Error) => Toast.error(error.message))
      .finally(() => setOnlineLoading(false));
  };

  const applyFilters = (nextFilters: Record<string, string>) => {
    setFilters(nextFilters);
    onFiltersChange?.(nextFilters);
    loadSummary(nextFilters);
    load(nextFilters, 1, pagination.pageSize);
    loadOnlineRows(nextFilters, 1, onlinePagination.pageSize);
  };

  const clearRangeFilters = () => {
    applyFilters(currentVehicleKeyword ? { keyword: currentVehicleKeyword } : {});
  };

  const openMileageEvidence = (row: DailyMileageRow) => {
    const dateFrom = row.date?.trim() ?? '';
    const dateTo = nextDate(dateFrom);
    onOpenHistory?.({
      keyword: row.vin,
      protocol: row.source,
      ...(dateFrom ? { dateFrom } : {}),
      ...(dateTo ? { dateTo } : {})
    });
  };
  const openMileageRawEvidence = (row: DailyMileageRow) => {
    const dateFrom = row.date?.trim() ?? '';
    const dateTo = nextDate(dateFrom);
    onOpenRaw?.({
      keyword: row.vin,
      protocol: row.source,
      ...(dateFrom ? { dateFrom } : {}),
      ...(dateTo ? { dateTo } : {})
    });
  };
  const copyMileageEvidence = (row: DailyMileageRow) => {
    copyText(mileageEvidencePackageText(row), '里程证据包');
  };
  const exportMileage = () => {
    if (rows.length === 0) {
      Toast.warning('当前没有可导出的里程明细');
      return;
    }
    downloadCsv(exportFileName(filters), buildCsv(mileageExportColumns, rows));
    Toast.success(`已导出 ${rows.length} 条里程明细`);
  };
  const copyStatisticsSummary = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    copyText(
      mileageSummaryText({
        filters,
        summary,
        pageMileageTotal,
        anomalyCount: anomalyRows.length,
        peakMileage,
        statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
        vehicleURL
      }),
      '统计摘要'
    );
  };
  const copyMileageDeliveryPackage = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    copyText(
      mileageDeliveryPackageText({
        filters,
        summary,
        pageMileageTotal,
        pageCoverageRate,
        anomalyCount: anomalyRows.length,
        closureStatus,
        closureDeltaKm,
        confidenceStatus,
        publishAuditConclusion,
        onlineSummary,
        peakMileage,
        statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
        vehicleURL
      }),
      '客户里程复核交付包'
    );
  };
  const copyMileageDecision = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    copyText(
      mileageCustomerDecisionText({
        filters,
        summary,
        pageMileageTotal,
        pageCoverageRate,
        anomalyCount: anomalyRows.length,
        closureStatus,
        closureDeltaKm,
        confidenceStatus,
        publishAuditConclusion,
        onlineSummary,
        peakMileage,
        statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
        vehicleURL
      }),
      '客户里程决策说明'
    );
  };
  const copyMileageReconciliationControl = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    copyText(
      mileageReconciliationControlText({
        filters,
        summary,
        pageMileageTotal,
        closureStatus,
        closureDeltaKm,
        anomalyCount: anomalyRows.length,
        pageCoverageRate,
        onlineSummary,
        peakMileage,
        statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
        vehicleURL
      }),
      '客户里程对账总控包'
    );
  };
  const copyBIPublishText = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    copyText(
      mileageBIPublishText({
        filters,
        summary,
        pageMileageTotal,
        pageCoverageRate,
        anomalyCount: anomalyRows.length,
        closureStatus,
        closureDeltaKm,
        confidenceStatus,
        sourceConsistencyText,
        statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
        vehicleURL
      }),
      'BI里程发布口径'
    );
  };
  const copyPublishAudit = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    copyText(
      mileagePublishAuditReport({
        filters,
        items: publishAuditItems,
        summary,
        statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
        vehicleURL
      }),
      '统计发布审计'
    );
  };
  const copyStatisticsImpact = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    copyText(
      statisticsImpactText({
        filters,
        summary,
        onlineSummary,
        closureStatus,
        confidenceStatus,
        anomalyCount: anomalyRows.length,
        pageCoverageRate,
        publishAuditConclusion,
        statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
        vehicleURL
      }),
      '统计影响范围'
    );
  };
  const copyOnlineStatusHandoff = () => {
    copyText(
      onlineStatusHandoffText({
        filters,
        summary: onlineSummary,
        rows: onlineRows,
        total: onlinePagination.total
      }),
      '在线状态说明'
    );
  };
  const copyOnlineOperationsReport = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    copyText(
      onlineOperationsReportText({
        filters,
        summary: onlineSummary,
        onlineRows,
        total: onlinePagination.total,
        statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
        vehicleURL
      }),
      '在线影响评估'
    );
  };
  const copyMileageReportJourneyPackage = () => {
    const vehicleURL = currentVehicleKeyword
      ? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
      : undefined;
    const reportPeriod = mileageRangeText;
    const trajectoryProof = peakMileage
      ? `${peakMileage.plate || peakMileage.vin} / ${peakMileage.date} / ${formatKm(peakMileage.dailyMileageKm)} km`
      : '暂无轨迹证明样本';
    copyText([
      '【里程报表交付旅程包】',
      `报表周期：${reportPeriod}`,
      `车辆范围：${currentVehicleKeyword || '全部车辆'}`,
      `数据通道：${currentProtocol || '全部数据通道'}`,
      `区间里程：${formatKm(summary.totalMileageKm)} km`,
      `区间闭合：${closureStatus}`,
      `记录覆盖：${formatPercent(pageCoverageRate)}`,
      `异常记录：${anomalyRows.length.toLocaleString()} 条`,
      `轨迹证明：${trajectoryProof}`,
      `导出发布：${mileageDeliveryState} / ${publishAuditConclusion}`,
      `在线影响：${onlineVehicleCount.toLocaleString()} 在线 / ${offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(onlineRatePercent)}`,
      `里程统计：${appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol }))}`,
      `轨迹回放：${appURL(buildAppHash({ page: 'history', keyword: currentVehicleKeyword, protocol: currentProtocol, filters: { ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) } }))}`,
      `历史明细：${appURL(buildAppHash({ page: 'history-query', keyword: currentVehicleKeyword, protocol: currentProtocol, filters: { ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}), tab: 'raw', includeFields: 'true' } }))}`,
      ...(vehicleURL ? [`车辆服务：${vehicleURL}`] : [])
    ].join('\n'), '里程报表交付旅程包');
  };
  const mileageReportJourneyItems = [
    {
      step: '1',
      title: '报表周期',
      value: mileageRangeText,
      detail: `${currentVehicleKeyword || '全部车辆'} / ${currentProtocol || '全部数据通道'}，先确认客户要看的车辆和时间段。`,
      color: currentVehicleKeyword ? 'blue' as const : 'orange' as const,
      disabled: false,
      onClick: copyStatisticsSummary
    },
    {
      step: '2',
      title: '区间闭合',
      value: closureStatus,
      detail: closureDeltaKm == null ? `当前明细覆盖 ${formatPercent(pageCoverageRate)}，发布前需要拉齐全量。` : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
      color: closureStatusColor,
      disabled: false,
      onClick: copyPublishAudit
    },
    {
      step: '3',
      title: '轨迹证明',
      value: peakMileage?.plate || peakMileage?.vin || '待选车辆',
      detail: peakMileage ? `${peakMileage.date} 最大单日 ${formatKm(peakMileage.dailyMileageKm)} km，建议回放轨迹证明。` : '选择车辆后可进入同一时间窗轨迹回放。',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => {
        if (peakMileage) {
          openMileageEvidence(peakMileage);
          return;
        }
        onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' });
      }
    },
    {
      step: '4',
      title: '导出发布',
      value: mileageDeliveryState,
      detail: `${publishAuditConclusion}，导出明细和交付包给客户或 BI 复核。`,
      color: mileageDeliveryColor,
      disabled: false,
      onClick: copyMileageReportJourneyPackage
    }
  ];
  const mileageDeliveryConsoleItems = [
    {
      label: '交付状态',
      value: mileageDeliveryState,
      detail: mileageDeliveryState === '可交付'
        ? '可进入客户查询、BI发布和报表交付。'
        : mileageDeliveryState === '暂缓交付'
          ? '存在阻断项，先完成闭合和异常复核。'
          : '复核闭合、覆盖、异常或在线影响后再交付。',
      color: mileageDeliveryColor,
      action: '复制交付',
      onClick: copyMileageDeliveryPackage
    },
    {
      label: '区间里程',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `范围 ${mileageRangeText}，统计车辆 ${summary.vehicleCount.toLocaleString()} 辆。`,
      color: 'blue' as const,
      action: '复制摘要',
      onClick: copyStatisticsSummary
    },
    {
      label: '闭合校验',
      value: closureStatus,
      detail: closureDeltaKm == null ? '当前页未覆盖全量记录，发布前需要导出或缩小范围。' : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
      color: closureStatusColor,
      action: '发布审计',
      onClick: copyPublishAudit
    },
    {
      label: '异常复核',
      value: `${anomalyRows.length.toLocaleString()} 条`,
      detail: anomalyRows[0] ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date} 需要复核。` : '当前明细没有异常标记。',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      action: '轨迹复核',
      onClick: () => {
        if (anomalyRows[0]) {
          openMileageEvidence(anomalyRows[0]);
          return;
        }
        onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' });
      }
    },
    {
      label: '数据导出',
      value: `${rows.length.toLocaleString()} 条明细`,
      detail: `当前页覆盖 ${formatPercent(pageCoverageRate)}，用于客户复盘和BI核对。`,
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      action: '导出明细',
      onClick: exportMileage
    }
  ];
  const mileageReconciliationControlItems = [
    {
      title: '区间里程',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `${summary.vehicleCount.toLocaleString()} 辆车，${mileageRangeText}。`,
      action: '复制摘要',
      color: 'blue' as const,
      disabled: false,
      onClick: copyStatisticsSummary
    },
    {
      title: '每日闭合',
      value: closureStatus,
      detail: closureDeltaKm == null ? `当前页覆盖 ${formatPercent(pageCoverageRate)}，交付前需要拉齐全量明细。` : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
      action: '闭合审计',
      color: closureStatusColor,
      disabled: false,
      onClick: copyPublishAudit
    },
    {
      title: '轨迹证明',
      value: peakMileage?.date || mileageRangeText,
      detail: peakMileage ? `${peakMileage.plate || peakMileage.vin} 最大单日 ${formatKm(peakMileage.dailyMileageKm)} km。` : '选择车辆后按同一时间窗回放轨迹。',
      action: '轨迹复核',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => {
        if (peakMileage) {
          openMileageEvidence(peakMileage);
          return;
        }
        onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' });
      }
    },
    {
      title: '报表导出',
      value: `${rows.length.toLocaleString()} 条`,
      detail: '导出当前里程明细和口径说明，作为客户对账附件。',
      action: '导出报表',
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      disabled: rows.length === 0,
      onClick: exportMileage
    }
  ];
  const mileageReconciliationItems = [
    {
      label: '区间里程',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `车辆 ${summary.vehicleCount.toLocaleString()} 辆，时间窗 ${mileageRangeText}。`,
      color: 'blue' as const,
      action: '复制摘要',
      onClick: copyStatisticsSummary
    },
    {
      label: '日报闭合',
      value: closureStatus,
      detail: closureDeltaKm == null ? `当前页覆盖 ${formatPercent(pageCoverageRate)}，交付前需要拉齐明细。` : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
      color: closureStatusColor,
      action: '闭合审计',
      onClick: copyPublishAudit
    },
    {
      label: '轨迹证据',
      value: peakMileage?.date || mileageRangeText,
      detail: peakMileage ? `${peakMileage.plate || peakMileage.vin} 最大单日 ${formatKm(peakMileage.dailyMileageKm)} km。` : '选择车辆后可按同一时间窗回放轨迹。',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      action: '轨迹回放',
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => {
        if (peakMileage) {
          openMileageEvidence(peakMileage);
          return;
        }
        onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' });
      }
    },
    {
      label: '告警通知',
      value: `${offlineVehicleCount.toLocaleString()} 离线`,
      detail: offlineVehicleCount > 0 ? '离线车辆会影响当日里程、定位和客户通知。' : '当前在线状态未形成主要统计风险。',
      color: offlineVehicleCount > 0 ? 'orange' as const : 'green' as const,
      action: '在线态势',
      onClick: copyOnlineOperationsReport
    },
    {
      label: '报表导出',
      value: `${rows.length.toLocaleString()} 条`,
      detail: '导出当前明细，作为客户对账、BI 核对和报表附件。',
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      action: '导出CSV',
      disabled: rows.length === 0,
      onClick: exportMileage
    }
  ];
  const mileageDefinitionMetrics = [
    {
      label: '区间总值',
      value: `${formatKm(summary.totalMileageKm)} km`,
      detail: `来自汇总口径，覆盖 ${summary.vehicleCount.toLocaleString()} 辆车。`,
      color: 'blue' as const,
      onClick: copyStatisticsSummary
    },
    {
      label: '明细合计',
      value: `${formatKm(pageMileageTotal)} km`,
      detail: `${rows.length.toLocaleString()} / ${summary.recordCount.toLocaleString()} 条明细，覆盖 ${formatPercent(pageCoverageRate)}。`,
      color: hasFullMileagePage ? 'green' as const : 'orange' as const,
      onClick: copyPublishAudit
    },
    {
      label: '闭合差值',
      value: closureDeltaKm == null ? '需全量' : `${formatKm(Math.abs(closureDeltaKm))} km`,
      detail: closureDeltaKm == null ? '当前为分页抽样，交付前需要拉齐全量明细。' : closureActionText,
      color: closureStatusColor,
      onClick: copyPublishAudit
    },
    {
      label: '异常记录',
      value: `${anomalyRows.length.toLocaleString()} 条`,
      detail: anomalyRows[0] ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date} 优先复核。` : '当前页没有异常日里程。',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      onClick: () => anomalyRows[0] ? copyMileageEvidence(anomalyRows[0]) : copyMileageDecision()
    }
  ];
  const mileageDefinitionActions = [
    {
      label: '复制口径',
      action: '决策说明',
      color: 'blue' as const,
      disabled: false,
      onClick: copyMileageDecision
    },
    {
      label: '复制交付',
      action: '交付包',
      color: mileageDeliveryColor,
      disabled: false,
      onClick: copyMileageDeliveryPackage
    },
    {
      label: '轨迹复核',
      action: '轨迹',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })
    },
    {
      label: '导出明细',
      action: 'CSV',
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      disabled: rows.length === 0,
      onClick: exportMileage
    }
  ];
  const mileageServiceTasks = [
    {
      title: '发布判断',
      value: publishAuditConclusion,
      detail: publishAuditConclusion === '可发布' ? '当前统计范围可进入客户报表或 BI 口径。' : '发布前需要补齐闭合、覆盖、异常或在线证据。',
      color: publishAuditColor,
      primaryAction: 'BI口径',
      secondaryAction: '发布审计',
      disabled: false,
      secondaryDisabled: false,
      onPrimary: copyBIPublishText,
      onSecondary: copyPublishAudit
    },
    {
      title: '区间复核',
      value: closureStatus,
      detail: `范围 ${mileageRangeText}，${closureActionText}`,
      color: closureStatusColor,
      primaryAction: '轨迹证据',
      secondaryAction: '历史明细',
      disabled: !currentVehicleKeyword || !onOpenHistory,
      secondaryDisabled: !currentVehicleKeyword || !onOpenRaw,
      onPrimary: () => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' }),
      onSecondary: () => onOpenRaw?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '', includeFields: 'true' })
    },
    {
      title: '异常处理',
      value: `${anomalyRows.length.toLocaleString()} 条异常`,
      detail: anomalyRows[0] ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date} 需要复核。` : '当前页未发现异常里程记录。',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      primaryAction: '复制证据',
      secondaryAction: '车辆档案',
      disabled: !anomalyRows[0],
      secondaryDisabled: !currentVehicleKeyword,
      onPrimary: () => anomalyRows[0] && copyMileageEvidence(anomalyRows[0]),
      onSecondary: () => currentVehicleKeyword && onOpenVehicle(currentVehicleKeyword, currentProtocol)
    },
    {
      title: '明细导出',
      value: `${rows.length.toLocaleString()} 条当前页`,
      detail: `累计 ${formatKm(summary.totalMileageKm)} km，当前页 ${formatKm(pageMileageTotal)} km。`,
      color: 'blue' as const,
      primaryAction: '导出明细',
      secondaryAction: '统计摘要',
      disabled: rows.length === 0,
      secondaryDisabled: false,
      onPrimary: exportMileage,
      onSecondary: copyStatisticsSummary
    }
  ];
  const mileageNextActions = [
    {
      title: publishAuditConclusion === '阻断发布' ? '先解除发布阻断' : publishAuditConclusion === '复核后发布' ? '先完成发布复核' : '可交付里程报告',
      value: publishAuditConclusion,
      detail: publishAuditConclusion === '可发布'
        ? '闭合、覆盖和异常检查通过后，可复制交付包或导出明细给客户。'
        : '先处理闭合、覆盖、异常和在线影响，再进入客户交付。',
      color: publishAuditColor,
      action: publishAuditConclusion === '可发布' ? '复制交付包' : '发布审计',
      disabled: false,
      onClick: publishAuditConclusion === '可发布' ? copyMileageDeliveryPackage : copyPublishAudit
    },
    {
      title: anomalyRows.length > 0 ? '优先复核异常日' : '按时间窗核对轨迹',
      value: anomalyRows.length > 0 ? `${anomalyRows.length.toLocaleString()} 条异常` : mileageRangeText,
      detail: anomalyRows[0]
        ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date} 建议先回放轨迹。`
        : '用同一个车辆和时间窗进入轨迹回放，核对位置、速度和里程变化。',
      color: anomalyRows.length > 0 ? 'orange' as const : 'blue' as const,
      action: '轨迹回放',
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => {
        if (anomalyRows[0]) {
          openMileageEvidence(anomalyRows[0]);
          return;
        }
        onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' });
      }
    },
    {
      title: pageCoverageRate >= 100 ? '明细覆盖完整' : '拉齐全量明细',
      value: formatPercent(pageCoverageRate),
      detail: pageCoverageRate >= 100
        ? '当前页已经覆盖筛选范围内全部明细，可直接导出复核。'
        : `${rows.length.toLocaleString()} / ${summary.recordCount.toLocaleString()} 条记录在当前页，导出前建议拉齐。`,
      color: pageCoverageRate >= 100 ? 'green' as const : 'orange' as const,
      action: '导出明细',
      disabled: rows.length === 0,
      onClick: exportMileage
    },
    {
      title: offlineVehicleCount > 0 ? '关注离线影响' : '在线状态正常',
      value: `${offlineVehicleCount.toLocaleString()} 离线`,
      detail: offlineVehicleCount > 0
        ? '离线车辆会影响实时位置、当日里程和告警触达，建议同步运营处理。'
        : '当前筛选范围内在线状态未形成主要统计风险。',
      color: offlineVehicleCount > 0 ? 'orange' as const : 'green' as const,
      action: '在线态势',
      disabled: false,
      onClick: copyOnlineOperationsReport
    }
  ];
  const mileageCustomerQuestions = [
    {
      question: '这段时间总共跑了多少？',
      answer: `${formatKm(summary.totalMileageKm)} km / ${summary.vehicleCount.toLocaleString()} 辆车`,
      action: '复制摘要',
      color: 'blue' as const,
      disabled: false,
      onClick: copyStatisticsSummary
    },
    {
      question: '这份里程能给客户或 BI 吗？',
      answer: `${mileageDeliveryState} / ${publishAuditConclusion}`,
      action: mileageDeliveryState === '可交付' ? '复制交付包' : '发布审计',
      color: mileageDeliveryColor,
      disabled: false,
      onClick: mileageDeliveryState === '可交付' ? copyMileageDeliveryPackage : copyPublishAudit
    },
    {
      question: '哪天或哪辆车有异常？',
      answer: anomalyRows[0] ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date}` : '当前明细无异常',
      action: anomalyRows[0] ? '异常证据' : '复制决策',
      color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
      disabled: false,
      onClick: () => anomalyRows[0] ? copyMileageEvidence(anomalyRows[0]) : copyMileageDecision()
    },
    {
      question: '这段路能回放轨迹吗？',
      answer: currentVehicleKeyword ? mileageRangeText : '请先选择车辆',
      action: '轨迹复核',
      color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
      disabled: !currentVehicleKeyword || !onOpenHistory,
      onClick: () => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })
    },
    {
      question: '明细数据能导出吗？',
      answer: `${rows.length.toLocaleString()} 条当前页 / 覆盖 ${formatPercent(pageCoverageRate)}`,
      action: '导出明细',
      color: rows.length > 0 ? 'blue' as const : 'grey' as const,
      disabled: rows.length === 0,
      onClick: exportMileage
    }
  ];

  useEffect(() => {
    const nextFilters = mergeInitialFilters(initialVin, initialProtocol, initialFilters);
    setFilters(nextFilters);
    loadSummary(nextFilters);
    load(nextFilters, 1, pagination.pageSize);
    loadOnlineRows(nextFilters, 1, onlinePagination.pageSize);
  }, [initialVin, initialProtocol, JSON.stringify(initialFilters)]);

  return (
    <div className="vp-page">
      <PageHeader
        title="里程统计"
        description="按车辆查询里程、在线影响、区间闭合、异常复核和数据交付"
        actions={(
          <Button disabled={!currentVehicleKeyword} onClick={() => onOpenVehicle(currentVehicleKeyword, currentProtocol)}>
            当前车辆服务
          </Button>
        )}
      />
      <section className="vp-mileage-conclusion-strip" aria-label="客户里程对账总控">
        <div className="vp-mileage-conclusion-copy">
          <Space wrap>
            <Tag color="blue">客户里程对账总控</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
            <Tag color={closureStatusColor}>{closureStatus}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>
            把区间里程、每日闭合、轨迹证明、异常通知和报表导出收敛成客户可验收的对账链路。
          </Typography.Title>
          <Typography.Text type="secondary">
            客户只需要知道这段时间跑了多少、是否闭合、哪里需要复核，以及能拿到哪份导出报表。
          </Typography.Text>
          <Space wrap>
            <Button size="small" theme="solid" type="primary" onClick={copyMileageReconciliationControl}>复制对账总控包</Button>
            <Button size="small" disabled={!currentVehicleKeyword || !onOpenHistory} onClick={() => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })}>轨迹复核</Button>
            <Button size="small" disabled={rows.length === 0} onClick={exportMileage}>导出报表</Button>
          </Space>
        </div>
        <div className="vp-mileage-conclusion-metrics">
          {mileageReconciliationControlItems.map((item) => (
            <button
              key={item.title}
              type="button"
              className="vp-mileage-conclusion-metric"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`客户里程对账总控 ${item.title} ${item.value} ${item.action}`}
            >
              <Tag color={item.color}>{item.title}</Tag>
              <strong>{item.value}</strong>
              <span>{item.detail}</span>
              <em>{item.action}</em>
            </button>
          ))}
        </div>
      </section>
      <section className="vp-mileage-report-journey" aria-label="里程报表交付旅程">
        <div className="vp-mileage-report-journey-copy">
          <Space wrap>
            <Tag color="blue">里程报表交付旅程</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
            <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>
            按客户报表习惯组织：先确认报表周期和车辆范围，再检查区间闭合、轨迹证明，最后导出或暂缓发布。
          </Typography.Title>
          <Typography.Text type="secondary">
            报表交付不再从协议解释开始，而是围绕车辆、时间、里程闭合和可导出证据完成客户复核。
          </Typography.Text>
          <Button size="small" theme="solid" type="primary" onClick={copyMileageReportJourneyPackage}>
            复制报表旅程包
          </Button>
        </div>
        <div className="vp-mileage-report-journey-steps">
          {mileageReportJourneyItems.map((item) => (
            <button
              key={item.step}
              type="button"
              className="vp-mileage-report-journey-step"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`里程报表交付旅程 ${item.step} ${item.title} ${item.value}`}
            >
              <Tag color={item.color}>{item.step}</Tag>
              <strong>{item.title}</strong>
              <span>{item.value}</span>
              <small>{item.detail}</small>
            </button>
          ))}
        </div>
      </section>
      <section className="vp-mileage-conclusion-strip" aria-label="客户里程结论条">
        <div className="vp-mileage-conclusion-copy">
          <Space wrap>
            <Tag color="blue">客户里程结论条</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
            <Tag color={closureStatusColor}>{closureStatus}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>
            先给客户一个可交付结论，再进入轨迹复核、明细导出和告警通知。
          </Typography.Title>
          <Typography.Text type="secondary">
            当前范围：{currentVehicleKeyword || '全部车辆'} / {mileageRangeText}，数据源只作为证据，不作为客户操作入口。
          </Typography.Text>
        </div>
        <div className="vp-mileage-conclusion-metrics">
          {mileageConclusionItems.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-conclusion-metric"
              onClick={item.onClick}
              aria-label={`客户里程结论 ${item.label} ${item.value}`}
            >
              <Tag color={item.color}>{item.displayLabel ?? item.label}</Tag>
              <strong>{item.value}</strong>
              <span>{item.detail}</span>
            </button>
          ))}
        </div>
        <div className="vp-mileage-conclusion-actions">
          {mileageConclusionActions.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-conclusion-action"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`客户里程动作 ${item.label} ${item.action}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <span>{item.action}</span>
            </button>
          ))}
        </div>
      </section>
      <section className="vp-mileage-definition-strip" aria-label="客户里程口径交付条">
        <div className="vp-mileage-definition-copy">
          <Space wrap>
            <Tag color="blue">客户里程口径交付条</Tag>
            <Tag color={closureStatusColor}>{closureStatus}</Tag>
            <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>
            日里程按当天首末总里程差值计算；区间总值必须等于每日里程之和，异常日进入轨迹和历史明细复核。
          </Typography.Title>
          <Typography.Text type="secondary">
            这是客户、BI 和运营三方共用口径：同一车辆、同一时间窗、同一统计证据，导出前先看闭合差值和异常记录。
          </Typography.Text>
        </div>
        <div className="vp-mileage-definition-metrics">
          {mileageDefinitionMetrics.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-definition-metric"
              onClick={item.onClick}
              aria-label={`客户里程口径交付 ${item.label} ${item.value}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <strong>{item.value}</strong>
              <span>{item.detail}</span>
            </button>
          ))}
        </div>
        <div className="vp-mileage-definition-actions">
          {mileageDefinitionActions.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-definition-action"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`客户里程口径动作 ${item.label} ${item.action}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <span>{item.action}</span>
            </button>
          ))}
        </div>
      </section>
      <section className="vp-mileage-customer-workbench" aria-label="客户里程统计工作台">
        <div className="vp-mileage-customer-workbench-main">
          <Space wrap>
            <Tag color="blue">客户里程统计工作台</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
            <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>
            统计页先回答客户这段时间跑了多少、每日是否闭合、异常在哪里、能否导出。
          </Typography.Title>
          <div className="vp-mileage-customer-workbench-meta">
            <span>车辆范围：{currentVehicleKeyword || '全部车辆'}</span>
            <span>时间范围：{mileageRangeText}</span>
            <span>来源证据只用于统计可信度：{currentProtocol || '全部数据通道'}</span>
          </div>
        </div>
        <div className="vp-mileage-customer-workbench-grid">
          {mileageCustomerWorkbenchItems.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-customer-workbench-item"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`客户里程统计工作台 ${item.label} ${item.value} ${item.action}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <strong>{item.value}</strong>
              <span>{item.detail}</span>
              <em>{item.action}</em>
            </button>
          ))}
        </div>
      </section>
      <section className="vp-mileage-reconciliation-conclusion" aria-label="里程对账结论">
        <div className="vp-mileage-reconciliation-conclusion-summary">
          <Space wrap>
            <Tag color="blue">里程对账结论</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>
            先回答客户这段时间跑了多少、闭合是否通过、异常是否需要复核，再进入轨迹、历史和导出。
          </Typography.Title>
        </div>
        <div className="vp-mileage-reconciliation-conclusion-grid">
          {mileageReconciliationConclusionItems.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-reconciliation-conclusion-item"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`里程对账结论 ${item.label} ${item.value} ${item.action}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <strong>{item.value}</strong>
              <span>{item.detail}</span>
              <em>{item.action}</em>
            </button>
          ))}
        </div>
      </section>
      <section className="vp-mileage-reconciliation-desk" aria-label="客户里程对账台">
        <div className="vp-mileage-reconciliation-summary">
          <Space wrap>
            <Tag color="blue">客户里程对账台</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
            <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>用同一辆车和同一时间窗完成区间里程、日报闭合、轨迹证据、告警通知和报表导出。</Typography.Title>
          <Typography.Text type="secondary">
            面向客户的统计页只围绕车辆服务展开：先看里程结论，再用轨迹和在线态势解释风险，最后交付 CSV 或复核说明。
          </Typography.Text>
        </div>
        <div className="vp-mileage-reconciliation-grid">
          {mileageReconciliationItems.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-reconciliation-item"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`客户里程对账台 ${item.label} ${item.value} ${item.action}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <strong>{item.value}</strong>
              <span>{item.detail}</span>
              <em>{item.action}</em>
            </button>
          ))}
        </div>
      </section>
      <section className="vp-mileage-delivery-console" aria-label="客户里程交付台">
        <div className="vp-mileage-delivery-console-summary">
          <Space wrap>
            <Tag color="blue">客户里程交付台</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
            <Tag color={closureStatusColor}>{closureStatus}</Tag>
          </Space>
          <strong>按自定义时间范围交付里程、闭合校验、异常复核和导出证据。</strong>
          <span>客户看统计页时先拿到可交付结论，再按同一车辆和时间窗进入轨迹、历史明细、发布审计和 CSV 导出。</span>
        </div>
        <div className="vp-mileage-delivery-console-grid">
          {mileageDeliveryConsoleItems.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-delivery-console-item"
              onClick={item.onClick}
              aria-label={`客户里程交付台 ${item.label} ${item.value} ${item.action}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <strong>{item.value}</strong>
              <span>{item.detail}</span>
              <em>{item.action}</em>
            </button>
          ))}
        </div>
      </section>
      <div className="vp-scope-bar">
        <span className="vp-scope-label">当前车辆：{currentVehicleKeyword || '-'}</span>
        <Tag color={currentProtocol ? 'blue' : 'green'}>数据通道：{currentProtocol || '全部数据通道'}</Tag>
        <Typography.Text type="tertiary">里程统计以车辆为对象，当前先覆盖里程、在线影响、闭合审计和异常复核。</Typography.Text>
      </div>
      <Card bordered className="vp-mileage-customer-query-board" bodyStyle={{ padding: 0 }}>
        <div className="vp-mileage-customer-query-summary">
          <Space wrap>
            <Tag color="blue">客户里程统计</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
            <Tag color={closureStatusColor}>{closureStatus}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>先定车辆和时间范围，再判断里程能否交付</Typography.Title>
          <Typography.Text type="secondary">
            里程统计从车辆服务出发：选择车辆或车队、设定时间窗、判断区间里程和发布状态，再进入轨迹、历史明细和导出明细。
          </Typography.Text>
          <Space wrap>
            <Button size="small" theme="solid" type="primary" onClick={copyStatisticsSummary}>复制统计摘要</Button>
            <Button size="small" theme="light" type="primary" onClick={copyMileageDecision}>复制决策说明</Button>
            <Button size="small" disabled={!currentVehicleKeyword || !onOpenHistory} onClick={() => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })}>轨迹复核</Button>
            <Button size="small" disabled={rows.length === 0} onClick={exportMileage}>导出明细</Button>
          </Space>
        </div>
        <div className="vp-mileage-customer-query-steps">
          {mileageCustomerQuerySteps.map((item) => (
            <button
              key={item.step}
              type="button"
              className="vp-mileage-customer-query-step"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`客户里程统计 ${item.title} ${item.action}`}
            >
              <span>{item.step}</span>
              <Tag color={item.color}>{item.title}</Tag>
              <strong>{item.value}</strong>
              <small>{item.detail}</small>
              <em>{item.action}</em>
            </button>
          ))}
        </div>
      </Card>
      <Card bordered title="客户里程交付导航" style={{ marginTop: 16 }}>
        <div className="vp-mileage-delivery-nav">
          <div className="vp-mileage-delivery-nav-summary">
            <Space wrap>
              <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
              <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
              <Tag color={closureStatusColor}>{closureStatus}</Tag>
            </Space>
            <Typography.Title heading={5} style={{ margin: 0 }}>把统计结果变成客户可交付的里程说明</Typography.Title>
            <Typography.Text type="secondary">
              把里程统计变成客户能看懂的交付路径：先确认口径，再回放轨迹，最后导出明细和结论。
            </Typography.Text>
          </div>
          <div className="vp-mileage-delivery-nav-grid">
            {mileageDeliveryNavigation.map((item) => (
              <button
                key={item.title}
                type="button"
                className="vp-mileage-delivery-nav-item"
                disabled={item.disabled}
                onClick={item.onClick}
                aria-label={`客户里程交付导航 ${item.title} ${item.action}`}
              >
                <Tag color={item.color}>{item.title}</Tag>
                <strong>{item.value}</strong>
                <span>{item.detail}</span>
                <em>{item.action}</em>
              </button>
            ))}
          </div>
        </div>
      </Card>
      <section className="vp-mileage-acceptance-strip" aria-label="里程客户验收清单">
        <div className="vp-mileage-acceptance-copy">
          <Space wrap>
            <Tag color="blue">里程客户验收清单</Tag>
            <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
            <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
          </Space>
          <Typography.Title heading={5} style={{ margin: 0 }}>
            客户交付前只看五个门禁：范围、闭合、覆盖、异常、在线影响；任何一项不通过都能直接进入复核动作。
          </Typography.Title>
          <Typography.Text type="secondary">
            这份清单把里程统计从技术查询变成客户验收口径，确保区间总值、每日明细、异常解释和导出证据能讲清楚。
          </Typography.Text>
        </div>
        <div className="vp-mileage-acceptance-grid">
          {mileageAcceptanceItems.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-acceptance-item"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`里程客户验收 ${item.label} ${item.value}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <strong>{item.value}</strong>
              <span>{item.detail}</span>
            </button>
          ))}
        </div>
        <div className="vp-mileage-acceptance-actions">
          {mileageAcceptanceActions.map((item) => (
            <button
              key={item.label}
              type="button"
              className="vp-mileage-acceptance-action"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`里程验收动作 ${item.label} ${item.action}`}
            >
              <Tag color={item.color}>{item.label}</Tag>
              <span>{item.action}</span>
            </button>
          ))}
        </div>
      </section>
      <Card bordered title="客户里程问题" style={{ marginTop: 16 }}>
        <div className="vp-mileage-question-grid">
          {mileageCustomerQuestions.map((item) => (
            <button
              key={item.question}
              type="button"
              className="vp-mileage-question-item"
              disabled={item.disabled}
              onClick={item.onClick}
              aria-label={`客户里程问题 ${item.question} ${item.action}`}
            >
              <strong>{item.question}</strong>
              <span>{item.answer}</span>
              <Tag color={item.color}>{item.action}</Tag>
            </button>
          ))}
        </div>
      </Card>
      <Card bordered title="里程报告建议" style={{ marginTop: 16 }}>
        <div className="vp-mileage-next-actions">
          <div className="vp-mileage-next-summary">
            <Space wrap>
              <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
              <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
              <Tag color={confidenceColor}>{confidenceStatus}</Tag>
            </Space>
            <Typography.Title heading={5} style={{ margin: 0 }}>从车辆服务视角安排下一步</Typography.Title>
            <Typography.Text type="secondary">
              里程页不再让客户先理解 GB32960、JT808、MQTT 的差异，而是直接给出交付、轨迹回放、历史查询、导出和在线影响的下一步动作。
            </Typography.Text>
          </div>
          <div className="vp-mileage-next-grid">
            {mileageNextActions.map((item) => (
              <button
                key={item.title}
                type="button"
                className="vp-mileage-next-action"
                disabled={item.disabled}
                onClick={item.onClick}
                aria-label={`里程报告建议 ${item.title} ${item.action}`}
              >
                <Tag color={item.color}>{item.title}</Tag>
                <strong>{item.value}</strong>
                <span>{item.detail}</span>
                <em>{item.action}</em>
              </button>
            ))}
          </div>
        </div>
      </Card>
      <Card bordered title="车辆统计服务总览" style={{ marginTop: 16 }}>
        <div className="vp-table-toolbar">
          <Space wrap>
            <Tag color="blue">当前统计证据</Tag>
            <Typography.Text strong>{currentEvidenceText}</Typography.Text>
            <Typography.Text type="secondary">三类数据源最终汇总为一个车辆服务统计视图</Typography.Text>
          </Space>
        </div>
        <div className="vp-stat-insight-grid">
          {[
            {
              title: '里程统计',
              value: `${formatKm(summary.totalMileageKm)} km`,
              color: 'blue' as const,
              detail: '每日里程、区间里程、异常差值和可审计证据。'
            },
            {
              title: '在线率与离线时长',
              value: formatPercent(onlineRatePercent),
              color: 'green' as const,
              detail: onlineStatsDetail || '按 VIN 统计在线率、离线时间和无更新时长。'
            },
            {
              title: '数据完整性',
              value: confidenceStatus,
              color: confidenceColor,
              detail: '围绕位置、里程、SOC、速度和数据通道新鲜度判断统计可信度。'
            },
            {
              title: '通道一致性',
              value: sourceConsistencyText,
              color: summary.sourceCount > 1 ? 'green' as const : 'orange' as const,
              detail: 'GB32960、JT808、Yutong MQTT 只作为同一车辆服务的数据通道。'
            }
          ].map((item) => (
            <div key={item.title} className="vp-monitor-metric">
              <Tag color={item.color}>{item.title}</Tag>
              <div className="vp-monitor-metric-value">{item.value}</div>
              <Typography.Text type="secondary">{item.detail}</Typography.Text>
            </div>
          ))}
        </div>
      </Card>
      <Card
        bordered
        title={<Space><span>客户里程决策台</span><Button size="small" onClick={copyMileageDecision}>复制决策说明</Button></Space>}
        style={{ marginTop: 16 }}
      >
        <div className="vp-mileage-decision-board">
          <div className="vp-mileage-decision-summary">
            <Space wrap>
              <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
              <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
              <Tag color={confidenceColor}>{confidenceStatus}</Tag>
            </Space>
            <Typography.Title heading={5} style={{ margin: 0 }}>先判断能不能交付，再进入轨迹、历史明细和导出复核</Typography.Title>
            <Typography.Text type="secondary">
              客户关心的是区间里程是否可信、异常是否解释清楚、离线是否影响统计。数据通道只作为可追溯依据，不作为页面主入口。
            </Typography.Text>
            <Space wrap>
              <Button size="small" theme="solid" type="primary" onClick={copyMileageDecision}>复制决策说明</Button>
              <Button size="small" disabled={!currentVehicleKeyword || !onOpenHistory} onClick={() => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })}>轨迹复核</Button>
              <Button size="small" disabled={!currentVehicleKeyword || !onOpenRaw} onClick={() => onOpenRaw?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '', includeFields: 'true' })}>历史明细</Button>
              <Button size="small" disabled={rows.length === 0} onClick={exportMileage}>导出明细</Button>
            </Space>
          </div>
          <div className="vp-mileage-decision-grid">
            {mileageDecisionItems.map((item) => (
              <button
                key={item.label}
                type="button"
                className="vp-mileage-decision-item"
                aria-label={`客户里程决策 ${item.label} ${item.action}`}
                onClick={item.onClick}
              >
                <Tag color={item.color}>{item.label}</Tag>
                <strong>{item.value}</strong>
                <span>{item.detail}</span>
                <em>{item.action}</em>
              </button>
            ))}
          </div>
        </div>
      </Card>
      <Card bordered title="客户里程复核交付包" style={{ marginTop: 16 }}>
        <div className="vp-mileage-delivery-board">
          <div className="vp-mileage-delivery-summary">
            <Space wrap>
              <Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
              <Tag color={closureStatusColor}>{closureStatus}</Tag>
            </Space>
            <div className="vp-monitor-metric-value">{formatKm(summary.totalMileageKm)} km</div>
            <Typography.Text type="secondary">
              面向客户交付里程时，先确认区间里程、闭合状态、异常记录和在线影响，再导出明细或进入轨迹与历史明细复核。
            </Typography.Text>
            <Space wrap>
              <Button size="small" theme="solid" type="primary" onClick={copyMileageDeliveryPackage}>复制交付包</Button>
              <Button size="small" disabled={rows.length === 0} onClick={exportMileage}>导出明细</Button>
              <Button
                size="small"
                disabled={!currentVehicleKeyword || !onOpenHistory}
                onClick={() => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })}
              >
                轨迹复核
              </Button>
            </Space>
          </div>
          <div className="vp-mileage-delivery-grid">
            {[
              {
                label: '区间里程',
                value: `${formatKm(summary.totalMileageKm)} km`,
                detail: `范围 ${mileageRangeText}，当前页明细 ${formatKm(pageMileageTotal)} km。`,
                color: 'blue' as const,
                action: '复制交付',
                onClick: copyMileageDeliveryPackage
              },
              {
                label: '闭合校验',
                value: closureStatus,
                detail: closureDeltaKm == null ? '当前页未覆盖全量记录，交付前需导出或缩小范围复核。' : `闭合差值 ${formatKm(Math.abs(closureDeltaKm))} km。`,
                color: closureStatusColor,
                action: '闭合摘要',
                onClick: copyStatisticsSummary
              },
              {
                label: '异常记录',
                value: anomalyRows.length.toLocaleString(),
                detail: anomalyRows[0] ? `${anomalyRows[0].plate || anomalyRows[0].vin} / ${anomalyRows[0].date} 需要复核。` : '当前页没有异常里程记录。',
                color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const,
                action: '异常明细',
                onClick: () => anomalyRows[0] ? copyMileageEvidence(anomalyRows[0]) : copyMileageDeliveryPackage
              },
              {
                label: '在线影响',
                value: formatPercent(onlineRatePercent),
                detail: `${onlineVehicleCount.toLocaleString()} 在线 / ${offlineVehicleCount.toLocaleString()} 离线，影响当日里程完整性判断。`,
                color: onlineRatePercent >= 90 ? 'green' as const : onlineRatePercent >= 60 ? 'orange' as const : 'red' as const,
                action: '在线态势',
                onClick: copyOnlineOperationsReport
              }
            ].map((item) => (
              <button
                key={item.label}
                type="button"
                className="vp-mileage-delivery-item"
                aria-label={`里程交付 ${item.label} ${item.action}`}
                onClick={item.onClick}
              >
                <span>
                  <Tag color={item.color}>{item.label}</Tag>
                  <strong>{item.value}</strong>
                </span>
                <Typography.Text type="secondary">{item.detail}</Typography.Text>
                <em>{item.action}</em>
              </button>
            ))}
          </div>
        </div>
      </Card>
      <Card
        bordered
        title={<Space><span>统计影响范围</span><Button size="small" onClick={copyStatisticsImpact}>复制影响范围</Button></Space>}
        style={{ marginTop: 16 }}
      >
        <div className="vp-stat-impact-board">
          <div className="vp-stat-impact-summary">
            <Tag color={statisticsImpactColor}>{statisticsImpactLevel}</Tag>
            <div className="vp-monitor-metric-value">{summary.vehicleCount.toLocaleString()} 辆车</div>
            <Typography.Text type="secondary">
              当前筛选会影响 {summary.recordCount.toLocaleString()} 条里程记录、{formatKm(summary.totalMileageKm)} km 里程口径和 {offlineVehicleCount.toLocaleString()} 辆离线车辆判断。
            </Typography.Text>
            <Space wrap>
              <Tag color={confidenceColor}>{confidenceStatus}</Tag>
              <Tag color={closureStatusColor}>{closureStatus}</Tag>
              <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
            </Space>
          </div>
          <div className="vp-stat-impact-grid">
            {statisticsImpactItems.map((item) => (
              <div key={item.label} className="vp-stat-impact-item">
                <Tag color={item.color}>{item.label}</Tag>
                <strong>{item.value}</strong>
                <Typography.Text type="secondary">{item.detail}</Typography.Text>
              </div>
            ))}
          </div>
        </div>
      </Card>
      <Card bordered title="里程服务任务板" style={{ marginTop: 16 }}>
        <div className="vp-mileage-task-grid">
          {mileageServiceTasks.map((item) => (
            <div key={item.title} className="vp-mileage-task-item">
              <div className="vp-mileage-task-head">
                <Tag color={item.color}>{item.title}</Tag>
                <strong>{item.value}</strong>
              </div>
              <Typography.Text type="secondary">{item.detail}</Typography.Text>
              <Space wrap>
                <Button
                  size="small"
                  theme="solid"
                  type="primary"
                  disabled={item.disabled}
                  aria-label={`里程服务任务 ${item.title} ${item.primaryAction}`}
                  onClick={item.onPrimary}
                >
                  {item.primaryAction}
                </Button>
                <Button
                  size="small"
                  theme="light"
                  type="primary"
                  disabled={item.secondaryDisabled}
                  aria-label={`里程服务任务 ${item.title} ${item.secondaryAction}`}
                  onClick={item.onSecondary}
                >
                  {item.secondaryAction}
                </Button>
              </Space>
            </div>
          ))}
        </div>
      </Card>
      <Card bordered>
        <Form key={JSON.stringify(filters)} initValues={filters} layout="horizontal" onSubmit={(values) => {
          const nextFilters = values as Record<string, string>;
          applyFilters(nextFilters);
        }}>
          <Form.Input field="keyword" label="车辆关键词" placeholder="VIN / 车牌 / 手机号 / OEM" style={{ width: 260 }} />
          <Form.Select field="protocol" label="数据通道" placeholder="全部数据通道" style={{ width: 180 }}>
            <Select.Option value="GB32960">GB32960</Select.Option>
            <Select.Option value="JT808">JT808</Select.Option>
            <Select.Option value="YUTONG_MQTT">YUTONG_MQTT</Select.Option>
          </Form.Select>
          <Form.Input field="dateFrom" label="开始日期" placeholder="2026-07-01" style={{ width: 160 }} />
          <Form.Input field="dateTo" label="结束日期" placeholder="2026-07-03" style={{ width: 160 }} />
          <Space>
            <Button htmlType="submit" theme="solid" type="primary">查询</Button>
            <Button onClick={() => {
              const nextFilters = mergeInitialFilters(initialVin, initialProtocol, {});
              applyFilters(nextFilters);
            }}>重置</Button>
          </Space>
        </Form>
      </Card>
      {filterSummary.length > 0 ? (
        <Card bordered title="当前里程筛选" style={{ marginTop: 16 }}>
          <Space wrap>
            {filterSummary.map((item) => (
              <Tag key={item} color="blue">{item}</Tag>
            ))}
            <Button size="small" onClick={clearRangeFilters}>清空筛选</Button>
          </Space>
        </Card>
      ) : null}
      <Card bordered loading={summaryLoading || loading} title="区间里程核对台" style={{ marginTop: 16 }}>
        <div className="vp-mileage-console">
          <div className="vp-mileage-console-main">
            <div className="vp-mileage-console-head">
              <div>
                <Typography.Title heading={5} style={{ margin: 0 }}>车辆里程核对</Typography.Title>
                <Typography.Text type="secondary">
                  面向车辆运营查看区间里程、异常记录、在线影响和复核动作。
                </Typography.Text>
              </div>
              <Space wrap>
                <Tag color={closureStatusColor}>{closureStatus}</Tag>
                <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
              </Space>
            </div>
            <div className="vp-mileage-kpi-grid">
              {mileageCustomerKpis.map((item) => (
                <button
                  key={item.label}
                  type="button"
                  className="vp-mileage-kpi-item"
                  onClick={() => {
                    if (item.label === '异常记录' && anomalyRows[0]) copyMileageEvidence(anomalyRows[0]);
                  }}
                >
                  <Tag color={item.color}>{item.label}</Tag>
                  <strong>{item.value}</strong>
                  <span>{item.detail}</span>
                </button>
              ))}
            </div>
            <div className="vp-mileage-mini-charts">
              <div>
                <div className="vp-mileage-mini-title">日里程趋势</div>
                <div className="vp-mileage-mini-chart">
                  {dateSeries.length > 0 ? dateSeries.slice(0, 10).map((item) => (
                    <div key={item.date} className="vp-mileage-mini-row">
                      <span>{item.date}</span>
                      <div><i style={{ width: `${maxDateMileage > 0 ? Math.max(4, (item.value / maxDateMileage) * 100) : 0}%` }} /></div>
                      <strong>{formatKm(item.value)} km</strong>
                    </div>
                  )) : <Typography.Text type="tertiary">暂无日里程趋势。</Typography.Text>}
                </div>
              </div>
              <div>
                <div className="vp-mileage-mini-title">来源贡献</div>
                <div className="vp-mileage-mini-chart">
                  {sourceSeries.length > 0 ? sourceSeries.slice(0, 5).map((item) => (
                    <div key={item.source} className="vp-mileage-mini-row">
                      <span>{item.source}</span>
                      <div><i className="vp-mileage-mini-row-green" style={{ width: `${maxSourceMileage > 0 ? Math.max(4, (item.value / maxSourceMileage) * 100) : 0}%` }} /></div>
                      <strong>{formatKm(item.value)} km</strong>
                    </div>
                  )) : <Typography.Text type="tertiary">暂无来源贡献。</Typography.Text>}
                </div>
              </div>
            </div>
          </div>
          <aside className="vp-mileage-console-side">
            <div className="vp-mileage-side-card">
              <div className="vp-mileage-side-title">核对动作</div>
              {mileageCustomerActions.map((item) => (
                <Button key={item.label} disabled={item.disabled} onClick={item.action}>{item.label}</Button>
              ))}
            </div>
            <div className="vp-mileage-side-card">
              <div className="vp-mileage-side-title">最高单日</div>
              {peakMileage ? (
                <>
                  <Typography.Text strong>{peakMileage.plate || peakMileage.vin}</Typography.Text>
                  <Typography.Text type="secondary">{peakMileage.date} / {peakMileage.source}</Typography.Text>
                  <div className="vp-monitor-metric-value">{formatKm(peakMileage.dailyMileageKm)} km</div>
                  <Space wrap>
                    <Button size="small" onClick={() => openMileageEvidence(peakMileage)}>轨迹复核</Button>
                    <Button size="small" onClick={() => copyMileageEvidence(peakMileage)}>复制证据</Button>
                  </Space>
                </>
              ) : (
                <Typography.Text type="tertiary">当前筛选下暂无最高单日记录。</Typography.Text>
              )}
            </div>
            <div className="vp-mileage-side-card">
              <div className="vp-mileage-side-title">里程口径</div>
              <Typography.Text type="secondary">
                区间里程以每日首末总里程差值汇总，目标是区间总值等于每日里程之和。
              </Typography.Text>
            </div>
          </aside>
        </div>
      </Card>
      <div className="vp-kpi-grid" style={{ marginTop: 16 }}>
        {[
          { label: '车辆数', value: summary.vehicleCount.toLocaleString() },
          { label: '累计里程 km', value: formatKm(summary.totalMileageKm) },
          { label: '单车平均 km', value: formatKm(summary.averageMileagePerVin) },
          { label: '来源 / 记录', value: `${summary.sourceCount}/${summary.recordCount.toLocaleString()}` }
        ].map((item) => (
          <Card key={item.label} bordered loading={summaryLoading}>
            <div className="vp-kpi-value">{item.value}</div>
            <div className="vp-kpi-label">{item.label}</div>
          </Card>
        ))}
      </div>
      <Card
        bordered
        loading={onlineLoading}
        title={<Space><span>在线影响评估</span><Button size="small" onClick={copyOnlineOperationsReport}>复制在线影响</Button></Space>}
        style={{ marginTop: 16 }}
      >
        <div className="vp-online-ops-board">
          <div className="vp-online-ops-summary">
            <Space wrap>
              <Tag color={onlineRatePercent >= 90 ? 'green' : onlineRatePercent >= 60 ? 'orange' : 'red'}>
                在线率 {formatPercent(onlineRatePercent)}
              </Tag>
              <Tag color={onlineSummary.redisOnlineKeys == null ? 'grey' : 'blue'}>
                Redis {onlineSummary.redisOnlineKeys == null ? '-' : onlineSummary.redisOnlineKeys.toLocaleString()}
              </Tag>
            </Space>
            <div className="vp-monitor-metric-value">{onlineVehicleCount.toLocaleString()} 在线</div>
            <Typography.Text type="secondary">
              在线状态用于解释统计缺口、离线车辆影响和当日里程是否需要延迟发布。
            </Typography.Text>
          </div>
          <div className="vp-online-ops-grid">
            {[
              {
                label: '离线车辆',
                value: offlineVehicleCount.toLocaleString(),
                detail: '离线车辆会影响实时统计、位置查询和当日里程完整性。',
                color: offlineVehicleCount > 0 ? 'orange' as const : 'green' as const
              },
              {
                label: '来源覆盖',
                value: onlineProtocolStats.length.toLocaleString(),
                detail: onlineProtocolStats.length > 0 ? onlineProtocolStats.map((item) => `${item.protocol} ${item.online}/${item.total}`).join('；') : '暂无来源在线统计。',
                color: onlineProtocolStats.length > 0 ? 'blue' as const : 'grey' as const
              },
              {
                label: '当前页离线',
                value: onlineRows.filter((row) => !row.online).length.toLocaleString(),
                detail: `${onlineRows.length.toLocaleString()} 条在线状态明细参与当前页复核。`,
                color: onlineRows.some((row) => !row.online) ? 'orange' as const : 'green' as const
              },
              {
                label: '最长离线',
                value: topOfflineRow ? formatOfflineDuration(topOfflineRow.offlineDurationMinutes) : '-',
                detail: topOfflineRow ? `${topOfflineRow.plate || topOfflineRow.vin} / ${topOfflineRow.lastSeen || '-'}` : '当前页暂无离线车辆。',
                color: topOfflineRow ? 'orange' as const : 'green' as const
              },
              {
                label: '统计证据',
                value: onlineSummary.evidence || '-',
                detail: '后端在线统计证据，可与 Redis key 和车辆快照互相校验。',
                color: onlineSummary.evidence ? 'blue' as const : 'grey' as const
              }
            ].map((item) => (
              <div key={item.label} className="vp-online-ops-item">
                <Tag color={item.color}>{item.label}</Tag>
                <strong>{item.value}</strong>
                <Typography.Text type="secondary">{item.detail}</Typography.Text>
              </div>
            ))}
          </div>
        </div>
      </Card>
      <Card bordered title="统计闭合工作台" loading={summaryLoading || loading} style={{ marginTop: 16 }}>
        <div className="vp-stat-closure-board">
          {[
            { label: '汇总总里程', value: `${formatKm(summary.totalMileageKm)} km`, color: 'blue' as const, detail: '后端按当前筛选范围返回的区间里程总值。' },
            { label: '明细合计', value: `${formatKm(pageMileageTotal)} km`, color: 'green' as const, detail: '当前页日里程明细求和，用于快速复核。' },
            { label: '闭合差值', value: closureDeltaKm == null ? '需全量' : `${formatKm(Math.abs(closureDeltaKm))} km`, color: closureStatusColor, detail: closureActionText },
            { label: '记录覆盖率', value: formatPercent(pageCoverageRate), color: pageCoverageRate >= 100 ? 'green' as const : 'grey' as const, detail: `${rows.length.toLocaleString()} / ${summary.recordCount.toLocaleString()} 条明细在当前页。` }
          ].map((item) => (
            <div key={item.label} className="vp-stat-closure-item">
              <Tag color={item.color}>{item.label}</Tag>
              <div className="vp-monitor-metric-value">{item.value}</div>
              <Typography.Text type="secondary">{item.detail}</Typography.Text>
            </div>
          ))}
        </div>
        <div className="vp-stat-closure-action">
          <Tag color={closureStatusColor}>{closureStatus}</Tag>
          <Typography.Text type="secondary">
            {closurePassed && anomalyRows.length === 0 ? '当前里程口径可直接用于 BI 里程口径；若存在跨通道差异，再进入车辆服务查看统计依据。' : '统计进入 BI 前需要结合异常记录、轨迹回放和历史明细完成复核。'}
          </Typography.Text>
          <Space wrap>
            <Button size="small" onClick={copyStatisticsSummary}>复制闭合摘要</Button>
            <Button
              size="small"
              disabled={!currentVehicleKeyword || !onOpenHistory}
              onClick={() => onOpenHistory?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '' })}
            >
              闭合复核轨迹
            </Button>
            <Button
              size="small"
              disabled={!currentVehicleKeyword || !onOpenRaw}
              onClick={() => onOpenRaw?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, dateFrom: filters.dateFrom ?? '', dateTo: filters.dateTo ?? '', includeFields: 'true' })}
            >
              闭合复核原始
            </Button>
          </Space>
        </div>
      </Card>
      <Card bordered title="BI发布口径" style={{ marginTop: 16 }}>
        <div className="vp-bi-publish-board">
          <div className="vp-bi-publish-main">
            <Tag color={confidenceColor}>{confidenceStatus}</Tag>
            <div className="vp-monitor-metric-value">
              {confidenceStatus === '可用于 BI' && closureStatus === '闭合通过' ? '可发布' : '需复核后发布'}
            </div>
            <Typography.Text type="secondary">
              日里程按首末总里程差值计算，区间总值必须等于每日里程之和；发布前同步检查异常记录、分页覆盖和通道一致性。
            </Typography.Text>
          </div>
          <div className="vp-bi-publish-grid">
            <div><span>闭合状态</span><strong>{closureStatus}</strong></div>
            <div><span>记录覆盖</span><strong>{formatPercent(pageCoverageRate)}</strong></div>
            <div><span>异常记录</span><strong>{anomalyRows.length.toLocaleString()}</strong></div>
            <div><span>通道一致性</span><strong>{sourceConsistencyText}</strong></div>
          </div>
          <Space wrap>
            <Button size="small" onClick={copyBIPublishText}>复制BI发布口径</Button>
            <Button size="small" onClick={copyStatisticsSummary}>复制统计摘要</Button>
          </Space>
        </div>
      </Card>
      <Card bordered title="统计发布审计" style={{ marginTop: 16 }}>
        <div className="vp-stat-audit-board">
          <div className="vp-stat-audit-summary">
            <Tag color={publishAuditColor}>{publishAuditConclusion}</Tag>
            <div className="vp-monitor-metric-value">
              通过 {publishAuditItems.length - publishReviewCount - publishBlockedCount} / 复核 {publishReviewCount} / 阻断 {publishBlockedCount}
            </div>
            <Typography.Text type="secondary">
              发布前统一审计闭合、覆盖、异常、数据通道和在线状态；不满足时先回到轨迹和历史明细复核。
            </Typography.Text>
            <Space wrap>
              <Button size="small" onClick={copyPublishAudit}>复制统计发布审计</Button>
              <Button size="small" disabled={!currentVehicleKeyword} onClick={() => onOpenVehicle(currentVehicleKeyword, currentProtocol)}>车辆服务</Button>
            </Space>
          </div>
          <div className="vp-stat-audit-grid">
            {publishAuditItems.map((item) => (
              <div key={item.key} className="vp-stat-audit-item">
                <Space wrap>
                  <Tag color={auditStatusColor(item.status)}>{auditStatusLabel(item.status)}</Tag>
                  <Tag color="blue">{item.label}</Tag>
                </Space>
                <strong>{item.value}</strong>
                <Typography.Text type="secondary">{item.detail}</Typography.Text>
                <div className="vp-stat-audit-action">{item.action}</div>
              </div>
            ))}
          </div>
        </div>
      </Card>
      <div className="vp-stat-workspace">
        <Card bordered title="区间趋势">
          <div className="vp-stat-chart">
            {dateSeries.length > 0 ? dateSeries.map((item) => (
              <div key={item.date} className="vp-stat-bar-row">
                <span className="vp-stat-bar-label">{item.date}</span>
                <div className="vp-stat-bar-track">
                  <span className="vp-stat-bar-fill" style={{ width: `${maxDateMileage > 0 ? Math.max(4, (item.value / maxDateMileage) * 100) : 0}%` }} />
                </div>
                <span className="vp-stat-bar-value">{formatKm(item.value)} km</span>
              </div>
            )) : (
              <Typography.Text type="secondary">当前筛选范围暂无可展示趋势。</Typography.Text>
            )}
          </div>
        </Card>
        <Card bordered title="来源贡献">
          <div className="vp-stat-chart">
            {sourceSeries.length > 0 ? sourceSeries.map((item) => (
              <div key={item.source} className="vp-stat-bar-row">
                <span className="vp-stat-bar-label">{item.source}</span>
                <div className="vp-stat-bar-track">
                  <span className="vp-stat-bar-fill vp-stat-bar-fill-green" style={{ width: `${maxSourceMileage > 0 ? Math.max(4, (item.value / maxSourceMileage) * 100) : 0}%` }} />
                </div>
                <span className="vp-stat-bar-value">{formatKm(item.value)} km</span>
              </div>
            )) : (
              <Typography.Text type="secondary">当前筛选范围暂无来源贡献。</Typography.Text>
            )}
          </div>
        </Card>
      </div>
      <div className="vp-stat-insight-grid">
        {[
          { label: '统计可信度', value: confidenceStatus, color: confidenceColor, detail: anomalyRows.length > 0 ? '存在异常里程记录，建议先核对统计依据。' : '当前分页未发现异常记录。' },
          { label: '异常率', value: formatPercent(anomalyRate), color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const, detail: `${anomalyRows.length.toLocaleString()} / ${rows.length.toLocaleString()} 条明细命中异常标记。` },
          { label: '最大单日占比', value: formatPercent(peakMileageShare), color: peakMileageShare > 50 ? 'orange' as const : 'blue' as const, detail: peakMileage ? `${peakMileage.plate || peakMileage.vin} 贡献最高单日里程。` : '暂无明细。' },
          { label: '当前页里程', value: `${formatKm(pageMileageTotal)} km`, color: 'blue' as const, detail: '用于快速核对当前分页明细合计。' },
          { label: '异常记录', value: anomalyRows.length.toLocaleString(), color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const, detail: '来自异常标记，优先核对首末总里程和断链。' },
          { label: '最大单日', value: peakMileage ? `${formatKm(peakMileage.dailyMileageKm)} km` : '-', color: 'blue' as const, detail: peakMileage ? `${peakMileage.plate || peakMileage.vin} / ${peakMileage.date}` : '暂无明细。' },
          { label: '分页覆盖率', value: formatPercent(pageCoverageRate), color: pageCoverageRate >= 100 ? 'green' as const : 'grey' as const, detail: '当前分页记录数 / 全量统计记录数。' },
          {
            label: '闭合校验',
            value: closureDeltaKm == null ? '需全量核验' : `${formatKm(Math.abs(closureDeltaKm))} km`,
            color: closurePassed ? 'green' as const : closureDeltaKm == null ? 'grey' as const : 'orange' as const,
            detail: closureDeltaKm == null ? '当前分页未覆盖全量记录，需翻页或导出全量后核验。' : '汇总总里程与当前明细合计的差值。'
          }
        ].map((item) => (
          <Card key={item.label} bordered>
            <Tag color={item.color}>{item.label}</Tag>
            <div className="vp-monitor-metric-value">{item.value}</div>
            <Typography.Text type="secondary">{item.detail}</Typography.Text>
          </Card>
        ))}
      </div>
      <Card bordered title="在线状态明细" style={{ marginTop: 16 }}>
        <div className="vp-table-toolbar">
          <Space wrap>
            <Tag color="green">在线 {onlineVehicleCount.toLocaleString()} 车</Tag>
            <Tag color="orange">离线 {offlineVehicleCount.toLocaleString()} 车</Tag>
            <Typography.Text type="secondary">按车辆服务归并 VIN，展示最近上报时间、离线时长和来源覆盖。</Typography.Text>
            <Button size="small" onClick={copyOnlineStatusHandoff}>复制在线状态清单</Button>
          </Space>
        </div>
        <Table
          loading={onlineLoading}
          rowKey={(row?: OnlineVehicleStatusRow) => row?.vin ?? ''}
          dataSource={onlineRows}
          pagination={{
            currentPage: onlinePagination.currentPage,
            pageSize: onlinePagination.pageSize,
            total: onlinePagination.total,
            showSizeChanger: true,
            onPageChange: (page) => loadOnlineRows(filters, page, onlinePagination.pageSize),
            onPageSizeChange: (pageSize) => loadOnlineRows(filters, 1, pageSize)
          }}
          columns={[
            { title: 'VIN', dataIndex: 'vin', width: 190 },
            { title: '车牌', dataIndex: 'plate', width: 120 },
            { title: 'OEM', dataIndex: 'oem', width: 120 },
            {
              title: '在线',
              width: 90,
              render: (_: unknown, row: OnlineVehicleStatusRow) => <Tag color={row.online ? 'green' : 'orange'}>{row.online ? '在线' : '离线'}</Tag>
            },
            { title: '最近上报', dataIndex: 'lastSeen', width: 180 },
            {
              title: '离线时长',
              width: 130,
              render: (_: unknown, row: OnlineVehicleStatusRow) => formatOfflineDuration(row.offlineDurationMinutes)
            },
            {
              title: '来源覆盖',
              width: 150,
              render: (_: unknown, row: OnlineVehicleStatusRow) => `${row.onlineSourceCount}/${row.sourceCount}`
            },
            {
              title: '来源明细',
              width: 240,
              render: (_: unknown, row: OnlineVehicleStatusRow) => (
                <Space spacing={4} wrap>
                  {(row.protocols ?? []).map((protocol) => <Tag key={protocol} color="blue">{protocol}</Tag>)}
                </Space>
              )
            },
            { title: '绑定状态', dataIndex: 'bindingStatus', width: 130 },
            {
              title: '操作',
              width: 120,
              render: (_: unknown, row: OnlineVehicleStatusRow) => (
                <Button disabled={!canOpenVehicle(row.vin)} onClick={() => onOpenVehicle(row.vin, currentProtocol)}>车辆服务</Button>
              )
            }
          ]}
        />
      </Card>
      <Card bordered title="里程口径" style={{ marginTop: 16 }}>
        <div className="vp-table-toolbar">
          <Space wrap>
            <Tag color="blue">可复制日报口径</Tag>
            <Button size="small" onClick={copyStatisticsSummary}>复制统计摘要</Button>
          </Space>
        </div>
        <div className="vp-stat-definition-grid">
          <div>
            <Tag color="blue">日里程</Tag>
            <p>按车辆、来源、日期聚合，以总里程差值作为日统计结果，避免中间断链导致分段累计不闭合。</p>
          </div>
          <div>
            <Tag color="green">区间里程</Tag>
            <p>按当前筛选范围汇总日里程，区间总值应等于各日里程之和，用于 BI 和运营报表口径。</p>
          </div>
          <div>
            <Tag color="orange">异常复核</Tag>
            <p>异常优先检查补传、通道切换、总里程回退和跨通道差异，必要时回到车辆服务查看历史明细。</p>
          </div>
        </div>
      </Card>
      <Card bordered style={{ marginTop: 16 }}>
        <div className="vp-table-toolbar">
          <Space wrap>
            <Tag color="blue">当前页 {rows.length.toLocaleString()} 条</Tag>
            <Button size="small" onClick={exportMileage}>导出里程当前页 CSV</Button>
          </Space>
        </div>
        <Table
          loading={loading}
          rowKey={(row?: DailyMileageRow) => `${row?.date ?? ''}-${row?.vin ?? ''}-${row?.source ?? ''}`}
          dataSource={rows}
          pagination={{
            currentPage: pagination.currentPage,
            pageSize: pagination.pageSize,
            total: pagination.total,
            showSizeChanger: true,
            onPageChange: (page) => load(filters, page, pagination.pageSize),
            onPageSizeChange: (pageSize) => load(filters, 1, pageSize)
          }}
          columns={[
            { title: '日期', dataIndex: 'date' },
            { title: 'VIN', dataIndex: 'vin' },
            { title: '车牌', dataIndex: 'plate' },
            { title: '起始里程', dataIndex: 'startMileageKm' },
            { title: '结束里程', dataIndex: 'endMileageKm' },
            { title: '日里程', dataIndex: 'dailyMileageKm' },
            { title: '来源', dataIndex: 'source' },
            { title: '异常', render: (_: unknown, row: DailyMileageRow) => row.anomalySeverity ? <Tag color="orange">{row.anomalySeverity}</Tag> : <Tag color="green">正常</Tag> },
            {
              title: '处置建议',
              width: 260,
              render: (_: unknown, row: DailyMileageRow) => {
                const action = mileageActionRecommendation(row);
                return (
                  <div>
                    <Tag color={action.color}>{action.label}</Tag>
                    <div style={{ marginTop: 6 }}>{action.detail}</div>
                  </div>
                );
              }
            },
            {
              title: '操作',
              width: 360,
              render: (_: unknown, row: DailyMileageRow) => (
                <Space spacing={4} wrap>
                  <Button disabled={!canOpenVehicle(row.vin)} onClick={() => copyMileageEvidence(row)}>复制证据</Button>
                  <Button disabled={!canOpenVehicle(row.vin) || !onOpenHistory} onClick={() => openMileageEvidence(row)}>核对轨迹</Button>
                  <Button disabled={!canOpenVehicle(row.vin) || !onOpenRaw} onClick={() => openMileageRawEvidence(row)}>核对原始</Button>
                  <Button disabled={!canOpenVehicle(row.vin)} onClick={() => onOpenVehicle(row.vin, row.source)}>车辆服务</Button>
                </Space>
              )
            }
          ]}
        />
      </Card>
    </div>
  );
}
