import { __esDecorate, __runInitializers } from "tslib";
import { html, nothing } from 'lit';
import { property } from 'lit/decorators.js';
import { HttpFlowsUi } from './HttpFlowsUi.js';
import '../../md/button/ui-button.js';
import '../../md/switch/ui-switch.js';
import '../../md/dialog/ui-dialog.js';
import '../../md/divider/ui-divider.js';
let HttpAssertions = (() => {
    let _classSuper = HttpFlowsUi;
    let _model_decorators;
    let _model_initializers = [];
    let _model_extraInitializers = [];
    return class HttpAssertions extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _model_decorators = [property({ type: Array })];
            __esDecorate(this, null, _model_decorators, { kind: "accessor", name: "model", static: false, private: false, access: { has: obj => "model" in obj, get: obj => obj.model, set: (obj, value) => { obj.model = value; } }, metadata: _metadata }, _model_initializers, _model_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #model_accessor_storage = __runInitializers(this, _model_initializers, []
        /**
         * Adds a new empty assertion to the model.
         * Note, this function won't notify the parent element
         * about the change as empty rules can be discarded.
         */
        );
        /**
         * The list of assertions.
         * This is a live list. All changes are propagated in the model.
         */
        get model() { return this.#model_accessor_storage; }
        set model(value) { this.#model_accessor_storage = value; }
        /**
         * Adds a new empty assertion to the model.
         * Note, this function won't notify the parent element
         * about the change as empty rules can be discarded.
         */
        addAssertion() {
            const { model } = this;
            model.push({
                enabled: true,
                steps: [],
            });
            this.requestUpdate();
        }
        /**
         * Removes an assertion at specified index.
         * @param index The index of the assertion in the `model` to remove.
         */
        removeAssertion(index) {
            const { model } = this;
            if (!model[index]) {
                throw new RangeError(`Invalid index: ${index}`);
            }
            model.splice(index, 1);
            this.requestUpdate();
            this.notifyChange();
        }
        /**
         * Toggles the enabled state of the assertion.
         * @param index The index of the assertion on the `model` array
         * @param value The `enabled` value.
         */
        toggleAssertion(index, value) {
            const { model } = this;
            if (!model[index]) {
                throw new RangeError(`Invalid index: ${index}`);
            }
            model[index].enabled = value;
            this.requestUpdate();
            this.notifyChange();
        }
        handleAdd() {
            this.addAssertion();
        }
        handleRemove(e) {
            const node = e.currentTarget;
            const index = Number(node.dataset.index);
            if (Number.isNaN(index)) {
                return;
            }
            this.removeAssertion(index);
        }
        handleToggle(e) {
            const node = e.currentTarget;
            const index = Number(node.dataset.index);
            if (Number.isNaN(index)) {
                return;
            }
            this.toggleAssertion(index, !!node.checked);
        }
        getStepsTarget(assertionOrActionIndex) {
            if (Number.isNaN(assertionOrActionIndex)) {
                return undefined;
            }
            return this.model[assertionOrActionIndex];
        }
        stepFromChangeEvent(e) {
            const input = e.target;
            input.checkValidity();
            const assertionIndex = Number(input.dataset.assertionIndex);
            const stepIndex = Number(input.dataset.stepIndex);
            if (Number.isNaN(assertionIndex) || Number.isNaN(stepIndex)) {
                return undefined;
            }
            const assertion = this.model[assertionIndex];
            if (!assertion) {
                return undefined;
            }
            return assertion.steps[stepIndex];
        }
        handleRenameAssertion(e) {
            const target = e.currentTarget;
            const assertionIndex = Number(target.dataset.assertionIndex);
            if (Number.isNaN(assertionIndex)) {
                return;
            }
            const assertion = this.model[assertionIndex];
            if (!assertion) {
                return;
            }
            const { description } = assertion;
            const dialog = this.shadowRoot?.querySelector('.rename-dialog');
            if (!dialog) {
                return;
            }
            const input = dialog.querySelector('ui-filled-text-field');
            input.value = description || '';
            dialog.open = true;
            dialog.dataset.assertionIndex = target.dataset.assertionIndex;
        }
        handleRenameDialogResult(e) {
            if (e.detail.cancelled) {
                return;
            }
            const dialog = e.currentTarget;
            const assertionIndex = Number(dialog.dataset.assertionIndex);
            if (Number.isNaN(assertionIndex)) {
                return;
            }
            const assertion = this.model[assertionIndex];
            if (!assertion) {
                return;
            }
            const input = dialog.querySelector('ui-filled-text-field');
            assertion.description = input.value;
            this.requestUpdate();
            this.notifyChange();
            input.value = '';
            delete dialog.dataset.assertionIndex;
        }
        render() {
            return html `
      ${this.renderActionButtons()}
      <div class="container">
        ${this.renderEditor()}
        <ui-divider vertical></ui-divider>
        ${this.renderAssertions()}
      </div>
      ${this.renderRenameAssertionDialog()}
    `;
        }
        renderActionButtons() {
            return html `
      <div class="editor-actions">
        <ui-button color="tonal" @click="${this.handleAdd}" class="add-button">Add</ui-button>
      </div>
    `;
        }
        renderAssertions() {
            return html `
      <section aria-label="Assertion options" class="options">
        ${this.renderResponseDataSourceSuggestions()} ${this.renderTransformationSuggestions()}
        ${this.renderAssertionSuggestions()}
      </section>
    `;
        }
        renderEditor() {
            const { model } = this;
            const content = Array.isArray(model) && !!model.length ? this.renderList(model) : this.renderEmptyMessage();
            return html ` <section aria-label="Assertions editor" class="editor surface1">${content}</section> `;
        }
        renderEmptyMessage() {
            return html ` <div class="empty-message">No assertions added</div> `;
        }
        renderList(model) {
            return html ` ${model.map((item, index) => this.renderAssertion(item, index))} `;
        }
        renderAssertion(item, index) {
            return html `
      <div class="step-row">
        ${this.renderAssertionDescription(item)}
        <div class="param-row">
          ${this.renderToggleButton(item, index)} ${this.renderSteps(item, index)}
          <div class="action-actions">${this.renderRenameAssertion(index)} ${this.renderDeleteAssertion(index)}</div>
        </div>
      </div>
    `;
        }
        renderAssertionDescription(item) {
            const { description } = item;
            if (!description) {
                return nothing;
            }
            return html ` <div class="assertion-description label-medium">${description}</div> `;
        }
        renderToggleButton(item, assertionIndex) {
            return html `
      <ui-switch
        .checked="${!!item.enabled}"
        @change="${this.handleToggle}"
        aria-label="Toggle this assertion"
        data-index="${assertionIndex}"
        class="toggle-button"
      ></ui-switch>
    `;
        }
        renderRenameAssertion(assertionIndex) {
            return html `
      <ui-icon-button
        aria-label="Rename this assertion"
        title="Rename this assertion"
        data-assertion-index="${assertionIndex}"
        @click="${this.handleRenameAssertion}"
        class="rename-button"
      >
        <ui-icon icon="rename" role="presentation"></ui-icon>
      </ui-icon-button>
    `;
        }
        renderDeleteAssertion(assertionIndex) {
            return html `
      <ui-icon-button
        aria-label="Delete this assertion"
        title="Delete this assertion"
        data-index="${assertionIndex}"
        @click="${this.handleRemove}"
        class="delete-button"
      >
        <ui-icon icon="deleteOutline" role="presentation"></ui-icon>
      </ui-icon-button>
    `;
        }
        renderRenameAssertionDialog() {
            return html `
      <ui-dialog
        modal
        class="rename-dialog"
        @close="${this.handleRenameDialogResult}"
        dismissLabel="Cancel"
        confirmLabel="Accept"
      >
        <ui-icon slot="icon" icon="rename"></ui-icon>
        <span slot="title">Rename assertion</span>

        <ui-filled-text-field name="rename" label="Assertion description" required class="input"></ui-filled-text-field>
      </ui-dialog>
    `;
        }
        constructor() {
            super(...arguments);
            __runInitializers(this, _model_extraInitializers);
        }
    };
})();
/**
 * @fires change When the model change
 */
export default HttpAssertions;
//# sourceMappingURL=HttpAssertions.element.js.map