import { Button, Card, Col, Form, Row, Select, Space, Spin, Table, Tag, Toast, Typography } from '@douyinfe/semi-ui';
import { IconSearch } from '@douyinfe/semi-icons';
import { useEffect, useMemo, useState } from 'react';
import { api } from '../api/client';
import type { DashboardSummary, LinkHealth, ProtocolStat, QualityIssueRow, ServiceStatusStat, VehicleCoverageRow, VehicleRealtimeRow, VehicleServiceSummary } from '../api/types';
import { PageHeader } from '../components/PageHeader';
import { SourceStatusTags } from '../components/SourceStatusTags';
import { StatusTag } from '../components/StatusTag';
import { VehicleMap, type VehicleMapPoint } from '../components/VehicleMap';
import { isAMapConfigured } from '../config/appConfig';
import { qualityIssueVehicleLookup } from '../domain/vehicleLookup';

const statusColor: Record<string, 'green' | 'orange' | 'red' | 'grey'> = {
  ok: 'green',
  warning: 'orange',
  error: 'red'
};

const serviceStatusColor: Record<string, 'green' | 'orange' | 'red' | 'grey'> = {
  healthy: 'green',
  degraded: 'orange',
  offline: 'red',
  no_data: 'orange',
  identity_required: 'orange'
};

const serviceStatusTitle: Record<string, string> = {
  healthy: '服务正常',
  degraded: '来源不完整',
  offline: '车辆离线',
  no_data: '暂无数据来源',
  identity_required: '身份未绑定'
};

const missingProtocolTitle: Record<string, string> = {
  GB32960: '缺 GB32960',
  JT808: '缺 JT808',
  YUTONG_MQTT: '缺 YUTONG_MQTT'
};

function formatLag(value?: number | null) {
  return value == null ? '未接入' : value.toLocaleString();
}

function formatCount(value?: number | null) {
  return value == null ? '0' : value.toLocaleString();
}

function vehicleServiceOnlineText(serviceSummary: VehicleServiceSummary | null, summary: DashboardSummary | null) {
  const onlineVehicles = serviceSummary?.onlineVehicles ?? summary?.onlineVehicles;
  const totalVehicles = serviceSummary?.totalVehicles;
  if (onlineVehicles == null || totalVehicles == null) {
    return '未接入';
  }
  return `${onlineVehicles.toLocaleString()} / ${totalVehicles.toLocaleString()} 在线`;
}

function formatProtocolRate(row: ProtocolStat) {
  if (!Number.isFinite(row.total) || row.total <= 0) {
    return '0%';
  }
  return `${Math.round((row.online / row.total) * 100)}%`;
}

function rowServiceStatus(row: { serviceStatus?: { title: string; severity: string }; onlineSourceCount: number; sourceCount: number }) {
  if (row.serviceStatus) {
    return {
      label: row.serviceStatus.title,
      color: row.serviceStatus.severity === 'ok' ? 'green' as const : row.serviceStatus.severity === 'error' ? 'red' as const : 'orange' as const
    };
  }
  if (row.onlineSourceCount <= 0) {
    return { label: '车辆离线', color: 'red' as const };
  }
  if (row.onlineSourceCount < row.sourceCount) {
    return { label: '来源不完整', color: 'orange' as const };
  }
  return { label: '服务正常', color: 'green' as const };
}

function sourceEvidenceText(row: { onlineSourceCount: number; sourceCount: number }) {
  return `${row.onlineSourceCount}/${row.sourceCount} 来源在线`;
}

function hasValidCoordinate(row: VehicleRealtimeRow) {
  return Number.isFinite(row.longitude) && Number.isFinite(row.latitude) && row.longitude !== 0 && row.latitude !== 0;
}

function sourceConsistencyAction(row: VehicleCoverageRow, onFilter: (filters: Record<string, string>) => void) {
  const consistency = row.sourceConsistency;
  if (!consistency) {
    return <Tag color="grey">未诊断</Tag>;
  }
  const color = consistency.severity === 'ok' ? 'green' as const : consistency.severity === 'error' ? 'red' as const : 'orange' as const;
  const label = consistency.title || consistency.status;
  if ((consistency.missingProtocols ?? []).length > 0) {
    return (
      <Button
        size="small"
        theme="light"
        type={color === 'red' ? 'danger' : color === 'orange' ? 'warning' : 'primary'}
        onClick={() => onFilter({ serviceStatus: 'degraded', missingProtocol: consistency.missingProtocols[0] })}
      >
        {label}
      </Button>
    );
  }
  return <Tag color={color}>{label}</Tag>;
}

export function Dashboard({
  onOpenVehicle,
  onOpenQuality,
  onOpenRealtime,
  onOpenVehicles
}: {
  onOpenVehicle: (vin: string, protocol?: string) => void;
  onOpenQuality: (filters?: Record<string, string>) => void;
  onOpenRealtime: (filters?: Record<string, string>) => void;
  onOpenVehicles: (filters?: Record<string, string>) => void;
}) {
  const [summary, setSummary] = useState<DashboardSummary | null>(null);
  const [serviceSummary, setServiceSummary] = useState<VehicleServiceSummary | null>(null);
  const [coverage, setCoverage] = useState<VehicleCoverageRow[]>([]);
  const [locations, setLocations] = useState<VehicleRealtimeRow[]>([]);
  const [qualityIssues, setQualityIssues] = useState<QualityIssueRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [coverageLoading, setCoverageLoading] = useState(false);
  const [coverageServiceStatusTitle, setCoverageServiceStatusTitle] = useState('');
  const [coverageFilters, setCoverageFilters] = useState<Record<string, string>>({});
  const amapConfigured = isAMapConfigured();

  const loadCoverage = (values?: Record<string, string>) => {
    const nextValues = values ?? {};
    setCoverageLoading(true);
    setCoverageFilters(nextValues);
    const scopeTitle = [
      nextValues.serviceStatus ? serviceStatusTitle[nextValues.serviceStatus] ?? nextValues.serviceStatus : '',
      nextValues.missingProtocol ? missingProtocolTitle[nextValues.missingProtocol] ?? `缺 ${nextValues.missingProtocol}` : ''
    ].filter(Boolean).join(' / ');
    setCoverageServiceStatusTitle(scopeTitle);
    const params = new URLSearchParams({ limit: '8' });
    if (nextValues.keyword) params.set('keyword', nextValues.keyword);
    if (nextValues.coverage) params.set('coverage', nextValues.coverage);
    if (nextValues.missingProtocol) params.set('missingProtocol', nextValues.missingProtocol);
    if (nextValues.online) params.set('online', nextValues.online);
    if (nextValues.bindingStatus) params.set('bindingStatus', nextValues.bindingStatus);
    if (nextValues.serviceStatus) params.set('serviceStatus', nextValues.serviceStatus);
    api.vehicleCoverage(params)
      .then((page) => setCoverage(page.items))
      .catch((error: Error) => Toast.error(error.message))
      .finally(() => setCoverageLoading(false));
  };

  useEffect(() => {
    const tasks = [
      api.dashboardSummary().then(setSummary),
      api.vehicleServiceSummary().then(setServiceSummary),
      api.vehicleCoverage(new URLSearchParams({ limit: '8' })).then((page) => setCoverage(page.items)),
      api.vehicleRealtime(new URLSearchParams({ limit: '8' })).then((page) => setLocations(page.items)),
      api.qualityIssues(new URLSearchParams({ limit: '5' })).then((page) => setQualityIssues(page.items))
    ];
    Promise.allSettled(tasks)
      .then((results) => {
        const failed = results.find((result) => result.status === 'rejected');
        if (failed?.status === 'rejected') {
          const reason = failed.reason;
          Toast.error(reason instanceof Error ? reason.message : '总览数据加载失败');
        }
      })
      .finally(() => setLoading(false));
  }, []);

  const kpis: Array<{ label: string; value: string; filters: Record<string, string> }> = [
    { label: '总车辆', value: formatCount(serviceSummary?.totalVehicles), filters: {} },
    { label: '在线车辆', value: formatCount(serviceSummary?.onlineVehicles ?? summary?.onlineVehicles), filters: { online: 'online' } },
    { label: '单源车辆', value: formatCount(serviceSummary?.singleSourceVehicles), filters: { coverage: 'single' } },
    { label: '多源车辆', value: formatCount(serviceSummary?.multiSourceVehicles), filters: { coverage: 'multi' } },
    { label: '暂无来源车辆', value: formatCount(serviceSummary?.noDataVehicles), filters: { serviceStatus: 'no_data' } },
    { label: '身份未绑定', value: formatCount(serviceSummary?.identityRequiredVehicles), filters: { serviceStatus: 'identity_required' } },
    { label: '档案不完整', value: formatCount(serviceSummary?.archiveIncompleteVehicles), filters: { archiveStatus: 'incomplete' } }
  ];
  const missingSourceCounts = new Map((serviceSummary?.missingSources ?? []).map((item) => [item.protocol, item.count]));
  const serviceActionQueue = useMemo<Array<{ label: string; count: number; filters: Record<string, string>; detail: string }>>(() => {
    const items: Array<{ label: string; count: number; filters: Record<string, string>; detail: string }> = [];
    if ((serviceSummary?.noDataVehicles ?? 0) > 0) {
      items.push({
        label: '确认平台转发',
        count: serviceSummary?.noDataVehicles ?? 0,
        filters: { serviceStatus: 'no_data' },
        detail: '车辆没有形成任何来源证据，优先确认上游平台是否持续转发。'
      });
    }
    if ((serviceSummary?.identityRequiredVehicles ?? 0) > 0) {
      items.push({
        label: '维护身份绑定',
        count: serviceSummary?.identityRequiredVehicles ?? 0,
        filters: { serviceStatus: 'identity_required' },
        detail: '已有数据但无法稳定归并到 VIN，会影响车辆服务聚合。'
      });
    }
    if ((serviceSummary?.archiveIncompleteVehicles ?? 0) > 0) {
      items.push({
        label: '完善车辆档案',
        count: serviceSummary?.archiveIncompleteVehicles ?? 0,
        filters: { archiveStatus: 'incomplete' },
        detail: '车辆缺少车牌、手机号或 OEM 等基础档案，影响后续运营查询和治理。'
      });
    }
    for (const field of serviceSummary?.archiveMissingFields ?? []) {
      if (field.count <= 0) continue;
      items.push({
        label: `补齐${field.title}`,
        count: field.count,
        filters: { archiveMissing: field.field },
        detail: `${field.title}会影响车辆档案检索、绑定确认和运营侧筛选。`
      });
    }
    for (const source of serviceSummary?.missingSources ?? []) {
      if (source.count <= 0) continue;
      items.push({
        label: `补齐 ${source.protocol} 来源`,
        count: source.count,
        filters: { serviceStatus: 'degraded', missingProtocol: source.protocol },
        detail: `${source.protocol} 来源缺失会降低跨来源定位、里程和实时判断可信度。`
      });
    }
    return items;
  }, [serviceSummary]);
  const commandOnlineCount = locations.filter((row) => row.online).length;
  const commandLocatedCount = locations.filter(hasValidCoordinate).length;
  const commandDegradedCount = locations.filter((row) => row.onlineSourceCount <= 0 || row.onlineSourceCount < row.sourceCount).length;
  const highPriorityIssue = qualityIssues.find((item) => item.severity === 'error') ?? qualityIssues[0];
  const commandMapPoints: VehicleMapPoint[] = locations.map((row, index) => ({
    id: row.vin || `${row.primaryProtocol || 'source'}-${index}`,
    label: row.plate || row.vin || 'unknown',
    longitude: row.longitude,
    latitude: row.latitude,
    online: row.online,
    title: `${row.plate || row.vin || '-'} ${row.primaryProtocol || ''} ${row.lastSeen || ''}`
  }));

  return (
    <div className="vp-page">
      <PageHeader title="总览工作台" description="以车辆服务为中心汇总在线状态、数据来源覆盖、质量问题和链路健康" />
      <Spin spinning={loading}>
        <div className="vp-kpi-grid">
          {kpis.map((item) => (
            <Card key={item.label} bordered className="vp-kpi-card" bodyStyle={{ padding: 0 }}>
              <button className="vp-kpi-button" type="button" onClick={() => onOpenVehicles(item.filters)} aria-label={`${item.label} ${item.value}`}>
              <div className="vp-kpi-value">{item.value}</div>
              <div className="vp-kpi-label">{item.label}</div>
              </button>
            </Card>
          ))}
        </div>
        <Card bordered title="统一车辆服务" style={{ marginBottom: 16 }}>
          <Space wrap>
            <Tag color="blue">{vehicleServiceOnlineText(serviceSummary, summary)}</Tag>
            <Button size="small" theme="light" type="primary" onClick={() => onOpenVehicles({ online: 'online' })}>查看在线车辆</Button>
            <Tag color="green">{formatCount(serviceSummary?.multiSourceVehicles)} 多源覆盖</Tag>
            <Button size="small" theme="light" type="primary" onClick={() => onOpenVehicles({ coverage: 'multi' })}>查看多源车辆</Button>
            <Tag color={(summary?.issueVehicles ?? 0) > 0 ? 'orange' : 'green'}>
              {formatCount(summary?.issueVehicles)} 质量关注
            </Tag>
            <Button size="small" theme="light" type={(summary?.issueVehicles ?? 0) > 0 ? 'warning' : 'tertiary'} onClick={() => onOpenQuality()}>查看质量关注</Button>
            <Tag color={(summary?.kafkaLag ?? 0) > 0 ? 'orange' : 'green'}>Kafka Lag {formatLag(summary?.kafkaLag)}</Tag>
          </Space>
        </Card>
        <Card
          bordered
          title="车辆态势指挥台"
          style={{ marginBottom: 16 }}
        >
          <div className="vp-monitor-layout">
            <div className="vp-monitor-map">
              <div className="vp-monitor-map-header">
                <Space wrap>
                  <Tag color={amapConfigured ? 'green' : 'orange'}>
                    {amapConfigured ? '高德地图配置就绪' : '高德地图待配置'}
                  </Tag>
                  <Tag color="green">在线 {commandOnlineCount.toLocaleString()} / {locations.length.toLocaleString()}</Tag>
                  <Tag color="blue">有效定位 {commandLocatedCount.toLocaleString()}</Tag>
                  <Tag color={commandDegradedCount > 0 ? 'orange' : 'green'}>降级/离线 {commandDegradedCount.toLocaleString()}</Tag>
                </Space>
              </div>
              <VehicleMap
                points={commandMapPoints}
                maxFallbackPoints={80}
                fallbackLabel="高德地图未配置，显示车辆态势坐标预览"
              />
            </div>
            <div className="vp-monitor-side">
              <div className="vp-monitor-metric">
                <Tag color="green">实时作业</Tag>
                <div className="vp-monitor-metric-value">{commandOnlineCount.toLocaleString()}</div>
                <Typography.Text type="secondary">当前预览车辆在线数，进入实时监控可按车辆、来源和服务状态筛选。</Typography.Text>
              </div>
              <div className="vp-monitor-metric">
                <Tag color={commandDegradedCount > 0 ? 'orange' : 'green'}>处置优先级</Tag>
                <div className="vp-monitor-metric-value">{commandDegradedCount.toLocaleString()}</div>
                <Typography.Text type="secondary">优先处理离线、无来源、身份未绑定和来源不完整车辆。</Typography.Text>
              </div>
              <Space vertical align="start">
                <Button theme="solid" type="primary" onClick={() => onOpenRealtime({ online: 'online' })}>查看实时态势</Button>
                <Button
                  disabled={!highPriorityIssue?.issueType}
                  theme="light"
                  type="warning"
                  onClick={() => onOpenQuality(highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {})}
                >
                  处理高优先级告警
                </Button>
                <Button theme="light" onClick={() => onOpenVehicles({ serviceStatus: 'degraded' })}>查看降级车辆</Button>
              </Space>
            </div>
          </div>
        </Card>
        {serviceActionQueue.length > 0 ? (
          <Card bordered title="车辆服务处置队列" style={{ marginBottom: 16 }}>
            <div className="vp-action-grid">
              {serviceActionQueue.map((item) => (
                <div key={`${item.label}-${item.count}`} className="vp-action-item">
                  <div>
                    <Tag color="orange">{item.label} {item.count.toLocaleString()}</Tag>
                    <Typography.Text type="secondary" style={{ display: 'block', marginTop: 8 }}>{item.detail}</Typography.Text>
                  </div>
                  <Button size="small" theme="light" type="warning" onClick={() => onOpenVehicles(item.filters)}>
                    {item.label} {item.count.toLocaleString()}
                  </Button>
                </div>
              ))}
            </div>
          </Card>
        ) : null}
        <Row gutter={16}>
          <Col span={8}>
            <Card title="车辆服务状态" bordered>
              <Table
                pagination={false}
                dataSource={serviceSummary?.serviceStatuses ?? summary?.serviceStatuses ?? []}
                columns={[
                  {
                    title: '状态',
                    render: (_: unknown, row: ServiceStatusStat) => <Tag color={serviceStatusColor[row.status] ?? 'grey'}>{row.title}</Tag>
                  },
                  { title: '车辆数', dataIndex: 'count' },
                  {
                    title: '操作',
                    width: 90,
                    render: (_: unknown, row: ServiceStatusStat) => (
                      <Button
                        aria-label={`查看${row.title}`}
                        icon={<IconSearch />}
                        size="small"
                        onClick={() => loadCoverage({ serviceStatus: row.status })}
                      />
                    )
                  }
                ]}
              />
            </Card>
          </Col>
          <Col span={8}>
            <Card title="来源证据在线分布" bordered>
              <Table
                pagination={false}
                dataSource={serviceSummary?.protocols ?? summary?.protocols ?? []}
                columns={[
                  { title: '来源证据', dataIndex: 'protocol' },
                  { title: '在线', dataIndex: 'online' },
                  { title: '总数', dataIndex: 'total' },
                  {
                    title: '在线率',
                    render: (_: unknown, row: ProtocolStat) => formatProtocolRate(row)
                  },
                  {
                    title: '缺失车辆',
                    render: (_: unknown, row: ProtocolStat) => {
                      const missingCount = missingSourceCounts.get(row.protocol);
                      if (missingCount == null) {
                        return '-';
                      }
                      return (
                        <Button
                          aria-label={`查看缺 ${row.protocol}`}
                          size="small"
                          onClick={() => loadCoverage({ missingProtocol: row.protocol })}
                        >
                          {formatCount(missingCount)}
                        </Button>
                      );
                    }
                  }
                ]}
              />
            </Card>
          </Col>
          <Col span={8}>
            <Card title="链路健康" bordered>
              <Table
                pagination={false}
                dataSource={summary?.linkHealth ?? []}
                columns={[
                  { title: '链路', dataIndex: 'name' },
                  {
                    title: '状态',
                    render: (_: unknown, row: LinkHealth) => <Tag color={statusColor[row.status] ?? 'grey'}>{row.status}</Tag>
                  },
                  { title: '说明', dataIndex: 'detail' }
                ]}
              />
            </Card>
          </Col>
        </Row>
        <Card title="实时积压" bordered style={{ marginTop: 16 }}>
          <Typography.Text>Kafka 当前消费积压：{formatLag(summary?.kafkaLag)}</Typography.Text>
        </Card>
        <Card
          title={<Space><span>质量问题预览</span><Button size="small" onClick={() => onOpenQuality()}>查看全部</Button></Space>}
          bordered
          style={{ marginTop: 16 }}
        >
          <Table
            pagination={false}
            rowKey={(row?: QualityIssueRow) => `${row?.protocol ?? ''}-${row?.issueType ?? ''}-${row?.lastSeen ?? ''}-${row?.detail ?? ''}`}
            dataSource={qualityIssues}
            columns={[
              { title: 'VIN', dataIndex: 'vin', width: 160 },
              { title: '车牌', dataIndex: 'plate', width: 110 },
              { title: '手机号', dataIndex: 'phone', width: 130 },
              { title: '来源地址', dataIndex: 'sourceEndpoint', width: 180 },
              { title: '来源', dataIndex: 'protocol', width: 110 },
              { title: '问题', dataIndex: 'issueType', width: 140 },
              { title: '级别', width: 90, render: (_: unknown, row: QualityIssueRow) => <Tag color={row.severity === 'error' ? 'red' : 'orange'}>{row.severity}</Tag> },
              { title: '最后时间', dataIndex: 'lastSeen', width: 170 },
              {
                title: '操作',
                width: 130,
                render: (_: unknown, row: QualityIssueRow) => {
                  const lookup = qualityIssueVehicleLookup(row);
                  return <Button disabled={!lookup.key} onClick={() => onOpenVehicle(lookup.key, row.protocol)}>{lookup.label}</Button>;
                }
              }
            ]}
          />
        </Card>
        <Card
          title={<Space><span>车辆服务覆盖</span><Button size="small" onClick={() => onOpenVehicles(coverageFilters)}>查看全部车辆</Button></Space>}
          bordered
          style={{ marginTop: 16 }}
        >
          {coverageServiceStatusTitle ? (
            <div className="vp-scope-bar" style={{ marginBottom: 12 }}>
              <Tag color="blue">当前筛选：{coverageServiceStatusTitle}</Tag>
            </div>
          ) : null}
          <Form layout="horizontal" onSubmit={(values) => loadCoverage(values as Record<string, string>)} style={{ marginBottom: 12 }}>
            <Form.Input field="keyword" label="关键词" placeholder="VIN / 车牌 / 手机号 / OEM" style={{ width: 240 }} />
            <Form.Select field="coverage" label="来源覆盖" placeholder="全部" style={{ width: 130 }}>
              <Select.Option value="single">单源</Select.Option>
              <Select.Option value="multi">多源</Select.Option>
            </Form.Select>
            <Form.Select field="missingProtocol" label="缺失来源" placeholder="全部" style={{ width: 170 }} data-testid="dashboard-missing-protocol-filter">
              <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.Select field="online" label="在线" placeholder="全部" style={{ width: 130 }}>
              <Select.Option value="online">在线</Select.Option>
              <Select.Option value="offline">离线</Select.Option>
            </Form.Select>
            <Form.Select field="bindingStatus" label="绑定" placeholder="全部" style={{ width: 130 }}>
              <Select.Option value="bound">已绑定</Select.Option>
              <Select.Option value="unbound">未绑定</Select.Option>
            </Form.Select>
            <Form.Select field="serviceStatus" label="服务状态" placeholder="全部" style={{ width: 150 }} data-testid="dashboard-service-status-filter">
              <Select.Option value="healthy">服务正常</Select.Option>
              <Select.Option value="degraded">来源不完整</Select.Option>
              <Select.Option value="offline">车辆离线</Select.Option>
              <Select.Option value="no_data">暂无数据来源</Select.Option>
              <Select.Option value="identity_required">身份未绑定</Select.Option>
            </Form.Select>
            <Space>
              <Button htmlType="submit" theme="solid" type="primary">筛选</Button>
              <Button onClick={() => loadCoverage({})}>重置</Button>
            </Space>
          </Form>
          <Table
            loading={coverageLoading}
            pagination={false}
            rowKey="vin"
            dataSource={coverage}
            columns={[
              { title: '车牌', dataIndex: 'plate', width: 110 },
              { title: 'VIN', dataIndex: 'vin', width: 190 },
              {
                title: '来源证据',
                width: 300,
                render: (_: unknown, row: VehicleCoverageRow) => (
                  <SourceStatusTags sourceStatus={row.sourceStatus} protocols={row.protocols} lastSeen={row.lastSeen} />
                )
              },
              {
                title: '证据覆盖',
                width: 130,
                render: (_: unknown, row: VehicleCoverageRow) => sourceEvidenceText(row)
              },
              {
                title: '服务状态',
                width: 130,
                render: (_: unknown, row: VehicleCoverageRow) => {
                  const status = rowServiceStatus(row);
                  return <Tag color={status.color}>{status.label}</Tag>;
                }
              },
              {
                title: '来源一致性',
                width: 140,
                render: (_: unknown, row: VehicleCoverageRow) => sourceConsistencyAction(row, loadCoverage)
              },
              { title: '在线', width: 90, render: (_: unknown, row: VehicleCoverageRow) => <StatusTag status={row.online ? 'ok' : 'offline'} /> },
              { title: '绑定', width: 90, render: (_: unknown, row: VehicleCoverageRow) => <Tag color={row.bindingStatus === 'bound' ? 'green' : 'orange'}>{row.bindingStatus === 'bound' ? '已绑定' : '未绑定'}</Tag> },
              { title: '最后时间', dataIndex: 'lastSeen', width: 170 },
              { title: '操作', width: 110, render: (_: unknown, row: VehicleCoverageRow) => <Button onClick={() => onOpenVehicle(row.vin)}>车辆服务</Button> }
            ]}
          />
        </Card>
        <Row gutter={16} style={{ marginTop: 16 }}>
          <Col span={12}>
            <Card title="实时位置预览" bordered>
              <div className="vp-map" style={{ height: 260 }}>
                {locations.map((row, index) => (
                  <span
                    key={row.vin}
                    className="vp-map-dot"
                    title={`${row.plate} ${row.primaryProtocol}`}
                    style={{ left: `${18 + index * 13}%`, top: `${24 + (index % 4) * 15}%` }}
                  />
                ))}
              </div>
            </Card>
          </Col>
          <Col span={12}>
            <Card title="最新车辆" bordered>
              <Table
                pagination={false}
                rowKey="vin"
                dataSource={locations}
                columns={[
                  { title: '车牌', dataIndex: 'plate' },
                  { title: 'VIN', dataIndex: 'vin' },
                  {
                    title: '来源证据',
                    render: (_: unknown, row: VehicleRealtimeRow) => (
                      <Space spacing={4} wrap>
                        {row.protocols.map((protocol) => <Tag key={protocol} color={protocol === row.primaryProtocol ? 'blue' : 'grey'}>{protocol}</Tag>)}
                      </Space>
                    )
                  },
                  {
                    title: '服务状态',
                    render: (_: unknown, row: VehicleRealtimeRow) => {
                      const status = rowServiceStatus(row);
                      return <Tag color={status.color}>{status.label}</Tag>;
                    }
                  },
                  { title: '最后时间', dataIndex: 'lastSeen' },
                  { title: '操作', width: 110, render: (_: unknown, row: VehicleRealtimeRow) => <Button onClick={() => onOpenVehicle(row.vin, row.primaryProtocol)}>车辆服务</Button> }
                ]}
              />
            </Card>
          </Col>
        </Row>
      </Spin>
    </div>
  );
}
