import { UMB_TEMPLATE_DETAIL_REPOSITORY_ALIAS, UmbTemplateItemRepository } from '../repository/index.js';
import { UMB_TEMPLATE_ENTITY_TYPE } from '../entity.js';
import { UMB_TEMPLATE_WORKSPACE_ALIAS } from './manifests.js';
import { UmbTemplateWorkspaceEditorElement } from './template-workspace-editor.element.js';
import { UmbEntityNamedDetailWorkspaceContextBase, UmbWorkspaceIsNewRedirectController, UmbWorkspaceIsNewRedirectControllerAlias, } from '../../../core/workspace/index.js';
import { UmbObjectState } from '../../../../libs/observable-api/index.js';
export class UmbTemplateWorkspaceContext extends UmbEntityNamedDetailWorkspaceContextBase {
    #masterTemplate;
    constructor(host) {
        super(host, {
            workspaceAlias: UMB_TEMPLATE_WORKSPACE_ALIAS,
            entityType: UMB_TEMPLATE_ENTITY_TYPE,
            detailRepositoryAlias: UMB_TEMPLATE_DETAIL_REPOSITORY_ALIAS,
        });
        this.itemRepository = new UmbTemplateItemRepository(this);
        this.#masterTemplate = new UmbObjectState(null);
        this.masterTemplate = this.#masterTemplate.asObservable();
        this.alias = this._data.createObservablePartOfCurrent((data) => data?.alias);
        this.content = this._data.createObservablePartOfCurrent((data) => data?.content);
        this.masterTemplateUnique = this._data.createObservablePartOfCurrent((data) => data?.masterTemplate?.unique);
        this.#updateMasterTemplateLayoutBlock = () => {
            const currentContent = this._data.getCurrent()?.content;
            const newMasterTemplateAlias = this.#masterTemplate?.getValue()?.alias;
            const hasLayoutBlock = this.getHasLayoutBlock();
            if (this.#masterTemplate.getValue() === null && hasLayoutBlock && currentContent) {
                const newString = currentContent.replace(this.getLayoutBlockRegexPattern(), `$1null$3`);
                this.setContent(newString);
                return;
            }
            //if has layout block in the content
            if (hasLayoutBlock && currentContent) {
                const string = currentContent.replace(this.getLayoutBlockRegexPattern(), `$1"${newMasterTemplateAlias}.cshtml"$3`);
                this.setContent(string);
                return;
            }
            //if no layout block in the content insert it at the beginning
            const string = `@{
	Layout = "${newMasterTemplateAlias}.cshtml";
}
${currentContent}`;
            this.setContent(string);
        };
        this.routes.setRoutes([
            {
                path: 'create/parent/:entityType/:parentUnique',
                component: UmbTemplateWorkspaceEditorElement,
                setup: async (component, info) => {
                    const parentEntityType = info.match.params.entityType;
                    const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique;
                    await this.create({ entityType: parentEntityType, unique: parentUnique });
                    new UmbWorkspaceIsNewRedirectController(this, this, this.getHostElement().shadowRoot.querySelector('umb-router-slot'));
                },
            },
            {
                path: 'edit/:unique',
                component: UmbTemplateWorkspaceEditorElement,
                setup: (component, info) => {
                    this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias);
                    const unique = info.match.params.unique;
                    this.load(unique);
                },
            },
        ]);
    }
    async load(unique) {
        const response = await super.load(unique);
        // On load we want to set the master template details but not update the layout block in the Razor file.
        // This is because you can still set a layout in code by setting `Layout = "_Layout.cshtml";` in the template file.
        // This gets set automatically if you create a template under a parent, but you don't have to do that, you can
        // just set  the `Layout` property in the Razor template file itself.
        // So even if there's no master template set by there being a parent, there may still be one set in the Razor
        // code, and we shouldn't overwrite it.
        await this.setMasterTemplate(response.data?.masterTemplate?.unique ?? null, false);
        return response;
    }
    async create(parent) {
        const data = await this.createScaffold({
            parent,
            preset: {
                masterTemplate: parent.unique ? { unique: parent.unique } : null,
            },
        });
        // On create set or reset the master template depending on whether the template is being created under a parent.
        // This is important to reset when a new template is created so the UI reflects the correct state.
        await this.setMasterTemplate(parent.unique, true);
        return data;
    }
    setAlias(value) {
        this._data.updateCurrent({ alias: value });
    }
    setContent(value) {
        this._data.updateCurrent({ content: value });
    }
    getLayoutBlockRegexPattern() {
        return new RegExp('(@{[\\s\\S][^if]*?Layout\\s*?=\\s*?)("[^"]*?"|null)(;[\\s\\S]*?})', 'gi');
    }
    getHasLayoutBlock() {
        return this.getData()?.content ? this.getLayoutBlockRegexPattern().test(this.getData()?.content) : false;
    }
    async setMasterTemplate(unique, updateLayoutBlock) {
        if (unique === null) {
            this.#masterTemplate.setValue(null);
        }
        else {
            // We need the whole template model if the unique id is provided
            const { data } = await this.itemRepository.requestItems([unique]);
            if (data) {
                this.#masterTemplate.setValue(data[0]);
            }
        }
        if (updateLayoutBlock) {
            this.#updateMasterTemplateLayoutBlock();
            this._data.updateCurrent({ masterTemplate: unique ? { unique } : null });
        }
        return unique;
    }
    #updateMasterTemplateLayoutBlock;
}
export { UmbTemplateWorkspaceContext as api };
