import { __esDecorate, __runInitializers } from "tslib";
import { html } from 'lit';
import { live } from 'lit/directives/live.js';
import { classMap } from 'lit/directives/class-map.js';
import { Property } from '@api-client/core/models/Property.js';
import { property, query, state } from 'lit/decorators.js';
import { variableValueLabel } from './Utils.js';
import ApiElement from '../ApiElement.js';
import elementStyles from './VariablesEditor.styles.js';
import '../../md/icons/ui-icon.js';
import '../../md/list/ui-list.js';
import '../../md/list/ui-list-item.js';
import '../../md/switch/ui-switch.js';
import '../../md/icon-button/ui-icon-button.js';
let VariablesEditor = (() => {
    let _classSuper = ApiElement;
    let _variables_decorators;
    let _variables_initializers = [];
    let _variables_extraInitializers = [];
    let _renderValues_decorators;
    let _renderValues_initializers = [];
    let _renderValues_extraInitializers = [];
    let _editedVariable_decorators;
    let _editedVariable_initializers = [];
    let _editedVariable_extraInitializers = [];
    let _editor_decorators;
    let _editor_initializers = [];
    let _editor_extraInitializers = [];
    return class VariablesEditor extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _variables_decorators = [property({ type: Array })];
            _renderValues_decorators = [property({ type: Boolean })];
            _editedVariable_decorators = [state()];
            _editor_decorators = [query('.editor')];
            __esDecorate(this, null, _variables_decorators, { kind: "accessor", name: "variables", static: false, private: false, access: { has: obj => "variables" in obj, get: obj => obj.variables, set: (obj, value) => { obj.variables = value; } }, metadata: _metadata }, _variables_initializers, _variables_extraInitializers);
            __esDecorate(this, null, _renderValues_decorators, { kind: "accessor", name: "renderValues", static: false, private: false, access: { has: obj => "renderValues" in obj, get: obj => obj.renderValues, set: (obj, value) => { obj.renderValues = value; } }, metadata: _metadata }, _renderValues_initializers, _renderValues_extraInitializers);
            __esDecorate(this, null, _editedVariable_decorators, { kind: "accessor", name: "editedVariable", static: false, private: false, access: { has: obj => "editedVariable" in obj, get: obj => obj.editedVariable, set: (obj, value) => { obj.editedVariable = value; } }, metadata: _metadata }, _editedVariable_initializers, _editedVariable_extraInitializers);
            __esDecorate(this, null, _editor_decorators, { kind: "accessor", name: "editor", static: false, private: false, access: { has: obj => "editor" in obj, get: obj => obj.editor, set: (obj, value) => { obj.editor = value; } }, metadata: _metadata }, _editor_initializers, _editor_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        static get styles() {
            return [elementStyles];
        }
        #variables_accessor_storage = __runInitializers(this, _variables_initializers, void 0);
        /**
         * The list of variables to render or edit.
         * This list is mutated. If you don't want this to mutate changes
         * make a copy first.
         */
        get variables() { return this.#variables_accessor_storage; }
        set variables(value) { this.#variables_accessor_storage = value; }
        #renderValues_accessor_storage = (__runInitializers(this, _variables_extraInitializers), __runInitializers(this, _renderValues_initializers, false));
        /**
         * By default all values are masked. When this is set it renders all values visible.
         */
        get renderValues() { return this.#renderValues_accessor_storage; }
        set renderValues(value) { this.#renderValues_accessor_storage = value; }
        #editedVariable_accessor_storage = (__runInitializers(this, _renderValues_extraInitializers), __runInitializers(this, _editedVariable_initializers, void 0));
        get editedVariable() { return this.#editedVariable_accessor_storage; }
        set editedVariable(value) { this.#editedVariable_accessor_storage = value; }
        #editor_accessor_storage = (__runInitializers(this, _editedVariable_extraInitializers), __runInitializers(this, _editor_initializers, null
        /**
         * Updates name/value of a parameter on a specific index.
         */
        ));
        get editor() { return this.#editor_accessor_storage; }
        set editor(value) { this.#editor_accessor_storage = value; }
        /**
         * Updates name/value of a parameter on a specific index.
         */
        updateProperty(index, field, value) {
            const { variables = [] } = this;
            if (!variables[index]) {
                return;
            }
            variables[index][field] = value;
            this.notifyChange();
        }
        /**
         * Removes a parameter from an index.
         */
        removeProperty(index) {
            const { variables = [] } = this;
            if (!variables[index]) {
                return;
            }
            variables.splice(index, 1);
            this.notifyChange();
            this.requestUpdate();
        }
        /**
         * Toggles enabled state of a parameter.
         */
        toggleProperty(index, enabled) {
            const { variables = [] } = this;
            if (!variables[index]) {
                return;
            }
            const variable = variables[index];
            if (variable.enabled === enabled) {
                return;
            }
            variable.enabled = enabled;
            this.notifyChange();
        }
        handleAddVariable() {
            if (!this.variables) {
                this.variables = [];
            }
            const item = Property.String();
            const index = this.variables.push(item.toJSON());
            this.editedVariable = index - 1;
            this.requestUpdate();
            this.ensureEditorInView();
        }
        async ensureEditorInView() {
            await this.updateComplete;
            const { editor } = this;
            if (editor) {
                editor.scrollIntoView();
            }
        }
        /**
         * Toggles visibility of the variable values.
         */
        handleVisibilityToggle() {
            this.renderValues = !this.renderValues;
        }
        /**
         * A handler for the click event on the variable edit icon.
         * Sets state to edit this variable
         */
        handleEditVariable(e) {
            const node = e.currentTarget;
            const index = Number(node.dataset.index);
            if (Number.isNaN(index)) {
                return;
            }
            this.editedVariable = index;
        }
        handleNameChange(e) {
            const input = e.target;
            const index = Number(input.dataset.index);
            if (Number.isNaN(index)) {
                return;
            }
            this.updateProperty(index, 'name', input.value);
            input.checkValidity();
        }
        handleValueChange(e) {
            const input = e.target;
            const index = Number(input.dataset.index);
            if (Number.isNaN(index)) {
                return;
            }
            this.updateProperty(index, 'value', input.value);
            input.checkValidity();
        }
        /**
         * Removes the variable from the environment
         */
        handleVariableDelete(e) {
            const node = e.currentTarget;
            const index = Number(node.dataset.index);
            if (Number.isNaN(index)) {
                return;
            }
            this.removeProperty(index);
        }
        handleRemove(e) {
            const node = e.currentTarget;
            const index = Number(node.dataset.index);
            if (Number.isNaN(index)) {
                return;
            }
            this.removeProperty(index);
        }
        handleToggle(e) {
            const node = e.currentTarget;
            const index = Number(node.dataset.index);
            if (Number.isNaN(index)) {
                return;
            }
            this.toggleProperty(index, !!node.checked);
        }
        /**
         * A handler for the variable editor close button click.
         */
        handleEditorClose() {
            this.editedVariable = undefined;
            this.requestUpdate();
        }
        render() {
            return html ` ${this.renderHeader()} ${this.renderList()} `;
        }
        renderHeader() {
            return html `
      <div class="header">
        <div class="section-title">Variables</div>
        ${this.renderAddButton()} ${this.renderToggleVisibilityButton()}
      </div>
    `;
        }
        renderAddButton() {
            return html `
      <ui-icon-button
        title="Add a variable"
        aria-label="Activate to add a new variable"
        @click="${this.handleAddVariable}"
        data-action="add-variables"
        ><ui-icon icon="add"></ui-icon
      ></ui-icon-button>
    `;
        }
        renderToggleVisibilityButton() {
            const icon = (this.renderValues ? 'visibilityOff' : 'visibility');
            return html `
      <ui-icon-button
        title="Toggle values visibility"
        aria-label="Activate to toggle variables visibility"
        @click="${this.handleVisibilityToggle}"
        data-action="toggle-visibility"
        ><ui-icon icon="${icon}"></ui-icon
      ></ui-icon-button>
    `;
        }
        renderList() {
            const { variables } = this;
            if (!Array.isArray(variables) || !variables.length) {
                return this.renderEmptyInfo();
            }
            return html `
      <ul class="variables-list">
        ${variables.map((item, index) => this.renderListItem(item, index))}
      </ul>
    `;
        }
        renderEmptyInfo() {
            return html `<p class="empty-message">This environment has no variables.</p>`;
        }
        /**
         * @param item The variable to render.
         * @returns The template for the variable line or variable editor
         */
        renderListItem(item, index) {
            if (this.editedVariable === index) {
                return this.renderEditor(item, index);
            }
            const classes = {
                'disabled': !item.enabled,
                'variable-item': true,
            };
            return html ` <li class=${classMap(classes)}>
      <span class="variable-name">${item.name}</span>
      <span class="variable-value">${variableValueLabel(item.value || '', !this.renderValues)}</span>
      ${this.renderListActions(index)}
    </li>`;
        }
        /**
         * @param index The index of the property on the list
         * @returns The template for list item actions
         */
        renderListActions(index) {
            return html ` <div class="list-actions">${this.renderEditButton(index)} ${this.renderDeleteButton(index)}</div>`;
        }
        /**
         * @param item The variable to render.
         * @returns The template for the variables editor
         */
        renderEditor(item, index) {
            return html `
      <li class="editor">
        <div class="param-row">
          ${this.renderToggleButton(item, index)} ${this.renderNameField(item, index)}
          ${this.renderValueField(item, index)} ${this.renderCloseEditor(index)}
        </div>
      </li>
    `;
        }
        renderToggleButton(item, index) {
            return html `
      <ui-switch
        .checked="${!!item.enabled}"
        @change="${this.handleToggle}"
        title="Toggle variable enabled"
        aria-label="Toggle variable enabled state"
        data-index="${index}"
      ></ui-switch>
    `;
        }
        renderDeleteButton(index) {
            return html `
      <ui-icon-button
        aria-label="Deletes this variable"
        title="Deletes this variable"
        data-index="${index}"
        @click="${this.handleRemove}"
        data-action="delete-editor"
      >
        <ui-icon icon="deleteOutline" role="presentation"></ui-icon>
      </ui-icon-button>
    `;
        }
        renderEditButton(index) {
            return html `
      <ui-icon-button
        aria-label="Edits this variable"
        title="Edits this variable"
        data-index="${index}"
        @click="${this.handleEditVariable}"
        data-action="edit"
      >
        <ui-icon icon="edit" role="presentation"></ui-icon>
      </ui-icon-button>
    `;
        }
        renderCloseEditor(index) {
            return html `
      <ui-icon-button
        aria-label="Closes the editor"
        title="Closes the editor"
        data-index="${index}"
        @click="${this.handleEditorClose}"
        data-action="close-editor"
      >
        <ui-icon icon="close" role="presentation"></ui-icon>
      </ui-icon-button>
    `;
        }
        renderNameField(item, index) {
            return html `
      <div class="input-wrapper name-input">
        <div class="error" role="presentation">Invalid character</div>
        <div class="state"></div>
        <input
          type="text"
          name="name"
          autocomplete="off"
          .value="${live(item.name)}"
          data-index="${index}"
          pattern="[a-zA-Z0-9_]+"
          required
          aria-label="Variable name"
          @change="${this.handleNameChange}"
        />
      </div>
    `;
        }
        renderValueField(item, index) {
            const type = this.renderValues ? 'text' : 'password';
            return html `
      <div class="input-wrapper value-input">
        <div class="error" role="presentation">Invalid character</div>
        <div class="state"></div>
        <input
          type="${type}"
          name="value"
          .value="${live(item.value)}"
          data-index="${index}"
          aria-label="Variable value"
          @change="${this.handleValueChange}"
        />
      </div>
    `;
        }
        constructor() {
            super(...arguments);
            __runInitializers(this, _editor_extraInitializers);
        }
    };
})();
/**
 * An element to render a list of variables with an ability to edit them.
 */
export default VariablesEditor;
//# sourceMappingURL=VariablesEditor.js.map