import { BehaviorSubject } from 'rxjs';
import { SavedFormatting } from '../../state/formattings';
import { PersistedSlice } from '../../../../../json-crdt-extensions/peritext/slice/PersistedSlice';
import { subject } from '../../../../util/rx';
import { toSchema } from '../../../../../json-crdt/schema/toSchema';
import { JsonCrdtDiff } from '../../../../../json-crdt-diff/JsonCrdtDiff';
import { Model } from '../../../../../json-crdt/model';
export class FormattingManageState {
    state;
    inline;
    selected$ = new BehaviorSubject(null);
    view$ = new BehaviorSubject('view');
    editing$ = new BehaviorSubject(undefined);
    constructor(state, inline) {
        this.state = state;
        this.inline = inline;
    }
    getFormattings$(inline = this.inline) {
        const state = this.state;
        return subject(state.surface.render$, () => {
            const slices = inline?.p1.layers;
            const res = [];
            if (!slices)
                return res;
            const registry = state.txt.editor.getRegistry();
            for (const slice of slices) {
                const tag = slice.type();
                if (typeof tag !== 'number' && typeof tag !== 'string')
                    continue;
                const behavior = registry.get(tag);
                if (!behavior)
                    continue;
                const isConfigurable = !!behavior.schema;
                if (!isConfigurable)
                    continue;
                if (!(slice instanceof PersistedSlice))
                    continue;
                res.push(new SavedFormatting(behavior, slice, state));
            }
            return res;
        });
    }
    select = (formatting) => {
        this.selected$.next(formatting);
    };
    switchToViewPanel = () => {
        this.view$.next('view');
        this.editing$.next(void 0);
    };
    switchToEditPanel = () => {
        const selected = this.selected$.getValue();
        if (!selected)
            return;
        this.view$.next('edit');
        const formatting = new SavedShadowFormatting(selected);
        this.editing$.next(formatting);
    };
    returnFromEditPanelAndSave = () => {
        const shadowFormatting = this.editing$.getValue();
        if (!shadowFormatting)
            return;
        const view = shadowFormatting.conf().view();
        const formatting = shadowFormatting.saved;
        const data = formatting.conf();
        if (!data)
            return;
        const model = data.api.model;
        const patch = new JsonCrdtDiff(model).diff(data.node, view);
        if (patch.ops.length)
            model.applyPatch(patch);
        this.switchToViewPanel();
        this.state.surface.rerender();
    };
}
export class SavedShadowFormatting extends SavedFormatting {
    saved;
    _model;
    constructor(saved) {
        super(saved.behavior, saved.range, saved.state);
        this.saved = saved;
        const nodeApi = saved.conf();
        const schema = nodeApi ? toSchema(nodeApi.node) : void 0;
        this._model = Model.create(schema);
    }
    conf() {
        return this._model.api.obj([]);
    }
}
//# sourceMappingURL=state.js.map