import * as _angular_core from '@angular/core';
import { InjectionToken, Signal, OnInit, OnDestroy, AfterViewInit, EventEmitter, Type, ViewContainerRef, ElementRef, Renderer2, NgZone } from '@angular/core';
import { CdkDragDrop, CdkDragStart } from '@angular/cdk/drag-drop';
import { Menu, MenuCloseReason } from '@ngstarter-ui/components/menu';
import { Popover } from '@ngstarter-ui/components/popover';
import { Observable } from 'rxjs';
import { SelectionModel } from '@angular/cdk/collections';
import { Overlay, OverlayContainer } from '@angular/cdk/overlay';

type TextAlignment = 'left' | 'center' | 'right' | 'justify' | 'start' | 'end' | '' | null;

declare const CONTENT_BUILDER: InjectionToken<unknown>;
declare const CONTENT_EDITOR_BLOCK: InjectionToken<readonly ContentEditorDataBlock[]>;
interface ContentEditorDataBlock {
    id: Signal<string>;
    getData(): any;
    focus(): void;
    isEmpty(): boolean;
    initialized: Signal<boolean>;
}
interface ContentEditorBlockEmpty {
    content: any;
    settings: {
        [prop: string]: any;
    };
}
interface ContentEditorBlock {
    id: string;
    type: string;
    content: any;
    isEmpty: boolean;
    props?: ContentEditorItemProperty[];
    settings: any;
}
interface ContentEditorBlockDef {
    component: () => any;
    type: string;
    empty: () => ContentEditorBlockEmpty;
    options: {
        [prop: string]: any;
    };
}
interface ContentEditorHeadingBlockSettings {
    level: number;
}
interface ContentEditorSuggestionHeading {
    type: 'item' | 'heading';
    title: string;
}
interface ContentEditorSuggestionItem {
    type: 'item' | 'heading';
    title: string;
    description: string;
    iconName: string;
    hotKeys: string;
    blockType: string;
    blockOptions: object;
}
interface ContentEditorImageContent {
    src: string;
    alt: string;
    [prop: string]: any;
}
interface ContentEditorVideoContent {
    src: string;
    caption: string;
    orientation?: 'portrait' | 'landscape';
    [prop: string]: any;
}
interface ContentEditorEmbedContent {
    url: string;
    type: string;
}
interface ContentEditorImageBlockSettings {
    width?: number;
    height?: number;
    actualWidth?: number;
    actualHeight?: number;
}
interface ContentEditorVideoBlockSettings {
    width?: number;
    height?: number;
    actualWidth?: number;
    actualHeight?: number;
}
interface ContentEditorEmbedBlockSettings {
    width: number | null;
    height: number | null;
}
interface ContentEditorListItem {
    content: string;
    props?: ContentEditorItemProperty[];
    children: ContentEditorListItem[];
    [prop: string]: any;
}
interface ContentEditorListSettings {
    listStyle: string;
}
interface ContentEditorItemProperty {
    name: string;
    value: string;
}
interface ContentEditorTableBlockSettings {
}
interface ContentEditorOptions {
    [prop: string]: any;
}

declare class CommandBarComponent implements OnInit, OnDestroy {
    private _document;
    private _textHighlightService;
    private _renderer;
    private _dialog;
    observedElement: HTMLElement | null;
    props: _angular_core.WritableSignal<ContentEditorItemProperty[]>;
    alignment: _angular_core.Signal<string>;
    ngOnInit(): void;
    toggleBold(): void;
    toggleItalic(): void;
    toggleCode(): void;
    toggleStrike(): void;
    toggleUnderline(): void;
    toggleSuperscript(): void;
    toggleSubscript(): void;
    isLinkActive(): boolean;
    isActive(tagName: string): boolean;
    setTextAlignment(alignment: TextAlignment): void;
    isTextAlignment(alignment: TextAlignment): boolean;
    addLink(): void;
    editLink(): void;
    protected onMenuOpen(): void;
    protected onMenuClose(): void;
    protected preventMenuClose(event: MouseEvent): void;
    protected onTextColorChanged(color: string): void;
    protected onBackgroundColorChanged(color: string): void;
    private _extractProps;
    ngOnDestroy(): void;
    private _unwrapTextSelection;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<CommandBarComponent, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<CommandBarComponent, "ngs-command-bar", never, { "observedElement": { "alias": "observedElement"; "required": false; }; }, {}, never, never, true, never>;
}

/**
 * Directive to enable mouse-drag selection of child blocks inside a container.
 *
 * Behavior:
 * - Drag can be started only from an area that is NOT inside a block (matched by `blockSelector`).
 * - While dragging, the directive creates a dynamic selection rectangle element with the
 *   class `selectionAreaClass` (default: `ngs-textContent-builder-selection-area`).
 * - Any block that intersects the selection rectangle receives `selectedClass` (default: `is-selected`).
 *   When the block leaves the selection area, the class is removed.
 */
declare class BlockSelectionDirective implements OnDestroy {
    private document;
    private _platformId;
    private contentBuilder;
    /** CSS selector for selectable blocks. Defaults to `.block`. */
    blockSelector: _angular_core.InputSignal<string>;
    autoScrollContainerSelector: _angular_core.InputSignal<string | null>;
    /** CSS class applied to the dynamic selection rectangle element. */
    selectionAreaClass: _angular_core.InputSignal<string>;
    /**
     * List of CSS class names to ignore when starting selection.
     * If the mousedown target or any of its ancestors (via closest) contains any of
     * these classes, the selection will NOT start. Class names can be provided with
     * or without leading dot (e.g., 'toolbar-button' or '.toolbar-button').
     */
    ignoreClasses: _angular_core.InputSignal<string[]>;
    private elRef;
    private host;
    private selection;
    private selectedSet;
    constructor();
    ngOnDestroy(): void;
    private isInIgnoredArea;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<BlockSelectionDirective, never>;
    static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BlockSelectionDirective, "[ngsBlockSelection]", never, { "blockSelector": { "alias": "blockSelector"; "required": false; "isSignal": true; }; "autoScrollContainerSelector": { "alias": "autoScrollContainerSelector"; "required": false; "isSignal": true; }; "selectionAreaClass": { "alias": "selectionAreaClass"; "required": false; "isSignal": true; }; "ignoreClasses": { "alias": "ignoreClasses"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
}

declare class ContentBuilderComponent implements OnInit, AfterViewInit, OnDestroy {
    private _platformId;
    private _store;
    private elRef;
    private envInjector;
    private cdr;
    private confirmManager;
    private _resolvedScrollContainer;
    private _scrollEffect?;
    private _scrollSubject;
    private _scrollBindSub;
    private _scroll$;
    get scrollContainerScrolled(): Observable<number>;
    private blockDefs;
    content: _angular_core.InputSignal<ContentEditorBlock[]>;
    contentChangedDelay: _angular_core.InputSignalWithTransform<number, unknown>;
    suggestions: _angular_core.InputSignal<any>;
    options: _angular_core.InputSignal<ContentEditorOptions>;
    scrollContainer: _angular_core.InputSignal<string | undefined>;
    readonly contentChanged: _angular_core.OutputEmitterRef<ContentEditorBlock[]>;
    readonly focusChanged: EventEmitter<void>;
    protected _content: _angular_core.WritableSignal<ContentEditorBlock[]>;
    protected blockDefsMap: Map<string, any>;
    protected blockDefsOptionsMap: Map<string, any>;
    protected _blockDragging: _angular_core.WritableSignal<boolean>;
    isSelectionOfBlocksActive: _angular_core.WritableSignal<boolean>;
    _oldContent: _angular_core.WritableSignal<{}>;
    readonly selectedBlocksModel: SelectionModel<unknown>;
    commandBar: typeof CommandBarComponent;
    get api(): {
        focusChanged: EventEmitter<void>;
    };
    private buildBlockDefMaps;
    getBlockDefOption(type: string, key: string): any;
    ngOnInit(): void;
    ngAfterViewInit(): void;
    /**
     * Public accessor for the resolved scroll container. If not computed yet, it will compute now.
     */
    getScrollContainer(): Element | Window;
    /**
     * Resolves the scroll container element according to the following rules:
     * - If `scrollContainer` input is provided, uses `closest(selector)` starting from the host element.
     * - If not provided or `closest` returned null, automatically finds the first scrollable parent by walking up the DOM.
     * - Fallback to `document.scrollingElement` or `window` if nothing suitable found.
     */
    private _computeScrollContainer;
    private _isElementScrollable;
    private _rebindScrollListener;
    appendBlock(type: string, focus?: boolean): void;
    insertBlock(type: string, index: number, options?: object, focus?: boolean, content?: any): any;
    private _createBlock;
    addBlock(type: string, options: object, index?: number): void;
    duplicateBlock(blockId: string): void;
    duplicateSelectedBlocks(popover: Popover): void;
    deleteBlock(blockId: string): void;
    setBlockProps(id: string, props: ContentEditorItemProperty[]): void;
    insertEmptyBlock(index: number): void;
    focusBlock(id: string | null): void;
    isBlockFocused(id: string): boolean;
    isActiveBlock(id: string): boolean;
    drop(event: CdkDragDrop<ContentEditorBlock[]>): void;
    onTagSelected(tagName: string | null): void;
    getData(): ContentEditorBlock[];
    emitContentChangeEvent(): void;
    selectBlock(blockId: string, multiple?: boolean): void;
    unselectBlock(blockId: string): void;
    unselectSelectedBlocks(): void;
    isBlockSelected(blockId: string): boolean;
    deleteSelectedBlocks(popover?: Popover): void;
    protected _onKeyDown(event: KeyboardEvent): void;
    protected onDragStarted(event: CdkDragStart, block: ContentEditorBlock): void;
    protected onDragEnded(event: CdkDragStart, block: ContentEditorBlock): void;
    protected addBlockFromSuggestionMenu(suggestionsMenu: Menu, type: string, options: object): void;
    protected preventMenuClose(event: Event): void;
    protected setActiveBlockId(event: Event, id: string | null): void;
    protected onFocusChange(origin: string | null, dataBlock: ContentEditorBlock): void;
    protected onSuggestionsMenuOpen(): void;
    protected onSuggestionsMenuClose(reason: MenuCloseReason): void;
    ngOnDestroy(): void;
    onSettingsPopoverClose(): void;
    protected _onPaste(event: ClipboardEvent): void;
    private _handleTextPaste;
    private _handleHtmlPaste;
    private _mapNodeToBlock;
    private _mapListItems;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<ContentBuilderComponent, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<ContentBuilderComponent, "ngs-content-builder", ["ngsContentBuilder"], { "content": { "alias": "content"; "required": false; "isSignal": true; }; "contentChangedDelay": { "alias": "contentChangedDelay"; "required": false; "isSignal": true; }; "suggestions": { "alias": "suggestions"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "scrollContainer": { "alias": "scrollContainer"; "required": false; "isSignal": true; }; }, { "contentChanged": "contentChanged"; }, never, never, true, [{ directive: typeof BlockSelectionDirective; inputs: { "autoScrollContainerSelector": "autoScrollContainerSelector"; }; outputs: {}; }]>;
}

declare class ContentViewerComponent {
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<ContentViewerComponent, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<ContentViewerComponent, "ngs-content-viewer", never, {}, {}, never, never, true, never>;
}

interface ISelectionPopupComponent {
    observedElement?: HTMLElement | null;
}
declare class TextSelectionPopupDirective implements OnDestroy {
    private overlay;
    private viewContainerRef;
    private elementRef;
    private renderer;
    private overlayContainer;
    private ngZone;
    targetComponent: Type<ISelectionPopupComponent>;
    closestContentObserverClass: string | null;
    tagSelected: EventEmitter<string | null>;
    private overlayRef;
    private hostElement;
    private currentSelectionRange;
    private documentClickListener;
    private positionStrategy;
    private scrollListener;
    private scrollSubject;
    private scrollSubscription;
    constructor(overlay: Overlay, viewContainerRef: ViewContainerRef, elementRef: ElementRef<HTMLElement>, renderer: Renderer2, overlayContainer: OverlayContainer, ngZone: NgZone);
    onDocumentClickHostListener(event: MouseEvent): void;
    onDocumentKeyDown(event: KeyboardEvent): void;
    private processSelection;
    private showPopup;
    private closePopupIfNeeded;
    private closePopup;
    private addScrollListener;
    private removeScrollListener;
    private updatePopupPositionOnScroll;
    private findClosestElementWithClass;
    private getContainingTagName;
    private addDocumentClickListener;
    private removeDocumentClickListener;
    private handleDocumentClick;
    private isEventInsidePopup;
    private isClickInsidePopup;
    private isFocusInsidePopup;
    private areRangesEqual;
    ngOnDestroy(): void;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<TextSelectionPopupDirective, never>;
    static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TextSelectionPopupDirective, "[ngsTextSelectionPopup]", never, { "targetComponent": { "alias": "targetComponent"; "required": false; }; "closestContentObserverClass": { "alias": "closestContentObserverClass"; "required": false; }; }, { "tagSelected": "tagSelected"; }, never, never, true, never>;
}

export { BlockSelectionDirective, CONTENT_BUILDER, CONTENT_EDITOR_BLOCK, CommandBarComponent, ContentBuilderComponent, ContentViewerComponent, TextSelectionPopupDirective };
export type { ContentEditorBlock, ContentEditorBlockDef, ContentEditorBlockEmpty, ContentEditorDataBlock, ContentEditorEmbedBlockSettings, ContentEditorEmbedContent, ContentEditorHeadingBlockSettings, ContentEditorImageBlockSettings, ContentEditorImageContent, ContentEditorItemProperty, ContentEditorListItem, ContentEditorListSettings, ContentEditorOptions, ContentEditorSuggestionHeading, ContentEditorSuggestionItem, ContentEditorTableBlockSettings, ContentEditorVideoBlockSettings, ContentEditorVideoContent, ISelectionPopupComponent };
