import { useEffect, useMemo, useRef, useState } from 'react';

import {
  buildFleetTableViewModel,
  fleetStatusKind,
  type FleetAuthFilter,
  type FleetFilter,
  type FleetInstance,
  type FleetSortColumn,
  type FleetStatus,
  type SortDirection,
} from './fleet-table-view-model.js';
import type { InstanceDataSource } from '../instances/instance-crud.js';
import type {
  FleetMessageLoadState,
  FleetMessagesDataSource,
} from './fleet-messages-api-data-source.js';
import { loadFleetMessageSummaries } from './fleet-messages-api-data-source.js';
import {
  createOperationClient,
  type OperationClient,
} from '../operations/operation-client.js';
import { safeUiError } from '../ui/locale.js';

export interface FleetSnapshot {
  readonly instances: readonly FleetInstance[];
  readonly statuses: ReadonlyMap<string, FleetStatus>;
}
export interface FleetDataSource {
  load(
    signal?: AbortSignal,
    onPartial?: (snapshot: FleetSnapshot) => void,
  ): Promise<FleetSnapshot>;
}
export interface FleetPageProps {
  readonly dataSource?: FleetDataSource;
  readonly messagesDataSource?: FleetMessagesDataSource;
  readonly instanceDataSource?: InstanceDataSource;
  readonly initialData?: FleetSnapshot;
  readonly refreshSignal?: number;
  readonly operationClient?: OperationClient;
}
type FleetMessageState = FleetMessageLoadState;

const EMPTY_SNAPSHOT: FleetSnapshot = { instances: [], statuses: new Map() };
const STATUS_LABELS: Readonly<Record<string, string>> = {
  online: '在线',
  auth: '需要认证',
  offline: '离线',
  unknown: '未知',
};
const SORT_COLUMN_LABELS: Readonly<Record<FleetSortColumn, string>> = {
  name: '名称',
  status: '状态',
  latency: '延迟',
  version: '版本',
  capabilities: '能力',
  tags: '标签',
  freshness: '数据新鲜度',
  anomalies: '异常',
};
const CAPABILITY_LABELS: Readonly<Record<string, string>> = {
  overview: '概览',
  cellular: '蜂窝网络',
  'device-network': '设备网络',
  messages: '消息',
  calls: '通话',
  esim: 'eSIM',
  notifications: '通知',
  automation: '自动化',
  ota: 'OTA',
};

function capabilityLabel(value: string): string {
  return CAPABILITY_LABELS[value] ?? value;
}

const percent = (value: number | undefined): string =>
  value === undefined ? '暂未获取' : `${value.toFixed(1)}%`;
const temperature = (value: number | undefined): string =>
  value === undefined ? '暂未获取' : `${value.toFixed(1)} °C`;
const messageDirection = (value: string): string =>
  value === 'incoming' || value === 'received'
    ? '收到'
    : value === 'outgoing' || value === 'sent'
      ? '发送'
      : '未知方向';

const messageTime = (value: string): string => {
  const date = new Date(value);
  return Number.isNaN(date.getTime()) ? value : date.toLocaleString('zh-CN');
};

export function canonicalHttpOrigin(value: string): string | null {
  try {
    const url = new URL(value);
    if (url.protocol !== 'http:' && url.protocol !== 'https:') return null;
    url.username = '';
    url.password = '';
    return url.origin;
  } catch {
    return null;
  }
}

type BatchActionKind = 'service-restart' | 'system-reboot';
type BatchProgress = Readonly<{
  action: BatchActionKind;
  total: number;
  completed: number;
  succeeded: number;
  failed: number;
  message: string;
}>;

const SERVICE_RESTART = {
  operationId: 'postServiceRestart',
  parameterSchemaId: 'simadmin.58e2204.postServiceRestart.parameters.v1',
  title: '重启服务',
} as const;
const SYSTEM_REBOOT = {
  operationId: 'postSystemReboot',
  parameterSchemaId: 'simadmin.58e2204.postSystemReboot.parameters.v1',
  title: '系统重启',
  delaySeconds: 3,
} as const;

export function FleetPage({
  dataSource,
  messagesDataSource,
  instanceDataSource,
  initialData,
  refreshSignal = 0,
  operationClient,
}: FleetPageProps) {
  const [snapshot, setSnapshot] = useState<FleetSnapshot | null>(initialData ?? null);
  const [error, setError] = useState<string | null>(null);
  const [attempt, setAttempt] = useState(0);
  const [query, setQuery] = useState('');
  const [filter, setFilter] = useState<FleetFilter>('all');
  const [auth, setAuth] = useState<FleetAuthFilter>('all');
  const [capability, setCapability] = useState('');
  const [version, setVersion] = useState('');
  const [tag, setTag] = useState('');
  const [page, setPage] = useState(1);
  const [sort, setSort] = useState<{ column: FleetSortColumn; direction: SortDirection }>({
    column: 'name',
    direction: 'asc',
  });
  const [selectedIds, setSelectedIds] = useState<ReadonlySet<string>>(new Set());
  const [batchOpen, setBatchOpen] = useState(false);
  const [batchBusy, setBatchBusy] = useState(false);
  const [batchProgress, setBatchProgress] = useState<BatchProgress | null>(null);
  const [cardAction, setCardAction] = useState<{
    id: string;
    busy: boolean;
    message?: string;
    error?: string;
  } | null>(null);
  const [deleteId, setDeleteId] = useState<string>();
  const [deleteOwner, setDeleteOwner] = useState<Readonly<{ id: string; revision: number }>>();
  const [deleteConfirmation, setDeleteConfirmation] = useState('');
  const [deleteBusy, setDeleteBusy] = useState(false);
  const deleteRequestRef = useRef(0);
  const [deleteStatus, setDeleteStatus] =
    useState<Readonly<{ id: string; kind: 'success' | 'error'; message: string }>>();
  const messagesOwner = useRef(0);
  const [messageStates, setMessageStates] = useState<ReadonlyMap<string, FleetMessageState>>(
    new Map(),
  );
  const resolvedOperationClient = useMemo(
    () => operationClient ?? createOperationClient(),
    [operationClient],
  );

  useEffect(() => {
    if (initialData && refreshSignal === 0) {
      setSnapshot(initialData);
      setError(null);
      return;
    }
    if (!dataSource) {
      setSnapshot(EMPTY_SNAPSHOT);
      return;
    }
    let active = true;
    const controller = new AbortController();
    // Keep the last known instances visible while refreshing so the homepage stays interactive.
    setSnapshot((current) => current);
    setError(null);
    void dataSource
      .load(controller.signal, (partial) => {
        if (active) setSnapshot(partial);
      })
      .then(
        (data) => {
          if (active) setSnapshot(data);
        },
        (reason: unknown) => {
          if (!active) return;
          if (reason instanceof DOMException && reason.name === 'AbortError') return;
          setError('实例加载失败。');
        },
      );
    return () => {
      active = false;
      controller.abort();
    };
  }, [attempt, dataSource, initialData, refreshSignal]);

  useEffect(() => {
    const request = ++messagesOwner.current;
    const controller = new AbortController();
    const instances = snapshot?.instances;
    setMessageStates(new Map<string, FleetMessageState>());
    if (!messagesDataSource || !instances) return () => controller.abort();
    void loadFleetMessageSummaries(
      messagesDataSource,
      instances.map((instance) => instance.id),
      controller.signal,
    ).then((entries) => {
      if (request === messagesOwner.current && !controller.signal.aborted)
        setMessageStates(entries);
    });
    return () => controller.abort();
  }, [messagesDataSource, snapshot]);

  const model = useMemo(
    () =>
      buildFleetTableViewModel(snapshot?.instances ?? [], snapshot?.statuses ?? new Map(), {
        query,
        filter,
        auth,
        ...(capability ? { capability } : {}),
        ...(version ? { version } : {}),
        ...(tag ? { tag } : {}),
        sort,
        selectedIds,
        page,
      }),
    [auth, capability, filter, page, query, selectedIds, snapshot, sort, tag, version],
  );

  const fleetSummary = useMemo(() => {
    const statuses = [...(snapshot?.statuses.values() ?? [])];
    const online = statuses.filter(
      (status) => status.reachable && status.authenticated !== false,
    ).length;
    return {
      total: snapshot?.instances.length ?? 0,
      online,
      attention: (snapshot?.instances.length ?? 0) - online,
    };
  }, [snapshot]);

  const statusFacetCounts = useMemo(() => {
    const counts: Record<FleetFilter, number> = {
      all: snapshot?.instances.length ?? 0,
      online: 0,
      auth: 0,
      offline: 0,
      unknown: 0,
    };
    for (const instance of snapshot?.instances ?? []) {
      const kind = fleetStatusKind(snapshot?.statuses.get(instance.id));
      counts[kind] += 1;
    }
    return counts;
  }, [snapshot]);

  const activeFilterChips = useMemo(() => {
    const chips: Array<{ key: string; label: string; onClear: () => void }> = [];
    const trimmedQuery = query.trim();
    if (trimmedQuery) {
      chips.push({
        key: 'query',
        label: `搜索：${trimmedQuery}`,
        onClear: () => {
          setQuery('');
          setPage(1);
        },
      });
    }
    if (filter !== 'all') {
      chips.push({
        key: 'status',
        label: `状态：${STATUS_LABELS[filter] ?? filter}`,
        onClear: () => {
          setFilter('all');
          setPage(1);
        },
      });
    }
    if (auth !== 'all') {
      const authLabel =
        auth === 'authenticated' ? '已认证' : auth === 'required' ? '需要认证' : '未知';
      chips.push({
        key: 'auth',
        label: `认证：${authLabel}`,
        onClear: () => {
          setAuth('all');
          setPage(1);
        },
      });
    }
    if (capability) {
      chips.push({
        key: 'capability',
        label: `能力：${capabilityLabel(capability)}`,
        onClear: () => {
          setCapability('');
          setPage(1);
        },
      });
    }
    if (version) {
      chips.push({
        key: 'version',
        label: `版本：${version}`,
        onClear: () => {
          setVersion('');
          setPage(1);
        },
      });
    }
    if (tag) {
      chips.push({
        key: 'tag',
        label: `标签：${tag}`,
        onClear: () => {
          setTag('');
          setPage(1);
        },
      });
    }
    return chips;
  }, [auth, capability, filter, query, tag, version]);

  const advancedFilterCount = useMemo(
    () =>
      (auth !== 'all' ? 1 : 0) +
      (capability ? 1 : 0) +
      (version ? 1 : 0) +
      (tag ? 1 : 0),
    [auth, capability, tag, version],
  );

  useEffect(() => {
    if (page !== model.page) setPage(model.page);
  }, [model.page, page]);

  function resetPage(action: () => void): void {
    action();
    setPage(1);
  }

  function clearAllFilters(): void {
    setQuery('');
    setFilter('all');
    setAuth('all');
    setCapability('');
    setVersion('');
    setTag('');
    setPage(1);
  }
  function toggleOne(id: string, checked: boolean): void {
    setSelectedIds((current) => {
      const next = new Set(current);
      if (checked) next.add(id);
      else next.delete(id);
      return next;
    });
  }
  function toggleVisible(checked: boolean): void {
    setSelectedIds((current) => {
      const next = new Set(current);
      for (const row of model.rows) {
        if (checked) next.add(row.id);
        else next.delete(row.id);
      }
      return next;
    });
  }

  async function beginDelete(id: string): Promise<void> {
    const request = ++deleteRequestRef.current;
    setDeleteId(id);
    setDeleteOwner(undefined);
    setDeleteConfirmation('');
    setDeleteStatus(undefined);
    if (!instanceDataSource) {
      setDeleteStatus({ id, kind: 'error', message: '无法准备删除，请稍后重试。' });
      return;
    }
    setDeleteBusy(true);
    try {
      const current = await instanceDataSource.get(id);
      if (request !== deleteRequestRef.current) return;
      if (current.id !== id) throw new Error('owner mismatch');
      setDeleteOwner({ id: current.id, revision: current.revision });
    } catch {
      if (request === deleteRequestRef.current) {
        setDeleteStatus({ id, kind: 'error', message: '无法准备删除，请稍后重试。' });
      }
    } finally {
      if (request === deleteRequestRef.current) setDeleteBusy(false);
    }
  }

  async function remove(id: string): Promise<void> {
    if (!instanceDataSource || deleteOwner?.id !== id || deleteConfirmation !== id) return;
    setDeleteBusy(true);
    setDeleteStatus(undefined);
    try {
      await instanceDataSource.delete(id, deleteOwner.revision);
      setDeleteStatus({ id, kind: 'success', message: '删除请求已提交。' });
      setDeleteId(undefined);
      setDeleteConfirmation('');
    } catch {
      setDeleteStatus({ id, kind: 'error', message: '删除请求失败，请稍后重试。' });
    } finally {
      setDeleteBusy(false);
    }
  }

  function selectedTargets(): Array<{ instanceId: string; revision: number }> {
    const instances = snapshot?.instances ?? [];
    return model.selectedIds.flatMap((id) => {
      const instance = instances.find((item) => item.id === id);
      if (!instance || !instance.revision || instance.revision < 1) return [];
      return [{ instanceId: id, revision: instance.revision }];
    });
  }

  async function runOperation(
    kind: BatchActionKind,
    targets: ReadonlyArray<{ instanceId: string; revision: number }>,
  ): Promise<{ succeeded: number; failed: number }> {
    const catalog = await resolvedOperationClient.list({ pageSize: 100 });
    const op = kind === 'service-restart' ? SERVICE_RESTART : SYSTEM_REBOOT;
    const entry = catalog.items.find((item) => item.operationId === op.operationId);
    if (!entry || entry.parameterSchemaId !== op.parameterSchemaId)
      throw new Error('Operation is not available.');
    let succeeded = 0;
    let failed = 0;
    let completed = 0;
    for (const target of targets) {
      try {
        const prepared = await resolvedOperationClient.prepare({
          operationId: op.operationId,
          targets: [target],
          parameters: {
            parameterSchemaId: op.parameterSchemaId,
            fields:
              kind === 'system-reboot'
                ? [{ fieldId: 'delay_seconds', kind: 'number', value: SYSTEM_REBOOT.delaySeconds }]
                : [],
          },
        });
        const confirmed =
          typeof window === 'undefined'
            ? true
            : window.confirm(
                `${prepared.confirmationPrompt}
风险等级 ${prepared.risk}。确认继续？`,
              );
        if (!confirmed) {
          failed += 1;
        } else {
          const job = await resolvedOperationClient.execute(prepared.id);
          if (job.status === 'succeeded') succeeded += 1;
          else failed += 1;
        }
      } catch {
        failed += 1;
      }
      completed += 1;
      setBatchProgress({
        action: kind,
        total: targets.length,
        completed,
        succeeded,
        failed,
        message: `${op.title}进度 ${completed}/${targets.length}`,
      });
    }
    return { succeeded, failed };
  }

  async function runBatch(kind: BatchActionKind): Promise<void> {
    const targets = selectedTargets();
    if (targets.length === 0) {
      setBatchProgress({
        action: kind,
        total: 0,
        completed: 0,
        succeeded: 0,
        failed: 0,
        message: '所选实例缺少配置版本，请刷新后重试。',
      });
      return;
    }
    const title = kind === 'service-restart' ? SERVICE_RESTART.title : SYSTEM_REBOOT.title;
    if (
      typeof window !== 'undefined' &&
      !window.confirm(`将对 ${targets.length} 个实例执行「${title}」。此操作为高风险，确认继续？`)
    )
      return;
    setBatchBusy(true);
    setBatchProgress({
      action: kind,
      total: targets.length,
      completed: 0,
      succeeded: 0,
      failed: 0,
      message: `正在执行${title}…`,
    });
    try {
      const result = await runOperation(kind, targets);
      setBatchProgress({
        action: kind,
        total: targets.length,
        completed: targets.length,
        succeeded: result.succeeded,
        failed: result.failed,
        message: `${title}完成：成功 ${result.succeeded}，失败 ${result.failed}。`,
      });
    } catch (error) {
      setBatchProgress({
        action: kind,
        total: targets.length,
        completed: 0,
        succeeded: 0,
        failed: targets.length,
        message: safeUiError(error, `${title}失败，请稍后重试。`),
      });
    } finally {
      setBatchBusy(false);
    }
  }

  async function runCardAction(id: string, kind: BatchActionKind): Promise<void> {
    const instance = snapshot?.instances.find((item) => item.id === id);
    if (!instance?.revision || instance.revision < 1) {
      setCardAction({ id, busy: false, error: '缺少配置版本，请刷新后重试。' });
      return;
    }
    const title = kind === 'service-restart' ? SERVICE_RESTART.title : SYSTEM_REBOOT.title;
    if (
      typeof window !== 'undefined' &&
      !window.confirm(`将对该实例执行「${title}」。此操作为高风险，确认继续？`)
    )
      return;
    setCardAction({ id, busy: true, message: `正在${title}…` });
    try {
      const result = await runOperation(kind, [{ instanceId: id, revision: instance.revision }]);
      setCardAction({
        id,
        busy: false,
        message:
          result.succeeded === 1
            ? `${title}已提交成功。`
            : `${title}失败，请稍后重试。`,
        ...(result.failed === 1 ? { error: `${title}失败，请稍后重试。` } : {}),
      });
    } catch (error) {
      setCardAction({
        id,
        busy: false,
        error: safeUiError(error, `${title}失败，请稍后重试。`),
      });
    }
  }

  const selectFilter = (
    label: string,
    value: string,
    setValue: (value: string) => void,
    choices: readonly string[],
    allLabel: string,
    displayChoice: (choice: string) => string = (choice) => choice,
  ) => (
    <label>
      <span>{label}</span>
      <select
        value={value}
        onChange={(event) => resetPage(() => setValue(event.currentTarget.value))}
      >
        <option value="">{allLabel}</option>
        {choices.map((choice) => (
          <option key={choice} value={choice}>
            {displayChoice(choice)}
          </option>
        ))}
      </select>
    </label>
  );

  return (
    <section className="fleet-panel" aria-labelledby="fleet-title">
      <div className="fleet-heading">
        <div>
          <h1 id="fleet-title">实例舰队</h1>
          <p>资源优先总览，查找并管理全部 SimAdmin 实例。</p>
        </div>
        <div className="fleet-actions">
          <a className="primary-action" href="/instances/new">
            添加实例
          </a>
          <span className="selection-summary" aria-live="polite">
            已选择 {model.selectedIds.length} 项
          </span>
          <button
            type="button"
            disabled={model.selectedIds.length === 0}
            onClick={() => setBatchOpen((open) => !open)}
          >
            批量操作
          </button>
        </div>
      </div>
      {snapshot ? (
        <section className="fleet-status-summary" aria-label="实例状态摘要">
          <div>
            <span>实例总数</span>
            <strong>{fleetSummary.total}</strong>
          </div>
          <div>
            <span>在线</span>
            <strong>{fleetSummary.online}</strong>
          </div>
          <div>
            <span>需处理</span>
            <strong>{fleetSummary.attention}</strong>
          </div>
        </section>
      ) : null}
      {batchOpen ? (
        <div className="batch-entry" role="region" aria-label="批量操作入口">
          <div className="batch-entry-copy">
            <strong>批量操作</strong>
            <p>已选择 {model.selectedIds.length} 项。重启将逐个实例安全确认后执行。</p>
          </div>
          <div className="batch-entry-actions" role="group" aria-label="批量重启操作">
            <button
              type="button"
              disabled={batchBusy || model.selectedIds.length === 0}
              onClick={() => void runBatch('service-restart')}
            >
              批量重启服务
            </button>
            <button
              type="button"
              className="danger-button"
              disabled={batchBusy || model.selectedIds.length === 0}
              onClick={() => void runBatch('system-reboot')}
            >
              批量系统重启
            </button>
          </div>
          {batchProgress ? (
            <p role="status" className="batch-progress">
              {batchProgress.message}
            </p>
          ) : null}
        </div>
      ) : null}
      <div className="fleet-toolbar" role="search" aria-label="实例搜索与筛选">
        <div className="fleet-search-row">
          <label className="fleet-search-field">
            <span className="visually-hidden">搜索实例</span>
            <span className="fleet-search-glyph" aria-hidden="true">
              ⌕
            </span>
            <input
              type="search"
              value={query}
              onChange={(event) => resetPage(() => setQuery(event.currentTarget.value))}
              placeholder="搜索名称、ID、标签、源地址…"
              autoComplete="off"
              spellCheck={false}
            />
            {query ? (
              <button
                type="button"
                className="fleet-search-clear"
                aria-label="清除搜索"
                onClick={() => resetPage(() => setQuery(''))}
              >
                清除
              </button>
            ) : null}
          </label>
        </div>
        <div className="fleet-status-chips" role="group" aria-label="按状态筛选">
          {(
            [
              ['all', '全部'],
              ['online', '在线'],
              ['auth', '需认证'],
              ['offline', '离线'],
              ['unknown', '未知'],
            ] as const
          ).map(([value, label]) => (
            <button
              key={value}
              type="button"
              className={`fleet-status-chip${filter === value ? ' is-active' : ''}`}
              aria-pressed={filter === value}
              onClick={() => resetPage(() => setFilter(value))}
            >
              <span>{label}</span>
              <strong>{statusFacetCounts[value]}</strong>
            </button>
          ))}
        </div>
        <div className="fleet-toolbar-meta">
          <p className="fleet-result-count" aria-live="polite">
            显示 <strong>{model.filteredCount}</strong> / {model.totalCount}
            {model.pageCount > 1 ? ` · 第 ${model.page}/${model.pageCount} 页` : null}
          </p>
          <div className="fleet-toolbar-controls">
            <label className="fleet-sort-field">
              <span className="visually-hidden">排序</span>
              <select
                aria-label="排序"
                value={`${sort.column}:${sort.direction}`}
                onChange={(event) => {
                  const [column, direction] = event.currentTarget.value.split(':') as [
                    FleetSortColumn,
                    SortDirection,
                  ];
                  resetPage(() => setSort({ column, direction }));
                }}
              >
                {(Object.keys(SORT_COLUMN_LABELS) as FleetSortColumn[]).flatMap((column) => [
                  <option key={`${column}:asc`} value={`${column}:asc`}>
                    {SORT_COLUMN_LABELS[column]} · 升序
                  </option>,
                  <option key={`${column}:desc`} value={`${column}:desc`}>
                    {SORT_COLUMN_LABELS[column]} · 降序
                  </option>,
                ])}
              </select>
            </label>
            <div className="fleet-select-all" role="group" aria-label="本页选择">
              <button
                type="button"
                onClick={() => toggleVisible(true)}
                disabled={model.rows.length === 0}
              >
                全选本页
              </button>
              <button
                type="button"
                onClick={() => toggleVisible(false)}
                disabled={model.selectedIds.length === 0}
              >
                清空选择
              </button>
            </div>
          </div>
        </div>
        {activeFilterChips.length > 0 ? (
          <div className="fleet-active-filters" aria-label="当前筛选条件">
            {activeFilterChips.map((chip) => (
              <button
                key={chip.key}
                type="button"
                className="fleet-active-chip"
                onClick={chip.onClear}
                aria-label={`移除筛选 ${chip.label}`}
              >
                <span>{chip.label}</span>
                <span aria-hidden="true">×</span>
              </button>
            ))}
            <button type="button" className="fleet-clear-filters" onClick={clearAllFilters}>
              清除全部筛选
            </button>
          </div>
        ) : null}
        <details className="fleet-advanced-filters">
          <summary>
            更多筛选
            {advancedFilterCount > 0 ? (
              <span className="fleet-advanced-count" aria-label={`已启用 ${advancedFilterCount} 项`}>
                {advancedFilterCount}
              </span>
            ) : null}
          </summary>
          <div className="fleet-advanced-filter-grid">
            <label>
              <span>认证</span>
              <select
                value={auth}
                onChange={(event) =>
                  resetPage(() => setAuth(event.currentTarget.value as FleetAuthFilter))
                }
              >
                <option value="all">全部认证状态</option>
                <option value="authenticated">已认证</option>
                <option value="required">需要认证</option>
                <option value="unknown">未知</option>
              </select>
            </label>
            {selectFilter(
              '能力',
              capability,
              setCapability,
              model.facets.capabilities,
              '全部能力',
              capabilityLabel,
            )}
            {selectFilter('版本', version, setVersion, model.facets.versions, '全部版本')}
            {selectFilter('标签', tag, setTag, model.facets.tags, '全部标签')}
          </div>
        </details>
      </div>

      {!snapshot && !error ? (
        <p role="status" aria-label="实例加载状态">
          正在加载实例列表…
        </p>
      ) : null}
      {error ? (
        <div className="state-panel state-error" role="alert">
          <p>无法加载实例。{error}</p>
          <button type="button" onClick={() => setAttempt((value) => value + 1)}>
            重试加载实例
          </button>
        </div>
      ) : null}
      {snapshot && model.emptyReason ? (
        <div className="state-panel">
          {model.emptyReason === 'config' ? (
            <>
              <p>尚未配置实例。</p>
              <a className="primary-action" href="/instances/new">
                添加实例
              </a>
            </>
          ) : null}
          {model.emptyReason === 'search' ? <p>没有实例符合搜索与筛选条件。</p> : null}
          {model.emptyReason === 'filter' ? <p>没有实例符合当前筛选条件。</p> : null}
        </div>
      ) : null}
      {snapshot && model.rows.length > 0 ? (
        <>
          <section className="fleet-card-section" aria-label="实例卡片">
            <div className="fleet-card-grid">
              {model.rows.map((row) => (
                <article
                  className={`fleet-card${row.selected ? ' is-selected' : ''}`}
                  aria-label={`${row.displayName} 实例概览`}
                  key={row.id}
                >
                  <header>
                    <label className="fleet-card-select touch-target">
                      <input
                        type="checkbox"
                        aria-label={`选择 ${row.displayName}`}
                        checked={row.selected}
                        onChange={(event) => toggleOne(row.id, event.currentTarget.checked)}
                      />
                    </label>
                    <a
                      className="fleet-card-entry"
                      href={`/instances/${encodeURIComponent(row.id)}/overview`}
                      aria-label={`打开 ${row.displayName} 实例仪表盘`}
                    >
                      <h2>{row.displayName}</h2>
                      <code>{row.id}</code>
                      <span className="fleet-card-entry-label">进入仪表盘</span>
                    </a>
                    <span className={`status status-${row.statusKind}`}>
                      {STATUS_LABELS[row.statusKind]}
                    </span>
                  </header>
                  {(() => {
                    const origin = canonicalHttpOrigin(row.instance.url);
                    return (
                      <p className="fleet-card-origin" aria-label={`${row.displayName} 源地址`}>
                        {origin ?? '源地址无效'}
                      </p>
                    );
                  })()}
                  {row.anomalies.length > 0 ? (
                    <p className="fleet-card-anomalies" aria-label={`${row.displayName} 异常`}>
                      {row.anomalies.join(', ')}
                    </p>
                  ) : null}
                  <dl className="fleet-card-metrics">
                    <div className="fleet-card-phone">
                      <dt>手机号</dt>
                      <dd>
                        {row.status?.summary?.resources?.phoneNumbers?.join('、') || '暂未获取'}
                      </dd>
                    </div>
                    <div>
                      <dt>CPU</dt>
                      <dd>
                        {row.status?.summary?.resources?.cpuPercent === undefined ? (
                          '暂未获取'
                        ) : (
                          <>
                            <meter
                              min="0"
                              max="100"
                              value={row.status.summary.resources.cpuPercent}
                              aria-label="CPU 使用率"
                            />
                            {percent(row.status.summary.resources.cpuPercent)}
                          </>
                        )}
                      </dd>
                    </div>
                    <div>
                      <dt>内存</dt>
                      <dd>
                        {row.status?.summary?.resources?.memoryPercent === undefined ? (
                          '暂未获取'
                        ) : (
                          <>
                            <meter
                              min="0"
                              max="100"
                              value={row.status.summary.resources.memoryPercent}
                              aria-label="内存使用率"
                            />
                            {percent(row.status.summary.resources.memoryPercent)}
                          </>
                        )}
                      </dd>
                    </div>
                    <div>
                      <dt>最高温度</dt>
                      <dd>{temperature(row.status?.summary?.resources?.maxTemperatureCelsius)}</dd>
                    </div>
                  </dl>
                  {row.capabilities.length > 0 ? (
                    <div className="capability-tags" aria-label="能力">
                      {row.capabilities.map((item) => (
                        <span key={item}>{capabilityLabel(item)}</span>
                      ))}
                    </div>
                  ) : null}
                  <section className="fleet-card-sms" aria-label="最近短信">
                    <h3>最近短信</h3>
                    {messageStates.get(row.id)?.unavailable ? (
                      <p className="fleet-card-sms-empty">短信暂不可用</p>
                    ) : messageStates.get(row.id)?.latest ? (
                      <dl>
                        <div>
                          <dt>方向</dt>
                          <dd>{messageDirection(messageStates.get(row.id)!.latest!.direction)}</dd>
                        </div>
                        <div>
                          <dt>号码</dt>
                          <dd>{messageStates.get(row.id)!.latest!.phoneNumber}</dd>
                        </div>
                        <div>
                          <dt>时间</dt>
                          <dd>{messageTime(messageStates.get(row.id)!.latest!.timestamp)}</dd>
                        </div>
                      </dl>
                    ) : (
                      <p className="fleet-card-sms-empty">暂无短信</p>
                    )}
                  </section>
                  <div
                    className="fleet-card-actions fleet-card-admin-actions"
                    role="group"
                    aria-label="实例管理操作"
                  >
                    <button
                      type="button"
                      aria-label={`重启服务 ${row.displayName}`}
                      disabled={cardAction?.id === row.id && cardAction.busy}
                      onClick={() => void runCardAction(row.id, 'service-restart')}
                    >
                      重启服务
                    </button>
                    <button
                      type="button"
                      className="danger-button"
                      aria-label={`系统重启 ${row.displayName}`}
                      disabled={cardAction?.id === row.id && cardAction.busy}
                      onClick={() => void runCardAction(row.id, 'system-reboot')}
                    >
                      系统重启
                    </button>
                    <a
                      href={`/settings/instances/${encodeURIComponent(row.id)}`}
                      aria-label={`编辑 ${row.displayName}`}
                    >
                      编辑
                    </a>
                    <button
                      type="button"
                      className="danger-button"
                      aria-label={`删除 ${row.displayName}`}
                      onClick={() => void beginDelete(row.id)}
                    >
                      删除
                    </button>
                  </div>
                  {cardAction?.id === row.id ? (
                    <p
                      role={cardAction.error ? 'alert' : 'status'}
                      className={cardAction.error ? 'card-operation-error' : 'card-operation-success'}
                    >
                      {cardAction.error ?? cardAction.message}
                    </p>
                  ) : null}
                  {deleteId === row.id ? (
                    <div className="card-delete-confirmation">
                      <p>删除后无法撤销。</p>
                      <label>
                        输入 {row.id} 以确认删除
                        <input
                          value={deleteConfirmation}
                          onChange={(event) => setDeleteConfirmation(event.currentTarget.value)}
                        />
                      </label>
                      <div className="fleet-card-actions">
                        <button
                          type="button"
                          className="danger-button"
                          disabled={
                            deleteBusy ||
                            deleteOwner?.id !== row.id ||
                            deleteConfirmation !== row.id
                          }
                          aria-label={`确认删除 ${row.displayName}`}
                          onClick={() => void remove(row.id)}
                        >
                          确认删除
                        </button>
                        <button
                          type="button"
                          onClick={() => {
                            setDeleteId(undefined);
                            setDeleteConfirmation('');
                            setDeleteStatus(undefined);
                          }}
                        >
                          取消
                        </button>
                      </div>
                    </div>
                  ) : null}
                  {deleteStatus?.id === row.id ? (
                    <p
                      role={deleteStatus.kind === 'error' ? 'alert' : 'status'}
                      className={
                        deleteStatus.kind === 'error'
                          ? 'card-operation-error'
                          : 'card-operation-success'
                      }
                    >
                      {deleteStatus.message}
                    </p>
                  ) : null}
                </article>
              ))}
            </div>
          </section>
          <nav className="pagination" aria-label="实例分页">
            <button
              type="button"
              aria-label="上一页"
              disabled={model.page === 1}
              onClick={() => setPage((value) => value - 1)}
            >
              上一页
            </button>
            <span>
              第 {model.page} 页，共 {model.pageCount} 页
            </span>
            <button
              type="button"
              aria-label="下一页"
              disabled={model.page === model.pageCount}
              onClick={() => setPage((value) => value + 1)}
            >
              下一页
            </button>
          </nav>
        </>
      ) : null}
    </section>
  );
}
