import { __esDecorate, __runInitializers } from "tslib";
import { html, nothing } from 'lit';
import { property, state } from 'lit/decorators.js';
import { live } from 'lit/directives/live.js';
import { ApiEditor } from './ApiEditor.js';
import { apiActionKindToIcon, apiActionKindToLabel } from '../lib/ui_mapping.js';
import { renderHelp } from '../../help/render.js';
let ApiModelingEntityEditor = (() => {
    let _classSuper = ApiEditor;
    let _exposed_decorators;
    let _exposed_initializers = [];
    let _exposed_extraInitializers = [];
    let _entity_decorators;
    let _entity_initializers = [];
    let _entity_extraInitializers = [];
    let _showCloseButton_decorators;
    let _showCloseButton_initializers = [];
    let _showCloseButton_extraInitializers = [];
    return class ApiModelingEntityEditor extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _exposed_decorators = [state()];
            _entity_decorators = [state()];
            _showCloseButton_decorators = [property({ type: Boolean })];
            __esDecorate(this, null, _exposed_decorators, { kind: "accessor", name: "exposed", static: false, private: false, access: { has: obj => "exposed" in obj, get: obj => obj.exposed, set: (obj, value) => { obj.exposed = value; } }, metadata: _metadata }, _exposed_initializers, _exposed_extraInitializers);
            __esDecorate(this, null, _entity_decorators, { kind: "accessor", name: "entity", static: false, private: false, access: { has: obj => "entity" in obj, get: obj => obj.entity, set: (obj, value) => { obj.entity = value; } }, metadata: _metadata }, _entity_initializers, _entity_extraInitializers);
            __esDecorate(this, null, _showCloseButton_decorators, { kind: "accessor", name: "showCloseButton", static: false, private: false, access: { has: obj => "showCloseButton" in obj, get: obj => obj.showCloseButton, set: (obj, value) => { obj.showCloseButton = value; } }, metadata: _metadata }, _showCloseButton_initializers, _showCloseButton_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #exposed_accessor_storage = __runInitializers(this, _exposed_initializers, void 0);
        /**
         * Computed exposed entity being edited.
         */
        get exposed() { return this.#exposed_accessor_storage; }
        set exposed(value) { this.#exposed_accessor_storage = value; }
        #entity_accessor_storage = (__runInitializers(this, _exposed_extraInitializers), __runInitializers(this, _entity_initializers, void 0));
        /**
         * Computed domain entity that corresponds to the exposed entity being edited.
         */
        get entity() { return this.#entity_accessor_storage; }
        set entity(value) { this.#entity_accessor_storage = value; }
        #showCloseButton_accessor_storage = (__runInitializers(this, _entity_extraInitializers), __runInitializers(this, _showCloseButton_initializers, false));
        /**
         * When true, shows a close button in the editor header.
         * @attribute
         */
        get showCloseButton() { return this.#showCloseButton_accessor_storage; }
        set showCloseButton(value) { this.#showCloseButton_accessor_storage = value; }
        setupModel(model, domainKey) {
            this.exposed = undefined;
            this.entity = undefined;
            if (!model || !domainKey) {
                return;
            }
            const exposed = model.exposes.find((exposed) => exposed.key === domainKey);
            this.exposed = exposed;
            if (!exposed) {
                return;
            }
            const domain = model.domain;
            if (!domain) {
                return;
            }
            const entity = domain.findEntity(exposed.entity.key, exposed.entity.domain);
            if (!entity) {
                return;
            }
            this.entity = entity;
        }
        handleCloseButtonClick() {
            this.dispatchEvent(new Event('close'));
        }
        handleCollectionPathChange(e) {
            const { exposed } = this;
            if (!exposed) {
                return;
            }
            const input = e.target;
            input.invalid = false;
            try {
                exposed.setCollectionPath(input.value);
                this.notifyChange();
            }
            catch (e) {
                input.invalid = true;
                input.invalidText = e.message;
            }
        }
        handleResourcePathChange(e) {
            const { exposed } = this;
            if (!exposed) {
                return;
            }
            const input = e.target;
            input.invalid = false;
            try {
                exposed.setResourcePath(input.value);
                this.notifyChange();
            }
            catch (e) {
                input.invalid = true;
                input.invalidText = e.message;
            }
        }
        handleActionToggle(e) {
            const { exposed } = this;
            if (!exposed) {
                return;
            }
            const toggle = e.target;
            const { name, checked } = toggle;
            if (checked) {
                this.addAction(name);
            }
            else {
                this.removeAction(name);
            }
        }
        removeAction(kind) {
            const { exposed } = this;
            if (!exposed) {
                return;
            }
            const action = exposed.actions.findIndex((action) => action.kind === kind);
            if (action === -1) {
                return;
            }
            exposed.actions.splice(action, 1);
            this.notifyChange();
            this.requestUpdate();
        }
        addAction(kind) {
            const { exposed } = this;
            if (!exposed) {
                return;
            }
            const existing = exposed.actions.find((action) => action.kind === kind);
            if (existing) {
                return;
            }
            let action;
            switch (kind) {
                case 'list':
                    action = { kind: 'list', filterableFields: [], sortableFields: [], pagination: { kind: 'offset' } };
                    break;
                case 'read':
                case 'create':
                case 'delete':
                    action = { kind };
                    break;
                case 'update':
                    action = { kind: 'update', allowedMethods: ['PUT'] };
                    break;
                case 'search':
                    action = { kind: 'search', fields: [] };
                    break;
                default:
                    throw new Error(`Unsupported action kind: ${kind}`);
            }
            exposed.actions.push(action);
            this.notifyChange();
            this.requestUpdate();
        }
        render() {
            if (!this.exposed || !this.entity) {
                return nothing;
            }
            return html `<div class="container">
      ${this.renderHeader(this.entity)} ${this.renderEndpointsConfiguration(this.exposed)}
      ${this.renderActionsSection(this.exposed)}
    </div>`;
        }
        /**
         * Renders a template of the editor header.
         * @param entity The related domain entity.
         */
        renderHeader(entity) {
            return html `<div class="intro">
      <div class="header">
        <span class="headline-medium ">${entity.info.getLabel()}</span>
        ${this.renderCloseButton()}
      </div>
      <div class="body-medium description">
        Define the logic related to the data entity. It is an endpoint that will be exposed through the API after
        attaching actions to it.
      </div>
    </div>`;
        }
        /**
         * Renders the close button if the `showCloseButton` flag is set.
         */
        renderCloseButton() {
            if (!this.showCloseButton) {
                return nothing;
            }
            return html `<ui-icon-button
      color="outlined"
      class="close-button"
      aria-label="Close editor"
      @click="${this.handleCloseButtonClick}"
    >
      <ui-icon icon="close"></ui-icon>
    </ui-icon-button>`;
        }
        renderEndpointsConfiguration(exposed) {
            return html `<div class="endpoints-configuration config-section">
      <div class="section-header title-large">Endpoints</div>
      <div class="section-description body-medium">Define endpoint paths for the collection and resource.</div>
      ${exposed.hasCollection ? this.renderCollectionPathInput(exposed) : nothing}
      ${this.renderResourcePathInput(exposed)}
    </div>`;
        }
        renderCollectionPathInput(exposed) {
            return html `<div class="row input-row">
      <ui-outlined-text-field
        class="input"
        name="collectionPath"
        label="Collection path"
        .value=${live(exposed.collectionPath || '')}
        ?disabled="${this.readonly}"
        @change=${this.handleCollectionPathChange}
      ></ui-outlined-text-field>
      ${renderHelp('modeling', 'api:collection-path-input')}
    </div>`;
        }
        renderResourcePathInput(exposed) {
            return html `<div class="row input-row">
      <ui-outlined-text-field
        class="input"
        name="resourcePath"
        label="Resource path"
        .value=${exposed.resourcePath || ''}
        ?disabled="${this.readonly}"
        @change=${this.handleResourcePathChange}
      ></ui-outlined-text-field>
      ${renderHelp('modeling', 'api:resource-path-input')}
    </div>`;
        }
        renderActionsSection(exposed) {
            return html `<div class="actions-configuration config-section">
      <div class="section-header title-large">Actions</div>
      <div class="section-description body-medium">
        In this section you can decide which actions can be performed on a collection and a resource.
      </div>
      ${this.renderCollectionActionsSection(exposed)} ${this.renderResourceActionsSection(exposed)}
    </div>`;
        }
        renderCollectionActionsSection(exposed) {
            if (!exposed.hasCollection) {
                return nothing;
            }
            let list = false;
            let create = false;
            let search = false;
            for (const action of exposed.actions) {
                if (action.kind === 'list') {
                    list = true;
                }
                else if (action.kind === 'create') {
                    create = true;
                }
                else if (action.kind === 'search') {
                    search = true;
                }
            }
            return html `<div class="collection-actions-configuration config-section">
      <div class="section-header">
        <div class="title-medium">Collection Actions</div>
        ${renderHelp('modeling', 'api:collection-actions')}
      </div>
      <ui-list class="action-presets">
        <ui-list-item lines="two">
          <ui-icon slot="start" class="action-icon">${apiActionKindToIcon('create')}</ui-icon>
          <span>${apiActionKindToLabel('create')}</span>
          <span slot="supporting-text">Create a new resource</span>
          <ui-switch
            slot="end"
            .checked=${create}
            name="create"
            @change=${this.handleActionToggle}
            ?disabled=${this.readonly}
          ></ui-switch>
        </ui-list-item>
        <ui-list-item lines="two">
          <ui-icon slot="start" class="action-icon">${apiActionKindToIcon('list')}</ui-icon>
          <span>${apiActionKindToLabel('list')}</span>
          <span slot="supporting-text">Paginate through the collection</span>
          <ui-switch
            slot="end"
            .checked=${list}
            name="list"
            @change=${this.handleActionToggle}
            ?disabled=${this.readonly}
          ></ui-switch>
        </ui-list-item>
        <ui-list-item lines="two">
          <ui-icon slot="start" class="action-icon">${apiActionKindToIcon('search')}</ui-icon>
          <span>${apiActionKindToLabel('search')}</span>
          <span slot="supporting-text">Search for a record</span>
          <ui-switch
            slot="end"
            .checked=${search}
            name="search"
            @change=${this.handleActionToggle}
            ?disabled=${this.readonly}
          ></ui-switch>
        </ui-list-item>
      </ui-list>
    </div>`;
        }
        renderResourceActionsSection(exposed) {
            let read = false;
            let update = false;
            let del = false;
            for (const action of exposed.actions) {
                if (action.kind === 'read') {
                    read = true;
                }
                else if (action.kind === 'update') {
                    update = true;
                }
                else if (action.kind === 'delete') {
                    del = true;
                }
            }
            return html `<div class="resource-actions-configuration config-section">
      <div class="section-header">
        <div class="title-medium">Resource Actions</div>
        ${renderHelp('modeling', 'api:resource-actions')}
      </div>
      <ui-list class="action-presets">
        <ui-list-item lines="two">
          <ui-icon slot="start" class="action-icon">${apiActionKindToIcon('read')}</ui-icon>
          <span>${apiActionKindToLabel('read')}</span>
          <span slot="supporting-text">Read a single object</span>
          <ui-switch
            slot="end"
            .checked=${read}
            name="read"
            @change=${this.handleActionToggle}
            ?disabled=${this.readonly}
          ></ui-switch>
        </ui-list-item>
        <ui-list-item lines="two">
          <ui-icon slot="start" class="action-icon">${apiActionKindToIcon('update')}</ui-icon>
          <span>${apiActionKindToLabel('update')}</span>
          <span slot="supporting-text">Update the object</span>
          <ui-switch
            slot="end"
            .checked=${update}
            name="update"
            @change=${this.handleActionToggle}
            ?disabled=${this.readonly}
          ></ui-switch>
        </ui-list-item>
        <ui-list-item lines="two">
          <ui-icon slot="start" class="action-icon">${apiActionKindToIcon('delete')}</ui-icon>
          <span>${apiActionKindToLabel('delete')}</span>
          <span slot="supporting-text">Delete from the collection</span>
          <ui-switch
            slot="end"
            .checked=${del}
            name="delete"
            @change=${this.handleActionToggle}
            ?disabled=${this.readonly}
          ></ui-switch>
        </ui-list-item>
      </ui-list>
    </div>`;
        }
        constructor() {
            super(...arguments);
            __runInitializers(this, _showCloseButton_extraInitializers);
        }
    };
})();
/**
 * An entity editor displaying information about an exposed entity
 * in the API model, including its domain entity.
 *
 * @fires close - Fired when the user clicks the close button in the header.
 */
export default ApiModelingEntityEditor;
//# sourceMappingURL=ApiModelingEntityEditor.js.map