import type { ReactNode, Key, ComponentType, Ref, CSSProperties } from 'react';
import type { PisellFloorMapLayoutProps, PisellFloorMapLayoutRef, FloorMapDataSources, FloorMapLayoutContextValue } from '../pisellFloorMapLayout/types';
import type { TableProps } from 'antd';
import type { CalendarPersistContextValue } from './shellFrame/Calendar/calendarPersistGuard';
import type { TimeRangeOption } from '../pisellTimeNavigator/types';
import type { VenueWallAppearanceTheme, VenueWallStatusToneOverrides } from './shellFrame/ResourceWall/venueWallUtils';
/**
 * 布局类型：一种 layout 对应一种「视图的集合」
 * - grid: 搜索 + 表格 + 分页
 * - card: 搜索 + 卡片列表 + 分页
 * 后续可扩展 list、kanban 等
 */
export declare type RecordBoardLayoutType = 'grid' | 'card';
/**
 * 列表区布局变体：`phone` 时 Grid 收紧列宽与单元格 padding，ToolBar 可配合 compact-narrow。
 * 与业务组件 `variant="phone"` 对齐，由宿主显式传入 RecordBoard。
 */
export declare type RecordBoardLayoutVariant = 'default' | 'phone';
/**
 * 列字段类型：对应 Pisell 表单组件，传入列 type 时用该组件自动渲染列（只读）与筛选项（编辑）
 */
export declare type RecordBoardFieldType = 'singleLineText' | 'longText' | 'email' | 'phone' | 'url' | 'number' | 'currency' | 'percent' | 'rating' | 'singleSelect' | 'multipleSelect' | 'dateTime';
/** 无 type 时筛选项可传入自定义组件，需支持 value / onChange 以接入 Form */
export declare type RecordBoardFilterComponentProps = {
    value?: any;
    onChange?: (value: any) => void;
    [key: string]: any;
};
/** 选项格式，用于 getOptions / options；color 用于只读态 Tag 展示 */
export declare type RecordBoardOptionItem = {
    label: string;
    value: any;
    /** 只读态 Tag 颜色，如 '#e6f7ff' 或 antd 预设 'blue' */
    color?: string;
};
/** 同步或异步返回选项列表，singleSelect/multipleSelect 的 fieldProps.getOptions 或 filter.getOptions 使用 */
export declare type RecordBoardGetOptions = (() => RecordBoardOptionItem[]) | (() => Promise<RecordBoardOptionItem[]>);
/** 列筛选配置：不传列 type 时使用。可配置 type + options/props，或传入 component（接收 value/onChange）。 */
export interface RecordBoardColumnFilterConfig {
    type?: 'single' | 'input' | 'datePicker' | 'rangePicker' | 'rangePickerNew' | 'search';
    label?: string;
    options?: RecordBoardOptionItem[];
    /** 同步或异步获取选项，与 options 二选一；支持 singleSelect/multipleSelect 及无 type 时 type:'single' */
    getOptions?: RecordBoardGetOptions;
    props?: Record<string, any>;
    /** 放在快速筛选(true)还是高级筛选(false) */
    quickFilter?: boolean;
    /** 无 type 时可用：自定义筛选组件，由 Form 注入 value/onChange */
    component?: ComponentType<RecordBoardFilterComponentProps>;
}
/**
 * RecordBoard 列类型扩展（与 antd Table Column 兼容，仅增加可选字段）。
 *
 * 有 type（如 singleLineText）时：
 * - 表格：自动用对应 Pisell 组件只读渲染；传入 render 则优先使用（覆盖）。
 * - 筛选：自动用对应组件编辑态；传入 filter（type 或 component）则优先使用（覆盖）。
 * - 排序：自动从组件 SortOptions 派生；传入 sort 则优先使用（覆盖）。
 *
 * 无 type 时：
 * - 表格：无 render 则纯文本；可自定义 render。
 * - 筛选：需配置 filterable + filter（type 或 component，component 需 value/onChange）。
 * - 排序：需配置 sortable + sort（type 或 getSortItems）。
 */
export interface RecordBoardColumnType<RecordType = any> {
    title?: ReactNode;
    dataIndex?: string | string[];
    key?: string;
    width?: number | string;
    align?: 'left' | 'right' | 'center';
    fixed?: 'left' | 'right' | boolean;
    ellipsis?: boolean;
    /** 列渲染；无 type 时必靠此或默认纯文本；有 type 时可选，传入则覆盖自动派生 */
    render?: (value: any, record: RecordType, index: number) => ReactNode;
    /** 其他 antd 列属性 */
    [key: string]: any;
    /** 字段类型；传入则表格/筛选/排序自动派生，可被 render/filter/sort 覆盖 */
    type?: RecordBoardFieldType;
    /**
     * 传给 Pisell 组件的额外 props（type 存在且未用 filter/render 覆盖时生效）。
     * singleSelect/multipleSelect 时支持 options 或 getOptions（同步/异步返回选项列表）。
     */
    fieldProps?: Record<string, any>;
    /** 是否参与筛选；false 时不生成筛项；有 type 时默认 true */
    filterable?: boolean;
    /** 筛选配置；无 type 时必传 type 或 component；有 type 时可选，传入则覆盖自动派生 */
    filter?: RecordBoardColumnFilterConfig;
    /** 是否参与排序；false 时不生成排序项；有 type 时默认 true */
    sortable?: boolean;
    /**
     * 排序配置；无 type 时需 sortable + sort；有 type 时可选，传入则覆盖自动派生。
     * - type：内置排序子项（string/number/option 等）。
     * - getSortItems：(fieldKey) => [{ key, label }]。
     */
    sort?: {
        type?: 'date' | 'string' | 'number' | 'option';
        label?: string;
        isHidden?: boolean;
        /** 自定义排序子项，优先于 type；fieldKey 为列 key/dataIndex */
        getSortItems?: (fieldKey: string) => Array<{
            key: string;
            label: string;
        }>;
    };
    /** 默认隐藏该列，与 grid.defaultHiddenColumnKeys 合并参与初始化列显隐 */
    hidden?: boolean;
    /**
     * 当开启 grid.collapseUniformColumns 时，用此函数从 (value, record) 得到用于比较的值；
     * 返回 string 或 number 时参与全等比较，返回 null/undefined 则该列不参与折叠。
     * 未传则用 dataIndex 取值；与 render 类似，便于从复杂数据中抽取值再判断是否全同。
     */
    uniformCompare?: (value: any, record: any) => string | number | null | undefined;
    /**
     * 当开启 grid.collapseUniformColumns 时，为 false 则该列即使全列同值/全空也不折叠、不进入总结区；默认 true。
     */
    collapseWhenUniform?: boolean;
}
/**
 * 分页状态（与容器内部一致）
 */
export interface RecordBoardPaginationState {
    pageNumber: number;
    pageSize: number;
}
/**
 * 列表请求结果（与 dataSource / useRequest 等对齐）
 */
export interface RecordBoardListResult {
    list: any[];
    count?: number;
    total?: number;
}
/** ShellFrame 内容区：表格、平面图、日历或大屏资源墙（与 GridLayout 同级切换） */
export declare type RecordBoardBodyView = 'grid' | 'floorMap' | 'calendar' | 'resourceWall';
/** 日历 Y 轴资源行（与 BookingCalendarDemo 中 court 对齐） */
export interface RecordBoardCalendarResource {
    id: string;
    name: string;
    /** 分组标签，用于筛选 chip（如区域 / 表单 code） */
    groupType?: string;
}
/**
 * 日历格内预约条数据（与 BookingCalendarDemo 内部 booking 形状一致）；
 * `raw` 为宿主预约行时，业务层可用其打开详情弹窗。
 */
export interface RecordBoardCalendarBookingLike {
    id: string;
    courtId: string;
    /** 起始营业日 `YYYY-MM-DD` */
    date: string;
    /** 起始日小时（0–24，含 .5 半格） */
    startHour: number;
    /** 结束日小时（0–24）；当 `endDate === date`（或未填）时即单日 booking */
    endHour: number;
    /**
     * 结束营业日 `YYYY-MM-DD`；不填或与 `date` 相同表示单日 booking。
     * 跨日预约必须填本字段，日历会按 `[date date+startHour, endDate endDate+endHour]` 整段连续渲染，
     * 不再按天切片成多条 item。
     */
    endDate?: string;
    name: string;
    kind: 'booking' | 'block';
    phone?: string;
    statusTag?: string;
    note?: string;
    blockBy?: string;
    blockedAt?: string;
    raw?: Record<string, unknown>;
}
/** 日视图时间轴上的一条预约 overlay（与 BookingCalendarDemo 内部结构对齐） */
export interface RecordBoardCalendarDayOverlayBooking {
    item: RecordBoardCalendarBookingLike;
    courtId: string;
    start: number;
    end: number;
    span: number;
    rowTop: number;
    rowHeight: number;
    rowIndex: number;
    lane?: number;
    laneCount?: number;
    continuesNext?: boolean;
    continuesPrev?: boolean;
}
/** 表头时间分组合并（声明式）；与 {@link RecordBoardCalendarProps.renderTimelineHeader} 二选一优先用 render */
export interface RecordBoardCalendarTimelineHeaderGroup {
    /** 含 0，对应 `hourSlots` 下标 */
    startSlotIndex: number;
    /** 含，须 ≥ startSlotIndex */
    endSlotIndex: number;
    label: ReactNode;
}
/** 自定义时间列表头时注入的上下文 */
export interface RecordBoardCalendarTimelineHeaderRenderContext {
    anchorDate: Date;
    /** 各列左边界钟点（相对锚日 0 点的浮点小时，与现 hourSlots 一致） */
    hourSlots: number[];
    slotStepMinutes: number;
    /** 单列像素宽：与历史日视图整点列宽一致（每槽一列，细粒度时列数变多、横向滚动） */
    slotColWidthPx: number;
    isLight: boolean;
    firstTimelineHour: number;
    endTimelineExclusive: number;
    isBusinessHour: (hour: number) => boolean;
    formatHourLabel: (hour: number) => string;
    /** 与 `hourSlots[i]` 一致 */
    getSlotStartHour: (slotIndex: number) => number;
    slotCount: number;
    /** 每槽「空闲场地数 / 总场地」等，键为槽起点钟点 */
    dayHourRemaining: Record<number, {
        remaining: number;
        total: number;
        ratio: number;
    }>;
}
/** 自定义左侧资源格 */
export interface RecordBoardCalendarResourceRenderArgs {
    view: 'resource' | 'day' | 'week' | 'month';
    row: {
        kind: 'court' | 'group';
        id: string;
        name?: string;
        label?: string;
        count?: number;
        collapsed?: boolean;
        type?: string;
    };
    isLight: boolean;
    /** 分组行折叠切换（仅 group 行有意义） */
    onToggleGroup?: (groupLabel: string) => void;
}
/** 自定义日视图中间预约条外层容器内层（定位仍由日历负责） */
export interface RecordBoardCalendarBookingRenderArgs {
    booking: RecordBoardCalendarDayOverlayBooking;
    dayKey: string;
    calendarView: 'resource' | 'day' | 'week' | 'month';
    isLight: boolean;
    /** 日视图时间轴上该预约条当前绘制宽度（像素），便于窄条用 Tooltip / minWidth 等策略展示信息 */
    overlayWidthPx: number;
    onOpenDetail: (item: RecordBoardCalendarBookingLike) => void;
    onDragStart: (item: RecordBoardCalendarBookingLike) => void;
    onJumpNext: () => void;
}
/**
 * 月 / 周格内单条预约插槽参数。
 * 未使用 {@link RecordBoardCalendarProps.renderMonthWeekBooking} 时，月 / 周格仅默认 booking（紫）/ block（红），不展示状态徽标与按状态的底色。
 */
export interface RecordBoardCalendarGridBookingRenderArgs {
    item: RecordBoardCalendarBookingLike;
    dateKey: string;
    view: 'month' | 'week' | 'resource';
    isLight: boolean;
    /**
     * 日历建议的外层样式（圆角、内边距、默认 booking/block 底色），可与自定义 `className` 拼接。
     * 宿主若完全自定义外观，可忽略本字段。
     */
    layoutClassName: string;
    onOpenDetail: (item: RecordBoardCalendarBookingLike) => void;
    /** 开始拖拽（月视图内置会处理 `draggable`；周格当前未挂 draggable，可自行在插槽内处理） */
    onDragStart?: (item: RecordBoardCalendarBookingLike) => void;
    draggable: boolean;
    /** 列表/弹层等容器实测宽度（像素）；未传时宿主可自行测量 */
    containerWidthPx?: number;
}
/** 拖拽改期的投放目标（与日历内部确认态 moveDraft 字段一致）。 */
export interface RecordBoardBookingMoveDraft {
    targetCourtId: string;
    /** `YYYY-MM-DD` */
    targetDate: string;
    /** 与日历 `hourSlots` 一致的浮点起点小时（可含半格如 9.5） */
    targetHour: number;
}
/**
 * 对接 `POST /shop/schedule/blocked-time` 的请求体（与后台字段一致）。
 */
export interface RecordBoardCalendarBlockedTimePayload {
    name: string;
    note?: string;
    resource_ids: number[];
    blocked_sales_channels: string[];
    /** `YYYY-MM-DD HH:mm` */
    start_time: string;
    /** `YYYY-MM-DD HH:mm` */
    end_time: string;
}
/** 日视图连续空闲槽合并后的一段（与内置锁台面版预填一致） */
export interface RecordBoardBlockedTimeMergedRange {
    courtId: string;
    /** `YYYY-MM-DD` */
    date: string;
    /** 与时间轴一致的浮点小时 */
    startHour: number;
    endHour: number;
}
/** 日视图多选的空闲格 */
export interface RecordBoardCalendarSelectedFreeSlot {
    courtId: string;
    date: string;
    hour: number;
    court?: string;
}
/**
 * 日视图「从选区新建」：与 {@link groupSelectedSlots} 合并后的一段一致（单 court、单日、连续小时）。
 */
export interface RecordBoardCreateBookingDayGroup {
    courtId: string;
    /** `YYYY-MM-DD` */
    date: string;
    startHour: number;
    endHour: number;
}
/**
 * 底部栏「新建预约」传给宿主的上下文。
 * 传入 {@link RecordBoardCalendarProps.onCreateBookingFromSelection} 后，
 * 日历**不再**调用 {@link CalendarPersistContextValue.beforePersist} / **不再**写入本地 `bookings`
 *（适用于 Pisell Reservation 等受控数据源场景）。
 */
export declare type RecordBoardCreateBookingFromSelectionPayload = {
    mode: 'day';
    groups: RecordBoardCreateBookingDayGroup[];
} | {
    mode: 'resource';
    courtId: string;
    /** 升序 `YYYY-MM-DD` */
    dates: string[];
    startHour: number;
    endHour: number;
};
/** 宿主弹出锁台/屏蔽表单时由日历传入的上下文（替代内置锁台面版） */
export interface RecordBoardBlockedTimePanelPayload {
    /** 槽位步长（小时），与日历内部 `slotStepHours` 一致 */
    slotStepHours: number;
    /** 与 {@link RecordBoardCalendarProps.slotStepMinutes} 一致 */
    slotStepMinutes: number;
    /** 日视图锚定日 `YYYY-MM-DD` */
    dayKey: string;
    selectedFreeSlots: RecordBoardCalendarSelectedFreeSlot[];
    mergedRange: RecordBoardBlockedTimeMergedRange;
}
/** 日历视图槽位 props：由 Shell 合并根级与子槽后传入 PisellRecordBoardCalendarView */
export interface RecordBoardCalendarProps {
    persistGuard?: CalendarPersistContextValue;
    /**
     * 日历画布外观：亮色切换 `theme-root.theme-light`；未传或 `dark` 为深色（默认）。
     */
    appearance?: 'light' | 'dark';
    className?: string;
    style?: CSSProperties;
    /** 受控：画布等资源行；不传则使用内置演示数据 */
    resources?: RecordBoardCalendarResource[];
    /** 受控：预约条列表；传入（含空数组）时不再使用内置 seed */
    bookings?: RecordBoardCalendarBookingLike[];
    loading?: boolean;
    /**
     * 点击预约条。返回 true 表示已消费（不再打开内置详情抽屉）。
     */
    onBookingClick?: (item: RecordBoardCalendarBookingLike) => boolean | void;
    /**
     * 拖拽预约条松手且投放合法后，由宿主接管确认与持久化（例如业务侧 booking 改约弹窗）。
     * **传入后**日历不再弹出内置 MoveConfirmModal，也不会写入本地 bookings。
     * 返回 `true` 表示宿主已视为完成（一般由弹窗 resolve）；`false`/`undefined`/reject 表示未生效。
     */
    onBookingMoveRequest?: (payload: {
        item: RecordBoardCalendarBookingLike;
        draft: RecordBoardBookingMoveDraft;
    }) => Promise<boolean | void>;
    /**
     * 锚点日 / 视图变化（月、周、日），用于父级扩展 booking 请求时间窗。
     * 宿主导出时建议对拉数做 **debounce**（如 200–300ms），与切 `bodyView`、切日等快速操作对齐，避免重复请求。
     */
    onViewportChange?: (payload: {
        view: string;
        anchorDate: Date;
        rangeStart: Date;
        rangeEnd: Date;
    }) => void;
    /** 当前日历粒度（与顶栏 Segmented 一致）；不传则组件内默认 `month` */
    calendarView?: 'resource' | 'day' | 'week' | 'month';
    onCalendarViewChange?: (view: 'resource' | 'day' | 'week' | 'month') => void;
    /** 锚点日（通常与营业日 `schedule.date` 对齐）；不传则组件内默认日期 */
    anchorDate?: Date;
    /** 日历内交互（如跨日跳转）更新锚点时回调，由父级写回日程 */
    onAnchorDateChange?: (date: Date) => void;
    /**
     * 日视图横向整点列所依据的营业区间（与 PisellTimeNavigator `range` 语义一致，如 06:00–次日 06:00）。
     * 不传时日历演示默认 02:00–次日 02:00。
     */
    timelineRange?: TimeRangeOption;
    /**
     * 日视图时间轴列步长（分钟）。须能整除 60 或与业务约定一致；默认 **60**（与历史「整点列」一致）。
     * Pisell Reservation 等业务可在私有包组装 props 时默认传 10。
     */
    slotStepMinutes?: number;
    /**
     * 保存「屏蔽时间」时提交（如 `/shop/schedule/blocked-time`）。
     * 返回 `false` 表示未成功（弹窗保持）；`true` 或 `undefined` 视为成功并关闭弹窗、清空选中。
     * 若同时传 {@link onBlockedTimePanelRequest}，内置锁台面版不再展示，本回调仅在内置路径生效。
     */
    onBlockedTimeSave?: (payload: RecordBoardCalendarBlockedTimePayload) => Promise<boolean | void>;
    /**
     * 日视图选中连续空闲槽并点「屏蔽」时，由宿主弹出锁台表单（替代内置锁台面版）。
     * **传入后**不再渲染内置屏蔽弹层；未传时仍使用内置表单 + {@link onBlockedTimeSave}。
     */
    onBlockedTimePanelRequest?: (payload: RecordBoardBlockedTimePanelPayload) => Promise<boolean | void>;
    /**
     * 日视图 / 资源视图：选中合法连续区间并点「新建预约」时由宿主接管（打开新建弹窗、跳转路由等）。
     * **传入后**日历跳过内置本地写入与 {@link persistGuard} 拦截。
     * 返回 `false` 表示未消费，选中态保留；其余视为成功并清空选区。
     */
    onCreateBookingFromSelection?: (payload: RecordBoardCreateBookingFromSelectionPayload) => boolean | void | Promise<boolean | void>;
    /** 与接口 `blocked_sales_channels` 一致；默认 `['online_store']` */
    blockedTimeSalesChannels?: string[];
    /**
     * 完全自定义日视图时间列表头（不含左上角日期角格）。未传时按槽渲染默认表头；
     * 若同时传 {@link timelineHeaderGroups}，则先渲染分组行再渲染默认/本插槽由实现约定：当前实现为先分组行再默认槽行。
     */
    renderTimelineHeader?: (ctx: RecordBoardCalendarTimelineHeaderRenderContext) => ReactNode;
    /**
     * 在时间槽行上方增加一行合并表头（列宽与槽位对齐）。
     * 若同时传 {@link renderTimelineHeader}，则仅渲染插槽，**忽略**本字段。
     */
    timelineHeaderGroups?: RecordBoardCalendarTimelineHeaderGroup[];
    /**
     * 自定义日视图时间轴上的预约条内容（仅日视图 overlay 生效；月 / 周见 {@link renderMonthWeekBooking}）。
     */
    renderBooking?: (args: RecordBoardCalendarBookingRenderArgs) => ReactNode;
    /**
     * 自定义月 / 周格内单条预约。未传时仅默认 booking / block 样式与名称、时间，不展示迟到/取消等状态徽标与状态变色。
     */
    renderMonthWeekBooking?: (args: RecordBoardCalendarGridBookingRenderArgs) => ReactNode;
    /** 自定义周/日视图左侧资源列单元 */
    renderResourceCell?: (args: RecordBoardCalendarResourceRenderArgs) => ReactNode;
    /**
     * 预约条在主轴刻度上的填充方式：
     * - 'proportional'：按精确时间比例（部分覆盖刻度 → 按比例宽/高）
     * - 'snap'：补全到当前刻度结束（部分覆盖 → 占满整刻度）
     * 不传时按视图默认：日视图 proportional，周/资源/月 snap。
     */
    tickFillMode?: 'proportional' | 'snap';
}
/**
 * 平面图槽位 props：与 PisellFloorMapLayout 对齐；items/renderItem 可省略（由 RecordBoard 默认 [] / () => null）。
 */
export declare type RecordBoardFloorMapProps = Partial<PisellFloorMapLayoutProps>;
/** 大屏资源墙单卡数据（与画布资源 id 对齐，见 {@link resourceId}） */
export interface RecordBoardResourceWallCardModel {
    /** 与日历/画布 `form_record` id 一致 */
    resourceId: string;
    resource: string;
    /** 资源类型等次级标签（如表单 `form_code`）；大屏卡左上角展示于资源名上方 */
    area?: string;
    /**
     * 资源墙展示态：由业务兼容层（如预约页）基于 booking.status + now + start/end 计算。
     * materials 侧仅按该字段渲染，不再做 light/时间窗口推断。
     */
    status?: 'available' | 'inUse' | 'boardingSoon' | 'late' | 'endingSoon' | 'expired';
    currentTime?: string;
    currentBooking?: string;
    /** boardingSoon：距离开始分钟；inUse/endingSoon/expired：距离结束分钟 */
    startsInMin?: number;
    /** late：已超过开始时间但仍未占用（分钟，递增） */
    lateMin?: number;
    remainingMin?: number;
    /**
     * 占用态当前场次 Unix 毫秒时间戳（宿主可用 booking start/end 回填）。
     * 大屏进度条优先用其与墙钟差值连续更新；缺省时退回「剩余分钟漂移 / 60」。
     */
    sessionStartMs?: number;
    sessionEndMs?: number;
    nextList?: Array<{
        time: string;
        booking: string;
        startInMin: number;
    }>;
    /**
     * 当前区展示的是「尚未开始」的预约时：主面板小标题用「下一预约」文案，且不再单独渲染下方 Next 条带。
     */
    wallUseNextLabelHideNextRow?: boolean;
    /**
     * @deprecated light 相关状态已弃用（2026-04）：资源墙仅保留 5 态，不再渲染 light 文案。
     * 旧字段暂保留以兼容历史数据源，但不会再被 materials 使用。
     */
    lightState?: 'off' | 'off_soon_on' | 'on_soon_off';
    /** @deprecated */
    lightOnInMin?: number;
    /** @deprecated */
    lightOffInMin?: number;
}
/**
 * 控制台「Resource & Layout」中与版式/轮播相关的可持久化字段（不含资源多选，其走 filter；不含配色，其走 appearanceTheme）。
 */
export interface RecordBoardResourceWallLayoutPersist {
    layoutKey: string;
    customCols: number;
    customRows: number;
    pageDurationSec: number;
    boardingSoonBeforeMin: number;
    heroMaxWidthRatio: number;
}
/** {@link RecordBoardResourceWallLayoutPersist} 默认值，与 {@link PisellRecordBoardResourceWallView} 历史初始 state 一致 */
export declare const DEFAULT_RESOURCE_WALL_LAYOUT_PERSIST: RecordBoardResourceWallLayoutPersist;
/**
 * 大屏资源墙视图 props；与 Shell 内 `PisellRecordBoard.ResourceWall` 合并（子优先）。
 * 展示顺序默认由 `searchParams.filter.values[filterFieldKey]`（默认 `resource_wall_resource_ids`）非空 `string[]` 决定；
 * **未写该键、值非数组、或 `[]`**：不展示卡片。**仅渲染 `cards` 中能按 `resourceId` 命中的项**；
 * 命中不到的 id（例如磁盘残留的旧店铺 / 已删资源）直接剔除、不再回退成「数字占位卡」，磁盘清洗由宿主负责。
 * 当 `searchParams.sort` 的字段名与 {@link RecordBoardResourceWallProps.statusSortFieldKeys} 匹配（默认 `status`）时，
 * 在筛选顺序基础上按卡占用态重排：升序空闲在前，降序占用（inUse/将结/已结束）在前。
 */
export interface RecordBoardResourceWallProps {
    className?: string;
    style?: CSSProperties;
    /** 全量卡片；展示时按快筛字段过滤 */
    cards?: RecordBoardResourceWallCardModel[];
    loading?: boolean;
    /**
     * 与 ToolBar 快筛里多选字段的 `name`/`key` 一致，用于从 context.searchParams.filter.values 读取 string[]。
     * @default 'resource_wall_resource_ids'
     */
    filterFieldKey?: string;
    /**
     * 与 ToolBar `searchParams.sort` 首段字段名比对（忽略大小写）；命中时资源墙按卡状态重排。
     * 列 key 不是 `status` 时传入实际字段名，例如 `['courtStatus']`。
     * @default ['status']
     */
    statusSortFieldKeys?: string[];
    /** 六态文案/配色覆盖（与默认 map 浅合并）；通常由宿主从 localStorage 水合 */
    statusToneOverrides?: VenueWallStatusToneOverrides;
    /** 覆盖变更时回调，宿主可写入 localStorage */
    onStatusToneOverridesChange?: (next: VenueWallStatusToneOverrides) => void;
    /**
     * 浅 / 深外观各自的卡面主色与六态覆盖；与 {@link onAppearanceThemeChange} 配合由宿主持久化。
     * 未传入时由视图内部维护（刷新丢失）。
     */
    appearanceTheme?: VenueWallAppearanceTheme;
    onAppearanceThemeChange?: (next: VenueWallAppearanceTheme) => void;
    /** 当前大屏外观：浅色 / 深色；与 {@link onAppearanceModeChange} 一并由宿主导入 localStorage */
    appearanceMode?: 'light' | 'dark';
    onAppearanceModeChange?: (mode: 'light' | 'dark') => void;
    /**
     * 版式与轮播等；与 {@link onResourceWallLayoutChange} 由宿主导入 localStorage（预约页）。
     */
    resourceWallLayout?: Partial<RecordBoardResourceWallLayoutPersist>;
    onResourceWallLayoutChange?: (next: RecordBoardResourceWallLayoutPersist) => void;
}
/**
 * RecordBoard 容器 Context 值
 * 与具体 layout 类型无关，所有 layout 共用同一套数据与操作
 */
export interface RecordBoardContextValue {
    /**
     * 平面图多数据源字典（整份各 key，不参与表格分页切片）。
     * ShellFrame 会与 FloorMap 子 props 中的 dataSources 合并后传入 PisellFloorMapLayout。
     */
    dataSources?: FloorMapDataSources;
    /**
     * 表格绑定 `dataSources` 的 key；仅当未传入根级 `data` 时，表格数据由 `dataSources[gridDataSourceKey]` 推导并做客户端分页切片。
     */
    gridDataSourceKey?: string;
    /** 当前列表数据 */
    data: any[];
    /** 加载态 */
    loading: boolean;
    /** 总数（用于分页） */
    total: number;
    /** 分页状态 */
    pagination: RecordBoardPaginationState;
    /** 分页变更 */
    onPageChange: (pageNumber: number, pageSize: number) => void;
    /** 搜索/筛选参数 */
    searchParams: Record<string, any>;
    /** 触发搜索（会重置到第一页） */
    onSearch: (params: Record<string, any>) => void;
    /** 重置搜索 */
    onReset?: () => void;
    /** 当前布局类型，供子组件按需做差异化 */
    layoutType: RecordBoardLayoutType;
    /**
     * 表格/工具栏手机紧凑布局；`phone` 时 Grid 应用列宽缩放与 `--phone` 样式。
     * @default 'default'
     */
    layoutVariant?: RecordBoardLayoutVariant;
    /** 多选：当前选中的 key 列表 */
    selectedKeys: Key[];
    /** 多选：当前选中的行数据 */
    selectedRows: any[];
    /** 多选：选择变更回调（表格/卡片勾选、BatchActionBar 全选/清空/反选时调用） */
    onSelectionChange: (keys: Key[], rows: any[]) => void;
    /** 行主键，用于多选与列表渲染，如 'id' 或 (record) => record.id */
    rowKey?: string | ((record: any) => Key);
    /**
     * 列显示隐藏状态（仅影响表格/卡片列展示，不影响 filter/sort 配置）。
     * key 为列 key/dataIndex，value 为是否显示；未出现的列默认显示。
     */
    columnVisibility?: Record<string, boolean>;
    /** 列显示隐藏变更回调 */
    onColumnVisibilityChange?: (visibility: Record<string, boolean>) => void;
    /** 列 key 顺序（用于列设置弹层拖拽排序），未设置时按 grid.columns 顺序 */
    columnOrder?: string[] | null;
    /** 列顺序变更回调（拖拽排序后） */
    onColumnOrderChange?: (columnKeys: string[]) => void;
    /** 各子组件透传 props，由 Provider 注入 */
    childComponentProps?: RecordBoardChildComponentProps;
    /**
     * 业务方完全自定义的分页渲染（从根 props 透传过来）。
     * `<RecordBoardPagination />` 优先级：组件 `render` prop > 此 ctx 字段 > 默认 materials Pagination。
     */
    paginationRender?: (ctx: RecordBoardContextValue) => React.ReactNode;
    /**
     * 与 `grid.infiniteScroll` 同步：为 true 时不渲染 ShellFrame 底部分页，由 Grid 表体触底触发翻页。
     */
    gridInfiniteScroll?: boolean;
    /** 是否占满父容器高度，供 ShellFrame 做弹性布局（内容区纯 CSS 滚动 + 表头 sticky；scroll.autoCalc 时用测量高度） */
    fillHeight?: boolean;
    /** 内容区滚动容器高度（fillHeight 且 grid.scroll.autoCalc 时由 ShellFrame 测量），供 Grid 计算 scroll.y */
    scrollAreaHeight?: number | null;
    /** 设置内容区滚动容器高度（由 ShellFrame 测量组件调用） */
    setScrollAreaHeight?: (height: number | null) => void;
    /** 点击重置时递增，供 ToolBar 给 PisellFilter 设 key 以强制重挂载，清空弹窗内表单 */
    filterResetKey?: number;
    /** 递增 filterResetKey，由 ToolBarReset 在重置时调用 */
    setFilterResetKey?: (fn: (prev: number) => number) => void;
    /** 当前主内容区：表格或平面图；无平面图配置时一般为 grid（ShellFrame 内仅 FloorMap 时会改为 floorMap） */
    bodyView: RecordBoardBodyView;
    setBodyView: (v: RecordBoardBodyView) => void;
    /** 根级传入的平面图 props（可选）；与 ShellFrame 内 FloorMap 子组件合并，子优先 */
    floorMapProps?: RecordBoardFloorMapProps;
    /**
     * 平面图数据/保存等注入上下文（与 `FloorMapLayoutContextValue` 同形），由 Shell 内置 `FloorMapLayoutProvider` 注入 `PisellFloorMapLayout`；
     * 与 `useRecordBoardContext()` 同源镜像，供 Toolbar 等读取。
     */
    floorMapLayoutContext?: FloorMapLayoutContextValue;
    /** 双视图并存时首屏偏好（根 props，与 PisellRecordBoard.defaultBodyView 一致） */
    defaultBodyView?: RecordBoardBodyView;
    /** 是否允许表格/平面图切换，与根 props `bodyViewSwitchable` 一致 */
    bodyViewSwitchable?: boolean;
    /** 挂到 ShellFrame 内 PisellFloorMapLayout，供外部 imperative 调用（如 saveLayout / fitBounds） */
    floorMapLayoutRef?: Ref<PisellFloorMapLayoutRef | null>;
    /**
     * 平面图视图下叠在画布内的底部居中悬浮区（如「编辑平面图」），不单独占一行 footer。
     */
    floorMapFooter?: ReactNode;
    /** 根级传入的日历视图 props（可选）；与 ShellFrame 内 Calendar 子组件合并，子优先 */
    calendarProps?: RecordBoardCalendarProps;
    /** 根级传入的大屏资源墙 props（可选）；与 ShellFrame 内 ResourceWall 子组件合并，子优先 */
    resourceWallProps?: RecordBoardResourceWallProps;
}
/**
 * 各 layout 下子组件的可选透传配置（类似 ChildComponentProps）
 */
/**
 * BatchActionBar 透传配置，与 PisellBatchActionBar 的 props 对齐。
 * 具体类型见 PisellBatchActionBarProps，此处仅做透传用。
 */
export declare type RecordBoardBatchActionBarProps = Record<string, any>;
/** Filter 透传配置，与 PisellFilter 的 props 对齐 */
export declare type RecordBoardFilterProps = Record<string, any>;
/**
 * ToolBar 透传配置。
 * - 继承 PisellToolBar 的 slots：topLeft、topRight、bottomLeft、bottomRight、tabs。
 * - search：默认在工具栏内渲染 PisellFind；为对象时透传为 PisellFind 的 props；为 false 时不渲染搜索。
 * - filter：默认在工具栏右侧渲染 PisellFilter；为对象时透传 PisellFilter props；为 false 时不渲染。筛选值绑定 searchParams.filter，变更触发 onSearch。
 */
export interface RecordBoardToolBarProps {
    /**
     * `compact`：Find / 快筛 / 排序筛选 / 重置 / 视图切换等统一小号，用于窄容器（如 HUD 内嵌表）。
     * `compact-narrow`：极窄容器（如 HUD 抽屉）下的进一步压缩 ──
     *   - Find 退化为图标触发器（弹搜索 Modal/Drawer），不再常驻 input
     *   - 列显示 / 排序 / 筛选合并到一个齿轮按钮的 Popover 内
     *   - Reset 仍单独保留（快捷高频动作）
     * @default 'default'
     */
    toolbarDensity?: 'default' | 'compact' | 'compact-narrow';
    className?: string;
    style?: React.CSSProperties;
    tabs?: React.ReactNode;
    topLeft?: React.ReactNode;
    topRight?: React.ReactNode;
    bottomLeft?: React.ReactNode;
    bottomRight?: React.ReactNode;
    /** 在 ToolBar 内渲染搜索：默认 PisellFind；对象透传 PisellFind props；false 不渲染 */
    search?: boolean | RecordBoardSearchProps;
    /** 在 ToolBar 右侧渲染筛选：默认 PisellFilter；对象透传 PisellFilter props；false 不渲染。值存于 searchParams.filter */
    filter?: boolean | RecordBoardFilterProps;
    /**
     * 在 ToolBar 内、筛选左侧渲染排序：默认 Sort；对象可传 list、placement 等；false 不渲染。值存于 searchParams.sort。
     * 资源墙视图：排序**菜单内**仅保留「状态」相关项（其余排序仅在表格等视图出现）；若无状态列派生项，会注入「空闲优先 / 占用优先」子项。
     * 可传 `resourceWallSortFieldKeys: string[]` 与非 `status` 列 key 对齐。表格/平面图/日历仍使用完整排序列表。
     */
    sort?: boolean | Record<string, any>;
    /**
     * 在 ToolBar 左侧展示内联快速筛选（替代 Filter 弹层内的 quickFilter）。
     * 为 true 时使用 columns 派生的 quickFilter 列表；为对象时可传 filterList、formFiltersPrefix、size 等。
     * 启用后建议对 filter 传 hiddenQuickFilter: true，弹层内仅保留高级筛选。
     * hideFilterNamesOnFloorMap：仅当 Shell 内同时有表格+平面图且当前为平面图时，按筛选项 name（或 key）从内联快筛中移除，避免与顶栏日程重复（如预约 booking_time_start_between）。
     */
    quickFilter?: boolean | Record<string, any>;
    /** 列显示隐藏设置入口；默认 true（有 grid.columns 时显示）；false 时不渲染 */
    columnSetting?: boolean;
    /**
     * 为 true 时不渲染顶栏 Segmented 视图切换（业务在 topLeft / tabs 内自绘切换器时使用，如手机 Table 下拉）。
     * @default false
     */
    hideBodyViewToggle?: boolean;
    /**
     * 仅 `toolbarDensity: 'compact-narrow'` 且存在左侧内联快筛时生效：
     * 将搜索图标 + 齿轮与快筛同置于一行 `flex-wrap` 容器，尾部 `margin-inline-start: auto`，
     * 以便快筛按钮换行后图标组与**最后一行**快筛右缘对齐（HUD 抽屉等极窄场景）。
     */
    mergeCompactNarrowTrailingWithQuickFilterRow?: boolean;
    /**
     * 桌面（非 compact-narrow）下把右侧操作区（列显示 / 排序 / 筛选 / 重置）收进一个齿轮按钮的 Popover，
     * 复用 compact-narrow 的齿轮机制以节省顶栏宽度。opt-in，默认平铺。
     * `compact-narrow` 始终强制收纳，不受此项影响。
     * @default undefined
     */
    collapseActions?: 'gear';
}
/** Search 透传配置，与 PisellFind 的 props 对齐 */
export declare type RecordBoardSearchProps = Record<string, any>;
/**
 * Grid 布局透传配置，对应 RecordBoardGridView 的 props（useRecordBoardContext('grid') 会将其合并到 context）。
 * 基于 antd TableProps，省略由 context 注入或组件自管的项（dataSource、loading、pagination、columns、scroll、size、rowSelection）。
 * 多选用 selectedKeys/selectedRows/onSelectionChange；其余 Table props（如 onRow、onHeaderRow、expandable、rowClassName、summary）透传。
 */
export declare type RecordBoardGridProps = {
    /** 列配置；ToolBar 据此派生筛选与排序，ColumnSetting 据此做列显示隐藏 */
    columns?: RecordBoardColumnType[];
    /** 默认隐藏的列 key 列表（对应 columns 的 key 或 dataIndex），用于初始化列显隐状态 */
    defaultHiddenColumnKeys?: string[];
    /**
     * 当前页某列全部同值或全部为空时：隐藏该列，并在表格上方展示总结区（列名 + 统一值/空数据）。
     * 比较规则：列可配置 uniformCompare(value, record) 返回用于比较的 string/number；否则用 dataIndex 取值；仅 string/number 参与比较，undefined/null 不参与。
     * 默认 true；传 false 可关闭。
     */
    collapseUniformColumns?: boolean;
    /**
     * 表格滚动配置，对齐 materials Table useGenScroll。
     * - x / y：同 antd Table scroll。
     * - autoCalc：为 true 时根据内容区高度自动计算 scroll.y（需 fillHeight），表头固定、表体滚动。
     * - scrollToFirstRowOnChange：翻页后是否滚动到第一行。
     */
    scroll?: {
        x?: number | string;
        y?: number | string;
        autoCalc?: boolean;
        scrollToFirstRowOnChange?: boolean;
    };
    /**
     * 为 true 时：表体滚动触底触发 `onPageChange` 加载下一页，ShellFrame **不展示**底部分页条。
     * 宿主需保证 `data` 为已加载的**累积**行（或 dataSources 模式由容器做累积切片），且 `total` 为总量；触底停更条件为 `data.length < total`。
     */
    infiniteScroll?: boolean;
    /**
     * 仅 `layoutVariant="phone"` 时生效：列 key → 最大宽度（px）。
     */
    phoneColumnWidthCaps?: Record<string, number>;
    /**
     * 仅 `layoutVariant="phone"` 时生效：列 key → 相对原 width 的缩放比例；未配置列使用 phoneColumnWidthRatio。
     */
    phoneColumnWidthRatioByKey?: Record<string, number>;
    /**
     * 仅 `layoutVariant="phone"` 时生效：默认列宽缩放比例。
     * @default 5/6
     */
    phoneColumnWidthRatio?: number;
    /** 表格尺寸 */
    size?: 'small' | 'middle' | 'default';
    /** 当前选中的行 key 列表（多选） */
    selectedKeys?: Key[];
    /** 当前选中的行数据（多选） */
    selectedRows?: unknown[];
    /** 多选变更回调 */
    onSelectionChange?: (keys: Key[], rows: unknown[]) => void;
    /** 多选列配置：fixed、columnWidth 等，与 selectedKeys/onSelectionChange 合并为 Table rowSelection */
    rowSelection?: Partial<Omit<NonNullable<TableProps<unknown>['rowSelection']>, 'selectedRowKeys' | 'onChange'>>;
} & Omit<TableProps<unknown>, 'dataSource' | 'loading' | 'pagination' | 'columns' | 'scroll' | 'size' | 'rowSelection'>;
export interface RecordBoardChildComponentProps {
    /** 搜索配置，透传给 PisellFind；关键词绑定 searchParams.keyword */
    search?: RecordBoardSearchProps;
    /** 工具栏配置，透传给 PisellToolBar；内置搜索会接 context.searchParams/onSearch */
    toolBar?: RecordBoardToolBarProps;
    pagination?: Record<string, any>;
    /** Grid 布局配置：列、滚动、尺寸等，透传给 RecordBoardGridView */
    grid?: RecordBoardGridProps;
    cardList?: Record<string, any>;
    /** 多选操作栏配置，透传给 PisellBatchActionBar */
    batchActionBar?: RecordBoardBatchActionBarProps;
}
/**
 * RecordBoard 容器 Props。
 * 仅打散传参：列表/分页/搜索/多选/列显隐、以及 grid/toolBar/search/paginationConfig/batchActionBar/cardList 独立传入。
 */
export interface RecordBoardProps {
    /** 子节点，一般为某种 Layout 或自定义组合 */
    children?: ReactNode;
    /** 当前使用的布局类型 */
    layoutType?: RecordBoardLayoutType;
    /** 行主键，用于多选与列表 */
    rowKey?: string | ((record: any) => Key);
    /** 当前列表数据 */
    data?: any[];
    /**
     * 平面图多数据源；与 `FloorMap` / 根级 `floorMap` 的 dataSources 在 ShellFrame 内合并（后者覆盖同 key）。
     * 表格默认仍用 `data`；若不传 `data` 且提供 `gridDataSourceKey`，则由本字段对应 key 推导表格行并客户端分页。
     */
    dataSources?: FloorMapDataSources;
    /**
     * 表格使用的 `dataSources` key（如 `'tables'`）；与 `floorMapConfig` 内 `dataSourceKey` 对齐。
     * 仅在根级 **`data` 未传入**时生效。
     */
    gridDataSourceKey?: string;
    /** 加载态 */
    loading?: boolean;
    /** 总数（用于分页）；由 `dataSources` 推导表格时，未传则默认为该 key 对应数组长度 */
    total?: number;
    /** 分页状态 */
    pagination?: RecordBoardPaginationState;
    /** 分页变更 */
    onPageChange?: (pageNumber: number, pageSize: number) => void;
    /** 搜索/筛选参数 */
    searchParams?: Record<string, any>;
    /** 触发搜索（会重置到第一页） */
    onSearch?: (params: Record<string, any>) => void;
    /** 重置搜索 */
    onReset?: () => void;
    /** 列显隐持久化：传入则用 @pisell/utils 的 getComponentStorageKey 规则写入 localStorage；低代码可传 __id */
    columnVisibilityStorageKey?: string;
    /** Grid 配置：列、滚动、尺寸等 */
    grid?: RecordBoardGridProps;
    /** 工具栏配置 */
    toolBar?: RecordBoardToolBarProps;
    /** 搜索配置，透传给 PisellFind */
    search?: RecordBoardSearchProps;
    /** 分页组件透传配置（与 pagination 状态区分，此处为 Pagination 组件 props） */
    paginationConfig?: Record<string, any>;
    /**
     * 完全自定义分页渲染：传入则 ShellFrame 内置的 `<RecordBoardPagination />` 用此函数替换默认渲染。
     *
     * 适用场景：业务方需要在窄容器（如 hud 抽屉）里不要 materials Pagination
     * 那套 50px 高、Previous/Next 大按钮、灰底边框容器，直接用 antd 原生 small Pagination
     * 或其它紧凑实现。比 `paginationConfig` 更彻底（后者只是 props 透传，外壳样式仍在）。
     *
     * 入参 ctx 包含 pagination/total/onPageChange 等当前分页所需上下文。
     */
    paginationRender?: (ctx: RecordBoardContextValue) => React.ReactNode;
    /** 多选操作栏配置 */
    batchActionBar?: RecordBoardBatchActionBarProps;
    /** 卡片列表配置 */
    cardList?: Record<string, any>;
    /**
     * 列表区布局变体；传 `phone` 时由 RecordBoard Grid 统一收窄列宽与单元格 padding。
     * @default 'default'
     */
    layoutVariant?: RecordBoardLayoutVariant;
    /** 是否启用分页（与 pagination 状态区分） */
    enablePagination?: boolean;
    /**
     * 日历（可选）：与 PisellRecordBoardCalendarView 对齐。
     * 推荐在 ShellFrame 内使用 PisellRecordBoard.Calendar 声明；若同时传根级与本项，Shell 内子组件 props 优先合并。
     */
    calendar?: RecordBoardCalendarProps;
    /**
     * 大屏资源墙（可选）：与 Shell 内 `PisellRecordBoard.ResourceWall` 对齐。
     * 推荐在 ShellFrame 内声明子组件；若同时传根级与本项，Shell 内子组件 props 优先合并。
     */
    resourceWall?: RecordBoardResourceWallProps;
    /**
     * 平面图（可选，兼容低代码 / SalesGrid 等）：与 PisellFloorMapLayout 对齐。
     * 推荐在 ShellFrame 内使用 PisellRecordBoard.FloorMap 声明；若同时传根级与本项，Shell 内子组件 props 优先合并。
     */
    floorMap?: RecordBoardFloorMapProps;
    /**
     * 平面图 Context 注入（`FloorMapLayoutContextValue`）：配置/保存/加载等；展示向 props 仍建议走 `floorMap`。
     * Shell 在平面图节点内置 Provider，无需再包一层 `FloorMapLayoutProvider`。
     */
    floorMapLayoutContext?: FloorMapLayoutContextValue;
    /**
     * 表格与平面图并存时首屏子视图，默认 grid。
     * 仅声明 FloorMap 而无 Grid/Card 内容时由 ShellFrame 固定为平面图，不出现切换器。
     */
    defaultBodyView?: RecordBoardBodyView;
    /** 与 bodyView 同步持久化到 localStorage 的 key（双视图时生效） */
    bodyViewStorageKey?: string;
    /**
     * 是否允许在表格/平面图之间切换（Segmented）。为 false 时不展示切换器，且若设置了 {@link lockedBodyView} 则锁定子视图。
     * @default true
     */
    bodyViewSwitchable?: boolean;
    /**
     * 当 `bodyViewSwitchable === false` 时强制保持的子视图；未传时默认为 `floorMap`。
     */
    lockedBodyView?: RecordBoardBodyView;
    /** 平面图 Layout 实例 ref，由 ShellFrame 注入 */
    floorMapLayoutRef?: Ref<PisellFloorMapLayoutRef | null>;
    /** 平面图画布内底部悬浮插槽（如编辑入口），注入 Context 供 ShellFrame 渲染 */
    floorMapFooter?: ReactNode;
    /** 其他 */
    [key: string]: any;
}
