import { HubItemEntity } from "../core/HubItemEntity";
import { getEditorConfig } from "../core/schemas/getEditorConfig";
import { Catalog } from "../search/Catalog";
import { DEFAULT_INITIATIVE_TEMPLATE } from "./defaults";
import { fetchInitiativeTemplate } from "./fetch";
import { initiativeTemplateToCardModel } from "./view";
import { cloneObject } from "../util";
import { createInitiativeTemplate, updateInitiativeTemplate, deleteInitiativeTemplate, } from "./edit";
import { enrichEntity } from "../core/enrichEntity";
import { getEditorSlug } from "../core/_internal/getEditorSlug";
import { hubItemEntityFromEditor } from "../core/_internal/hubItemEntityFromEditor";
import { setProp } from "../objects/set-prop";
/**
 * Hub Initiative Template Class
 */
export class HubInitiativeTemplate extends HubItemEntity {
    constructor(initiativeTemplate, context) {
        super(initiativeTemplate, context);
        this._catalog = Catalog.fromJson(initiativeTemplate.catalog, this.context);
    }
    get catalog() {
        return this._catalog;
    }
    /**
     * Create an instance from an IHubInitiativeTemplate object
     * @param json - JSON object to create a HubInitiativeTemplate from
     * @param context - ArcGIS context
     * @returns - instance of HubInitiativeTemplate
     */
    static fromJson(json, context) {
        // merge what we have with the default values
        const pojo = this.applyDefaults(json, context);
        return new HubInitiativeTemplate(pojo, context);
    }
    /**
     * Create a new HubInitiativeTemplate, returning a HubInitiativeTemplate instance.
     * Note: This does not persist the HubInitiativeTemplate into the backing store
     * @param partialInitiativeTemplate
     * @param context
     * @param save
     * @returns
     */
    static async create(partialInitiativeTemplate, context, save = false) {
        const pojo = this.applyDefaults(partialInitiativeTemplate, context);
        // return an instance of HubInitiativeTemplate
        const instance = HubInitiativeTemplate.fromJson(pojo, context);
        if (save) {
            await instance.save();
        }
        return instance;
    }
    /**
     * Fetch a HubInitiativeTemplate from the backing store and return a HubInitiativeTemplate instance.
     * @param identifier - Identifier of the initiative template to load
     * @param context
     */
    static async fetch(identifier, context) {
        // fetch the initiative template by id or slug
        try {
            const initiativeTemplate = await fetchInitiativeTemplate(identifier, context.requestOptions);
            // create an instance of HubInitiativeTemplate from the initiative template
            return HubInitiativeTemplate.fromJson(initiativeTemplate, context);
        }
        catch (ex) {
            if (ex.message ===
                "CONT_0001: Item does not exist or is inaccessible.") {
                throw new Error(`Initiative Template not found.`);
            }
            else {
                throw ex;
            }
        }
    }
    /**
     * Given a partial initiative template, apply defaults to it to ensure that a baseline of properties are set
     * @param partialInitiativeTemplate
     * @param context
     * @returns
     */
    static applyDefaults(partialInitiativeTemplate, context) {
        // ensure we have the orgUrlKey
        if (!partialInitiativeTemplate.orgUrlKey) {
            partialInitiativeTemplate.orgUrlKey = context.portal.urlKey;
        }
        // ensure orgUrlKey is lowercase
        partialInitiativeTemplate.orgUrlKey =
            partialInitiativeTemplate.orgUrlKey.toLowerCase();
        const pojo = Object.assign(Object.assign({}, DEFAULT_INITIATIVE_TEMPLATE), partialInitiativeTemplate);
        return pojo;
    }
    /**
     * Convert the project entity into a card view model that can
     * be consumed by the suite of hub gallery components
     * @param opts - view model options
     * @returns
     */
    convertToCardModel(opts) {
        return initiativeTemplateToCardModel(this.entity, this.context, opts);
    }
    /**
     * Get the editor config for the HubInitiativeTemplate entity.
     * @param i18nScope translation scope to be interpolated into the uiSchema
     * @param type editor type -- corresponds to the returned uiSchema
     */
    async getEditorConfig(i18nScope, type) {
        // delegate to the schema subsystem
        return getEditorConfig(i18nScope, type, this.entity, this.context);
    }
    /**
     * Return the initiative template as an editor object
     * @param editorContext
     */
    async toEditor(_editorContext = {}, include = []) {
        // cast the entity to its editor
        const editor = include.length
            ? (await enrichEntity(cloneObject(this.entity), include, this.context.hubRequestOptions))
            : cloneObject(this.entity);
        // slug life
        editor._slug = getEditorSlug(this.entity);
        // for now, just return
        return editor;
    }
    /**
     * Load the initiative template from the editor object
     * @param editor
     */
    async fromEditor(editor) {
        // delegate to an item-specific fromEditor util to
        // handle shared "fromEditor" logic
        const res = await hubItemEntityFromEditor(editor, this.context);
        // iterate over the res object keys and set the values
        // on the HubInitiativeTemplate instance
        Object.entries(res).forEach(([key, value]) => {
            setProp(key, value, this);
        });
        // save, which will also create an entity if we don't have an id for it
        await this.save();
        return this.entity;
    }
    /**
     * Apply a new state to the instance
     * @param changes
     */
    update(changes) {
        if (this.isDestroyed) {
            throw new Error("HubInitiativeTemplate is already destroyed.");
        }
        // merge partial onto existing entity
        this.entity = Object.assign(Object.assign({}, this.entity), changes);
        // update internal instances
        if (changes.catalog) {
            this._catalog = Catalog.fromJson(this.entity.catalog, this.context);
        }
    }
    /**
     * Save the HubInitiativeTemplate to the backing store.
     * @returns
     */
    async save() {
        if (this.isDestroyed) {
            throw new Error("HubInitiativeTemplate is already destroyed.");
        }
        // get the catalog and permission configs
        this.entity.catalog = this._catalog.toJson();
        if (this.entity.id) {
            // update it
            this.entity = await updateInitiativeTemplate(this.entity, this.context.userRequestOptions);
        }
        else {
            // create it
            this.entity = await createInitiativeTemplate(this.entity, this.context.userRequestOptions);
        }
        // call the after save hook on superclass
        await super.afterSave();
    }
    /**
     * Delete the HubInitiativeTemplate from the store
     * set a flag to indicate that it is destroyed
     * @returns
     */
    async delete() {
        if (this.isDestroyed) {
            throw new Error("HubInitiativeTemplate is already destroyed.");
        }
        this.isDestroyed = true;
        await deleteInitiativeTemplate(this.entity.id, this.context.userRequestOptions);
    }
}
//# sourceMappingURL=HubInitiativeTemplate.js.map