/**
 * 拓扑图：基于 GET /tenant/device 返回的设备数组，构造 PisellFloorMapLayout 所需的
 * `FloorMapViewConfig` + `dataSources`，无连线、按 `type_code` 动态生成 elementKinds、
 * 用近似正方形网格自动布局。**不依赖 shop floor-plan**。
 */
import type { FloorMapDataSources, FloorMapEdge, FloorMapElementKindCategory, FloorMapElementKindConfig, FloorMapSceneElement, FloorMapViewConfig } from '@pisell/materials';
/** 接口返回里单台设备（局部字段，仅用本视图实际用到的） */
export interface RawTopologyDevice {
    id: number | string;
    type_code?: string | null;
    type_kind?: string | null;
    model_code?: string | null;
    number?: string | null;
    status?: string | null;
    link?: string | null;
    /** 设备上报信息（与 saasDevice devicePlanning 的 `device.data` 结构一致） */
    data?: Record<string, unknown> | null;
    name?: Record<string, string | null> | string | null;
    type?: {
        name?: Record<string, string | null> | null;
    } | null;
    model?: {
        name?: Record<string, string | null> | null;
        code?: string | null;
    } | null;
    /**
     * 关联工作区（`with=workarea` 时返回）。拓扑里把 workarea 当作「分区/选区」：
     * 同一 workarea 的设备聚成一个选区（虚线框），自动排列时分区内独立布局/连线。
     * `sort` 用于分区之间的稳定排序；`workarea_id=0` / `workarea=null` 视为「无分区」。
     */
    workarea?: {
        id?: number;
        name?: Record<string, string | null> | null;
        sort?: number | null;
    } | null;
    workarea_id?: number | null;
}
export { TOPOLOGY_DEVICE_KIND_PREFIX } from './topologyFloorPlanConstants';
/**
 * 静态 `type_code` 枚举：拓扑图所有可识别的设备类型。
 * 接口返回里若出现未列入的 `type_code`，会落到 `<prefix>unknown` 兜底 kind。
 */
export declare const TOPOLOGY_DEVICE_TYPE_CODES: readonly ["pos", "receipt_printer", "label_printer", "switch", "info_display", "terminal", "chenlei", "test1"];
export declare type TopologyDeviceTypeCode = (typeof TOPOLOGY_DEVICE_TYPE_CODES)[number];
/** 拓扑设备所有 kind value（含 unknown 兜底） */
export declare const TOPOLOGY_DEVICE_KIND_VALUES: string[];
/** 从 HTTP 封装响应中提取 `data` 数组（兼容 `{data: [...]}` / 直接数组） */
export declare function extractRawDeviceList(response: unknown): RawTopologyDevice[];
/** 接口返回里单条连接（局部字段，仅用本视图实际用到的） */
export interface RawTopologyDeviceConnection {
    id: number | string;
    source_device_id: number | string;
    target_device_id: number | string;
    status?: string | null;
    config?: {
        connection_ip?: string | null;
        connection_type?: string | null;
        connection_method?: string | null;
    } | null;
}
/** 从 HTTP 封装响应中提取设备连接 `data` 数组 */
export declare function extractRawDeviceConnectionList(response: unknown): RawTopologyDeviceConnection[];
/**
 * 设备 IP：与 devicePlanning 详情「网络 → 本地 IP」同源（`data.network.local_ip`）。
 */
export declare function deviceIpAddress(device: RawTopologyDevice): string | undefined;
/** 设备数组 → `dataSources.devices`（PisellFloorMapLayout 需要的扁平 record 形式） */
export declare function buildTopologyDeviceDataSources(rawDevices: RawTopologyDevice[]): FloorMapDataSources;
/**
 * 基于固定 `TOPOLOGY_DEVICE_TYPE_CODES` 枚举生成图元种类，**不依赖**接口响应。
 * 接口若返回新的 type_code，运行时会落到 `unknown` 兜底 kind（见 `buildTopologyConnectionAwareSceneElements`）。
 */
export declare function buildTopologyDeviceElementKinds(displayLocale?: string): {
    categories: FloorMapElementKindCategory[];
    kinds: FloorMapElementKindConfig[];
    /** type_code → kind value（落点时使用） */
    typeCodeToKind: Map<string, string>;
};
/**
 * 计算「锚点设备所在连通分量」的设备 id 集合（含锚点自身）。
 *
 * 用于设备端「聚焦」视图：只展示当前设备以及与它（直接或间接）连通的整条链路。
 * 与全量布局复用同一套邻接表 / 连通分量逻辑，避免另起平行的连接推断。
 *
 * @param anchorId 当前设备 id（如设备端 `app.storage.iotDevice.id`）
 * @returns 锚点所在连通分量的设备 id 集合；锚点不在设备列表里时返回 `null`
 *          （调用方应据此回退到全量视图）
 */
export declare function collectConnectedComponentDeviceIds(rawDevices: RawTopologyDevice[], rawConnections: RawTopologyDeviceConnection[], anchorId: string): Set<string> | null;
/**
 * 连接优先布局：把所有设备当成一整块做 connection-aware 布局并生成 sceneElement。
 * 不区分分区，整体居左上、留 PADDING 边距。
 */
export declare function buildTopologyConnectionAwareSceneElements(rawDevices: RawTopologyDevice[], rawConnections: RawTopologyDeviceConnection[], typeCodeToKind: Map<string, string>): {
    sceneElements: FloorMapSceneElement[];
};
/**
 * 分区（workarea）感知布局：
 * - 按 `workarea` 把设备分组；同组设备聚成一个**选区虚线框**（取 workarea 名）。
 * - 每个分区**内部**单独跑 connection-aware 布局，连线逻辑只用「两端都在本分区」的连接，
 *   保证同分区设备贴在一起、连线不跨区乱穿。
 * - 各分区块按行打包（超出最大行宽换行），分区之间留 `GROUP_GAP`。
 * - 「无分区」设备同样独立成块，但不画虚线框。
 *
 * 跨分区的连接仍由 {@link buildTopologyEdgesFromConnections} 统一画成边（连线本身不丢）。
 */
export declare function buildTopologyWorkareaGroupedSceneElements(rawDevices: RawTopologyDevice[], rawConnections: RawTopologyDeviceConnection[], typeCodeToKind: Map<string, string>): {
    sceneElements: FloorMapSceneElement[];
};
export declare function getConnectionTypeStyle(connectionType: string | null | undefined): {
    color?: string;
    dashed?: boolean;
};
/**
 * connection 数组 → `FloorMapEdge[]`。
 * - 仅保留两端 device 都在当前 device 数组里的连接（避免悬空 edge）。
 * - 锚点强制走 top/bottom：source 所在层在 target 上方时 source.bottom→target.top；
 *   反之 source.top→target.bottom；同层时也用 top↔bottom，避免出现左右锚点连线。
 */
export declare function buildTopologyEdgesFromConnections(rawConnections: RawTopologyDeviceConnection[], rawDevices: RawTopologyDevice[]): FloorMapEdge[];
/**
 * 一站式：原始设备数组 + 连接数组 → 阅读态 `FloorMapViewConfig`。
 * `rawConnections` 未传或为空时不渲染连线，仅展示节点。
 *
 * 此函数只做「全量自动布局」，不考虑已保存的 floor-plan 数据。需要做对账请用
 * {@link reconcileTopologyView}。
 */
export declare function buildTopologyFloorMapConfigFromDevices(rawDevices: RawTopologyDevice[], rawConnections?: RawTopologyDeviceConnection[], displayLocale?: string): {
    config: FloorMapViewConfig;
    dataSources: FloorMapDataSources;
};
export interface ReconcileTopologyViewParams {
    rawDevices: RawTopologyDevice[];
    rawConnections: RawTopologyDeviceConnection[];
    /** 已保存的 sceneElements；首次进来传 undefined / 空数组 */
    savedSceneElements?: FloorMapSceneElement[];
    /** 已保存的 edges；用于复用 routing snapshot（其余字段从连接接口刷新） */
    savedEdges?: FloorMapEdge[];
    /** 画布 Tab / 分类等展示语言（与引擎 umi_locale 一致） */
    displayLocale?: string;
}
export interface ReconcileTopologyViewResult {
    config: FloorMapViewConfig;
    dataSources: FloorMapDataSources;
    /** 此次 reconcile 新增的设备 id（首次进来 = 全部设备） */
    addedDeviceIds: string[];
    /** 已保存里 API 已经没有的 instanceId（ghost），渲染时按下线状态展示 */
    ghostInstanceIds: string[];
    /** 已保存里 API 已经没有的设备 id（ghostInstanceIds 反向解析后） */
    ghostDeviceIds: string[];
    /** 已存在并被保留位置的设备 id（debug 用） */
    keptDeviceIds: string[];
}
/**
 * 接入 floor-plan 的核心：把「已保存布局」「设备列表」「连接列表」对账成最终 view config。
 *
 * 规则：
 * - 设备同时在 API + 已保存里：保留位置/尺寸，用 API 数据刷新 elementKind / name
 * - 设备只在 API（新设备）：放到「新增区」auto-layout
 * - 设备只在已保存（接口已下线，ghost）：保留 sceneElement，由 UI 侧渲染下线样式
 * - 边：按当前 connections 接口重建；保留 savedEdges 的 routing snapshot（按 id 配对）
 *
 * 当 `savedSceneElements` 为空时退化为整体 auto-layout，等价于 `buildTopologyFloorMapConfigFromDevices`。
 */
export declare function reconcileTopologyView(params: ReconcileTopologyViewParams): ReconcileTopologyViewResult;
