import { BlockService } from '@blockeditor/block-std';
import { assertExists } from '@blockeditor/global/utils';
import { FileDropManager, } from '../_common/components/file-drop-manager.js';
import { DEFAULT_IMAGE_PROXY_ENDPOINT, ExportManager, } from '../_common/export-manager/export-manager.js';
import { DEFAULT_CANVAS_TEXT_FONT_CONFIG } from '../surface-block/consts.js';
import { copySelectedModelsCommand, deleteSelectedModelsCommand, deleteTextCommand, formatBlockCommand, formatNativeCommand, formatTextCommand, getBlockIndexCommand, getBlockSelectionsCommand, getImageSelectionsCommand, getNextBlockCommand, getPrevBlockCommand, getSelectedBlocksCommand, getSelectedModelsCommand, getTextSelectionCommand, withHostCommand, } from './commands/index.js';
import { FontLoader } from './font-loader/font-loader.js';
export class PageService extends BlockService {
    constructor() {
        super(...arguments);
        this.fontLoader = new FontLoader();
        this._fileDropOptions = {
            flavour: this.flavour,
        };
        this._exportOptions = {
            imageProxyEndpoint: DEFAULT_IMAGE_PROXY_ENDPOINT,
        };
        this._embedBlockRegistry = new Set();
        this.registerEmbedBlockOptions = (options) => {
            this._embedBlockRegistry.add(options);
        };
        this.getEmbedBlockOptions = (url) => {
            const entries = this._embedBlockRegistry.entries();
            for (const [options] of entries) {
                const regex = options.urlRegex;
                if (regex.test(url))
                    return options;
            }
            return null;
        };
    }
    get viewportElement() {
        const pageElement = this.std.view.viewFromPath('block', [
            this.std.page.root?.id ?? '',
        ]);
        assertExists(pageElement);
        const viewportElement = pageElement.viewportElement;
        assertExists(viewportElement);
        return viewportElement;
    }
    mounted() {
        super.mounted();
        this.handleEvent('selectionChange', () => {
            const viewport = this.viewportElement;
            if (!viewport)
                return;
            const selection = document.getSelection();
            if (!selection || !selection.rangeCount)
                return;
            const range = selection.getRangeAt(0);
            const startElement = range.startContainer instanceof Element
                ? range.startContainer
                : range.startContainer.parentElement;
            if (!startElement)
                return;
            if (startElement === document.documentElement ||
                startElement === document.body)
                return;
            if (startElement.closest('.blockeditor-overlay'))
                return;
            if (!viewport.contains(startElement)) {
                this.std.event.deactivate();
                return;
            }
            const endElement = range.endContainer instanceof Element
                ? range.endContainer
                : range.endContainer.parentElement;
            if (!endElement)
                return;
            if (!viewport.contains(endElement)) {
                this.std.event.deactivate();
                return;
            }
            this.std.event.activate();
        }, {
            global: true,
        });
        this.std.command
            .add('getBlockIndex', getBlockIndexCommand)
            .add('getNextBlock', getNextBlockCommand)
            .add('getPrevBlock', getPrevBlockCommand)
            .add('getSelectedBlocks', getSelectedBlocksCommand)
            .add('copySelectedModels', copySelectedModelsCommand)
            .add('deleteSelectedModels', deleteSelectedModelsCommand)
            .add('getSelectedModels', getSelectedModelsCommand)
            .add('getBlockSelections', getBlockSelectionsCommand)
            .add('getImageSelections', getImageSelectionsCommand)
            .add('getTextSelection', getTextSelectionCommand)
            .add('deleteText', deleteTextCommand)
            .add('formatBlock', formatBlockCommand)
            .add('formatNative', formatNativeCommand)
            .add('formatText', formatTextCommand)
            .add('withHost', withHostCommand);
        this.loadFonts();
        this.fileDropManager = new FileDropManager(this, this._fileDropOptions);
        this.exportManager = new ExportManager(this, this._exportOptions);
        this.disposables.addFromEvent(this.std.host, 'dragover', this.fileDropManager.onDragOver);
    }
    get selectedBlocks() {
        let result = [];
        this.std.command
            .pipe()
            .withHost()
            .tryAll(chain => [
            chain.getTextSelection(),
            chain.getImageSelections(),
            chain.getBlockSelections(),
        ])
            .getSelectedBlocks()
            .inline(({ selectedBlocks }) => {
            if (!selectedBlocks)
                return;
            result = selectedBlocks;
        })
            .run();
        return result;
    }
    get selectedModels() {
        return this.selectedBlocks.map(block => block.model);
    }
    loadFonts() {
        this.fontLoader.load(DEFAULT_CANVAS_TEXT_FONT_CONFIG);
    }
}
//# sourceMappingURL=page-service.js.map