import { c as SceneDocument, a as SceneElement, S as ScenePage, B as Bounds } from './model-DnfO_PdJ.js';
import { S as SceneOperation } from './operations-ByJ6yXOW.js';
import { CanvasRenderPalette } from './theme/index.js';

/**
 * Seams between the design-canvas editor's engine and components, mirroring
 * the sequences-react pattern: interface-only so layers build independently.
 *
 * Persistence: the command stack executes optimistically against local state
 * and emits `SceneOperation[]` through `DesignCanvasProps.onApplyOperations`.
 * The host's apply returns the new revision (and the server document when it
 * re-minted ids); a rejected promise rolls the command back. Drag gestures
 * coalesce: pointer moves mutate volatile state, ONE command (final attrs,
 * inverse = pre-gesture attrs) executes on release — undo is per-gesture,
 * never per-pixel.
 */

/** Define the state of the editor scene including document, view settings, and selection details */
interface EditorSceneState {
    document: SceneDocument;
    activePageId: string;
    selectedElementIds: string[];
    /** Pixels per document px. */
    zoom: number;
    panX: number;
    panY: number;
    gridEnabled: boolean;
    /** Document px between grid lines. */
    gridSize: number;
    snapEnabled: boolean;
    showRulers: boolean;
    showBleed: boolean;
}
/** Define a command with execution, undo, and operation methods for scene editing and persistence */
interface SceneCommand {
    label: string;
    execute(state: EditorSceneState): EditorSceneState;
    undo(state: EditorSceneState): EditorSceneState;
    operations(): SceneOperation[];
    /**
     * The inverse operation sequence for server-side persistence of an undo.
     * Most commands return an exact inverse (e.g. set_attrs → prior set_attrs,
     * add_element → delete_element). deletePageCommand returns add_page +
     * per-element add_element ops restoring the full page snapshot.
     */
    inverseOperations(): SceneOperation[];
}
/** Manage and track scene commands with undo, redo, and state subscription capabilities */
interface SceneCommandStack {
    execute(command: SceneCommand): void;
    /** Apply the top-of-done-stack inverse and return the command (callers use
     *  `command.inverseOperations()` to persist the undo to the server). */
    undo(): SceneCommand;
    /** Re-execute the top-of-redo-stack and return the command (callers use
     *  `command.operations()` to persist the redo to the server). */
    redo(): SceneCommand;
    canUndo(): boolean;
    canRedo(): boolean;
    subscribe(listener: () => void): () => void;
    getState(): EditorSceneState;
    /** Update volatile view state (zoom/pan/selection/toggles) without touching
     *  history — view changes are never undo steps. */
    setView(patch: Partial<Omit<EditorSceneState, 'document'>>): void;
    /** Rebase onto a server refresh WITHOUT clearing history (history holds
     *  operations, not snapshots). */
    reset(document: SceneDocument): void;
    /**
     * Remove a specific command from the undo stack and apply its inverse to
     * the current state. Called by the persistence layer when a save rejects
     * AFTER the user may have made further edits.
     *
     * Invariant: for commands that operate on disjoint attributes, rollback is
     * identity for all commands executed after the rolled-back one — their net
     * effect is preserved. For overlapping attr edits (same element, same field)
     * the result is defined but not guaranteed to be semantically correct; the
     * caller should trigger an onResyncRequired fetch in that case.
     *
     * If `command` is not found in the undo stack (stale or double-fire
     * rejection handler), this is a safe no-op.
     */
    rollback(command: SceneCommand): void;
}
/** Define snap target categories for aligning elements within a layout system */
type SnapTargetKind = 'grid' | 'element-edge' | 'element-center' | 'page-edge' | 'page-center' | 'guide';
/** Define a target position and kind for snapping elements on a page */
interface SnapTarget {
    /** Page-coordinate position of the snap line. */
    position: number;
    kind: SnapTargetKind;
}
/** Define vertical and horizontal collections of snap targets for alignment purposes */
interface SnapTargets {
    vertical: SnapTarget[];
    horizontal: SnapTarget[];
}
/** Define the result of a snap operation including coordinates and active snap lines */
interface SnapResult {
    x: number;
    y: number;
    /** Lines to render while the gesture holds the snap. */
    activeVertical: SnapTarget | null;
    activeHorizontal: SnapTarget | null;
}
/** Resolve snapping targets and apply snapping logic to moving elements within the editor scene */
interface SnapEngine {
    /** Collect targets for a gesture: other elements' edges/centers, page
     *  edges/center, saved guides, and grid lines when enabled. `excludeIds`
     *  removes the dragged elements' own geometry. */
    collectTargets(state: EditorSceneState, excludeIds: string[]): SnapTargets;
    /** Snap a moving AABB. Threshold is SCREEN pixels, divided by zoom. */
    apply(bounds: Bounds, targets: SnapTargets, thresholdPx: number, zoom: number): SnapResult;
}
/** Define methods and properties to calculate zoom and pan transformations between document and screen coordinates */
interface ZoomPanMath {
    minZoom: number;
    maxZoom: number;
    /** Zoom about a screen point so the document point under the cursor stays
     *  fixed (wheel-zoom-to-cursor). Returns the clamped new view. */
    zoomAtPoint(state: {
        zoom: number;
        panX: number;
        panY: number;
    }, factor: number, screenX: number, screenY: number): {
        zoom: number;
        panX: number;
        panY: number;
    };
    /** Fit the active page into a viewport with padding. */
    fitPage(page: {
        width: number;
        height: number;
    }, viewport: {
        width: number;
        height: number;
    }, paddingPx?: number): {
        zoom: number;
        panX: number;
        panY: number;
    };
    documentToScreen(state: {
        zoom: number;
        panX: number;
        panY: number;
    }, x: number, y: number): {
        x: number;
        y: number;
    };
    screenToDocument(state: {
        zoom: number;
        panX: number;
        panY: number;
    }, x: number, y: number): {
        x: number;
        y: number;
    };
}
/** Resolve the result of applying a scene update including revision and optional normalized document */
interface ApplySceneResult {
    rev: number;
    /** Present when the server re-minted ids or normalized the document; the
     *  editor rebases onto it. */
    document?: SceneDocument;
}
/**
 * What the chrome's Export control collects and hands to the workspace's
 * export callback. The workspace (which owns the Konva stage) renders the
 * page to a data URL with these params and forwards the full result to
 * {@link DesignCanvasProps.onExport}. The chrome is Konva-free, so it cannot
 * produce the data URL itself — it only chooses the format and scale.
 */
interface ExportTriggerOptions {
    format: 'png' | 'jpeg';
    /** Output scale multiplier (1 = page size, 2 = retina). */
    pixelRatio: number;
}
/**
 * Editor capability mode.
 * - `'edit'` (default): the full authoring editor — insert panel, page
 *   add/duplicate/delete, layers, grid/snap/ruler/bleed toggles, group/ungroup,
 *   z-order. This is the designer surface.
 * - `'review'`: a lean review/tweak surface for agent-authored output. The
 *   minimal toolbar exposes only safe direct edits (undo/redo, fit/zoom). The
 *   insert panel, blank-page-create, and authoring controls are hidden. Drag,
 *   select, double-click-to-edit-text, image swap, the agent panel, and
 *   gallery/thumbnail/export all stay. Additive and backward-compatible.
 */
type DesignCanvasMode = 'edit' | 'review';
/** Define properties and callbacks for configuring and controlling the design canvas editor */
interface DesignCanvasProps {
    document: SceneDocument;
    /** Revision the document was loaded at; threaded through saves. */
    rev: number;
    canWrite: boolean;
    /** Editor capability mode. Default `'edit'` (full authoring editor). Set
     *  `'review'` for a lean reviewer that hides authoring controls but keeps
     *  drag/select/text-edit/image-swap and the agent panel. */
    mode?: DesignCanvasMode;
    /** Persist operations. Resolve with the new revision; reject to roll back.
     *  A stale-revision failure should resolve AFTER refetch with the fresh
     *  document so the editor rebases instead of fighting. */
    onApplyOperations(operations: SceneOperation[]): Promise<ApplySceneResult>;
    onSelectionChange?(elements: SceneElement[]): void;
    /** Host panels: agent chat (right), asset/template browser (left). */
    renderAgentPanel?(ctx: {
        selectedElements: SceneElement[];
        activePageId: string;
    }): React.ReactNode;
    renderSidePanel?(ctx: {
        selectedElements: SceneElement[];
        activePageId: string;
        activePage: ScenePage;
    }): React.ReactNode;
    /** Export hook — host persists the rendered blob (upload → asset row). */
    onExport?(result: {
        pageId: string;
        format: 'png' | 'jpeg';
        dataUrl: string;
        pixelRatio: number;
    }): Promise<void>;
    /**
     * Optional caller-supplied default for the export popover. The chrome's
     * Export control opens with this format/scale pre-selected. Omitted →
     * PNG @ 1x.
     */
    exportDefaults?: ExportTriggerOptions;
    className?: string;
    /** Konva render palette — the full hex colors the bitmap canvas paints with
     *  (grid, snap guides, selection handles, placeholders). Konva cannot resolve
     *  `var(--…)`, so the host supplies the active theme's `canvasRender` here
     *  (e.g. `darkTheme.canvasRender` under a dark surface). Omitted →
     *  `lightTheme.canvasRender`, which keeps light-mode rendering byte-identical
     *  to the historical hardcoded values. */
    render?: CanvasRenderPalette;
    /** Fit the active page to the viewport once, on the first non-zero measurement. Default true. Set false to keep zoom:1/pan:0 (e.g. when restoring a saved viewport). */
    fitOnMount?: boolean;
    /** Called once after the first real (non-zero) measurement, after the initial fit is applied (or skipped when fitOnMount is false). */
    onReady?(): void;
    /** Show the branded in-canvas empty state (three doors: template, add element,
     *  ask the agent) while the active page has no elements and the user can write.
     *  Default true. Additive and backward-compatible. */
    showEmptyState?: boolean;
    /** Wire the empty state's "Ask the agent" door. Typically focuses the agent
     *  panel (`renderAgentPanel`). Omitted → that door is hidden. */
    onAskAgent?(): void;
    /** Field label for the page-size preset control. Overridable so a consumer
     *  can use the clearer "Page size"; defaults to "Preset" for back-compat. */
    pageSizeLabel?: string;
    /** Title/aria for the "turn on print bleed" action. Defaults to
     *  "Show print bleed" (the outcome), not the print-shop term "bleed". */
    enableBleedLabel?: string;
    /** Label/aria for the zoom fit action. Defaults to "Fit to screen". */
    fitLabel?: string;
}

/**
 * Undo/redo command stack over immutable `EditorSceneState`.
 *
 * History entries hold COMMANDS (state transforms + durable operations
 * captured at construction), never snapshots. Rebasing the document via
 * `reset()` therefore cannot stale the history: a later undo re-applies the
 * inverse transform to whatever document is current. If the rebase removed an
 * element a historical command targets, that transform throws (fail loud)
 * rather than silently editing the wrong element.
 *
 * `setView` updates volatile view state (zoom/pan/selection/toggles) without
 * touching history — view changes are never undo steps.
 */

/** Oldest entries are dropped past this bound; redo stack is cleared on execute. */
declare const SCENE_COMMAND_HISTORY_LIMIT = 200;
/**
 * The base {@link SceneCommandStack} plus the two command-specific recovery
 * primitives the undo/redo persistence path needs. `rollback` (on the base
 * contract) undoes a failed COMMIT; these undo a failed UNDO/REDO persist.
 * Defined here (not on the shared contract) so consumers that take the stack as
 * `ReturnType<typeof createSceneCommandStack>` see them without a contract bump.
 */
interface SceneCommandStackWithReapply extends SceneCommandStack {
    /**
     * A persisted UNDO rejected: re-apply that command's FORWARD transform (move
     * it redo→undo). Mirrors `rollback`'s command-specific contract — it acts on
     * the captured command, not blindly on the redo-stack top, so an interleaved
     * edit cannot make it re-apply the wrong command. No-op if the command is not
     * the top of the redo stack (a newer edit reshaped history — the next
     * `reset()` reconciles).
     */
    reexecute(command: SceneCommand): void;
    /**
     * A persisted REDO rejected: re-apply that command's INVERSE transform (move
     * it undo→redo). The redo-side mirror of `reexecute`. No-op unless the command
     * is the top of the undo stack.
     */
    reundo(command: SceneCommand): void;
}
/** Create a command stack for scene editing with reapply capabilities based on the given document and page ID */
declare function createSceneCommandStack(document: SceneDocument, activePageId: string): SceneCommandStackWithReapply;

export { type ApplySceneResult as A, type DesignCanvasProps as D, type ExportTriggerOptions as E, SCENE_COMMAND_HISTORY_LIMIT as S, type ZoomPanMath as Z, type DesignCanvasMode as a, type EditorSceneState as b, createSceneCommandStack as c, type SceneCommand as d, type SceneCommandStack as e, type SceneCommandStackWithReapply as f, type SnapEngine as g, type SnapResult as h, type SnapTarget as i, type SnapTargetKind as j, type SnapTargets as k };
