import { __esDecorate, __runInitializers } from "tslib";
import { html, nothing } from 'lit';
import { property, state } from 'lit/decorators.js';
import { ApiEditor } from './ApiEditor.js';
import { apiActionKindToIcon, getPropertyIcon } from '../lib/ui_mapping.js';
import { renderHelp } from '../../help/render.js';
let ApiSearchActionEditor = (() => {
    let _classSuper = ApiEditor;
    let _exposed_decorators;
    let _exposed_initializers = [];
    let _exposed_extraInitializers = [];
    let _entity_decorators;
    let _entity_initializers = [];
    let _entity_extraInitializers = [];
    let _action_decorators;
    let _action_initializers = [];
    let _action_extraInitializers = [];
    let _indexed_decorators;
    let _indexed_initializers = [];
    let _indexed_extraInitializers = [];
    let _showCloseButton_decorators;
    let _showCloseButton_initializers = [];
    let _showCloseButton_extraInitializers = [];
    let _activeTab_decorators;
    let _activeTab_initializers = [];
    let _activeTab_extraInitializers = [];
    return class ApiSearchActionEditor extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _exposed_decorators = [state()];
            _entity_decorators = [state()];
            _action_decorators = [state()];
            _indexed_decorators = [state()];
            _showCloseButton_decorators = [property({ type: Boolean })];
            _activeTab_decorators = [state()];
            __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, _action_decorators, { kind: "accessor", name: "action", static: false, private: false, access: { has: obj => "action" in obj, get: obj => obj.action, set: (obj, value) => { obj.action = value; } }, metadata: _metadata }, _action_initializers, _action_extraInitializers);
            __esDecorate(this, null, _indexed_decorators, { kind: "accessor", name: "indexed", static: false, private: false, access: { has: obj => "indexed" in obj, get: obj => obj.indexed, set: (obj, value) => { obj.indexed = value; } }, metadata: _metadata }, _indexed_initializers, _indexed_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);
            __esDecorate(this, null, _activeTab_decorators, { kind: "accessor", name: "activeTab", static: false, private: false, access: { has: obj => "activeTab" in obj, get: obj => obj.activeTab, set: (obj, value) => { obj.activeTab = value; } }, metadata: _metadata }, _activeTab_initializers, _activeTab_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; }
        #action_accessor_storage = (__runInitializers(this, _entity_extraInitializers), __runInitializers(this, _action_initializers, void 0));
        /**
         * Computed search action definition being edited.
         */
        get action() { return this.#action_accessor_storage; }
        set action(value) { this.#action_accessor_storage = value; }
        #indexed_accessor_storage = (__runInitializers(this, _action_extraInitializers), __runInitializers(this, _indexed_initializers, []
        /**
         * When true, shows a close button in the editor header.
         * @attribute
         */
        ));
        /**
         * All the indexed properties of the entity.
         */
        get indexed() { return this.#indexed_accessor_storage; }
        set indexed(value) { this.#indexed_accessor_storage = value; }
        #showCloseButton_accessor_storage = (__runInitializers(this, _indexed_extraInitializers), __runInitializers(this, _showCloseButton_initializers, false
        /**
         * The currently active tab index.
         */
        ));
        /**
         * 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; }
        #activeTab_accessor_storage = (__runInitializers(this, _showCloseButton_extraInitializers), __runInitializers(this, _activeTab_initializers, 0));
        /**
         * The currently active tab index.
         */
        get activeTab() { return this.#activeTab_accessor_storage; }
        set activeTab(value) { this.#activeTab_accessor_storage = value; }
        setupModel(model, domainKey) {
            this.exposed = undefined;
            this.entity = undefined;
            this.action = undefined;
            this.indexed = [];
            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;
            const action = exposed.actions.find((action) => action.kind === 'search');
            this.action = action;
            const indexed = [];
            for (const property of entity.properties) {
                if (property.index) {
                    // Note that properties on the entity can't change as they belong to a published data domain.
                    indexed.push(property);
                }
            }
            this.indexed = indexed;
        }
        handleCloseButtonClick() {
            this.dispatchEvent(new Event('close'));
        }
        /**
         * Handles tab change events.
         */
        handleTabChange(e) {
            this.activeTab = e.detail.index;
        }
        handleAddSearchField(e) {
            const item = e.detail.item;
            if (!item.value) {
                return;
            }
            this.addSearchField(item.value);
        }
        handleRemoveField(fieldKey) {
            const { action } = this;
            if (!action) {
                throw new Error('No action is set.');
            }
            this.removeSearchField(fieldKey);
        }
        addSearchField(fieldKey) {
            const { action } = this;
            if (!action) {
                throw new Error('No action is set.');
            }
            if (!action.fields.includes(fieldKey)) {
                action.fields.push(fieldKey);
                this.notifyChange();
                this.requestUpdate();
            }
        }
        removeSearchField(fieldKey) {
            const { action } = this;
            if (!action) {
                throw new Error('No action is set.');
            }
            const index = action.fields.indexOf(fieldKey);
            if (index !== -1) {
                action.fields.splice(index, 1);
                this.notifyChange();
                this.requestUpdate();
            }
        }
        handleConfigurationChange() {
            this.notifyChange();
        }
        render() {
            if (!this.exposed || !this.entity || !this.action) {
                return nothing;
            }
            return html `<div class="container">${this.renderHeader()} ${this.renderTabs()} ${this.renderTabContent()}</div>`;
        }
        /**
         * Renders a template of the editor header.
         */
        renderHeader() {
            const { entity } = this;
            let label = 'Search action';
            if (entity) {
                label = entity.info.getLabel() + ': Search action';
            }
            return html `<div class="intro">
      <div class="header">
        <ui-icon>${apiActionKindToIcon('search')}</ui-icon>
        <span class="headline-medium">${label}</span>
        ${this.renderCloseButton()}
      </div>
      <div class="body-medium description">Search action allows searching through the indexed fields.</div>
    </div>`;
        }
        /**
         * Renders the tabs navigation.
         */
        renderTabs() {
            return html `<ui-tabs
      class="tabs"
      .activeTabIndex="${this.activeTab}"
      @change="${this.handleTabChange}"
      priority="secondary"
    >
      <ui-tab>Configuration</ui-tab>
      <ui-tab>Access</ui-tab>
      <ui-tab>Limits</ui-tab>
    </ui-tabs>`;
        }
        /**
         * Renders the content for the currently active tab.
         */
        renderTabContent() {
            if (!this.action) {
                return nothing;
            }
            switch (this.activeTab) {
                case 0:
                    return this.renderConfigurationTab();
                case 1:
                    return this.renderAccessTab();
                case 2:
                    return this.renderLimitsTab();
                default:
                    return nothing;
            }
        }
        /**
         * Renders the Configuration tab content.
         */
        renderConfigurationTab() {
            if (!this.action) {
                return nothing;
            }
            return html `<div class="configuration-tab">${this.renderSearchConfiguration(this.action, this.indexed)}</div>`;
        }
        /**
         * Renders the Access tab content.
         */
        renderAccessTab() {
            return html `<div class="config-section">
      <api-modeling-access-configuration
        .model="${this.model}"
        domainKey="${this.exposed?.key || ''}"
        operation="search"
        target="action"
        class="access-configuration"
        @change="${this.handleConfigurationChange}"
      ></api-modeling-access-configuration>
    </div>`;
        }
        /**
         * Renders the Limits tab content.
         */
        renderLimitsTab() {
            return html `<div class="config-section">
      <api-modeling-rate-limiting
        .model="${this.model}"
        domainKey="${this.exposed?.key || ''}"
        operation="search"
        target="action"
        class="rate-limiting-configuration"
        @change="${this.handleConfigurationChange}"
      ></api-modeling-rate-limiting>
    </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>`;
        }
        renderSearchConfiguration(action, indexed) {
            const { fields: selected } = action;
            const availableFields = indexed.filter((property) => !selected.includes(property.key));
            const hasAvailableFields = availableFields.length > 0;
            return html `<div class="search-configuration config-section">
      <div class="config-intro">
        <div class="section-header">
          <span class="title-large">Search Fields</span>
          ${renderHelp('modeling', 'api:search-action:fields')}
        </div>
        <div class="section-description body-medium">Fields from the entity that can be used for searching.</div>
      </div>

      <ui-button class="add-button" color="tonal" popovertarget="fields-menu" ?disabled="${!hasAvailableFields}">
        <ui-icon slot="icon" icon="add"></ui-icon>
        Add field
      </ui-button>
      <ui-menu id="fields-menu" popover="auto" @select="${this.handleAddSearchField}">
        ${availableFields.map((property) => html `<ui-menu-item value="${property.key}">${property.info.getLabel()}</ui-menu-item>`)}
      </ui-menu>
      ${selected.length > 0
                ? html `<ui-list class="fields-list" delegateFocus
            >${selected.map((fieldKey) => this.renderFieldListItem(fieldKey, indexed))}</ui-list
          >`
                : nothing}
    </div>`;
        }
        renderFieldListItem(fieldKey, indexed) {
            const property = indexed.find((p) => p.key === fieldKey);
            const title = property?.info?.getLabel() || fieldKey;
            const description = property?.info?.description;
            const icon = property ? getPropertyIcon(property) : 'questionMark';
            return html `<ui-list-item static class="field-list-item">
      <span slot="start">
        <ui-icon icon="${icon}"></ui-icon>
      </span>
      <span>${title}</span>
      ${description ? html `<span slot="supporting-text">${description}</span>` : nothing}
      <ui-icon-button
        slot="end"
        color="standard"
        @click="${() => this.handleRemoveField(fieldKey)}"
        aria-label="Remove filter field"
        inwardFocus
      >
        <ui-icon icon="deleteOutline"></ui-icon>
      </ui-icon-button>
    </ui-list-item>`;
        }
        constructor() {
            super(...arguments);
            __runInitializers(this, _activeTab_extraInitializers);
        }
    };
})();
export default ApiSearchActionEditor;
//# sourceMappingURL=ApiSearchActionEditor.js.map