import { __esDecorate, __runInitializers } from "tslib";
import { html } from 'lit';
import { property, state } from 'lit/decorators.js';
import { Environment } from '@api-client/core/models/Environment.js';
import { Server } from '@api-client/core/models/Server.js';
import { RequestAuthorization } from '@api-client/core/models/RequestAuthorization.js';
import { live } from 'lit/directives/live.js';
import ApiElement from '../ApiElement.js';
import { Events } from '../../events/Events.js';
import elementStyles from './EnvironmentEditor.styles.js';
import { authTypeToLabel } from '../authorization/AuthLabels.js';
import '../../define/environment/server-editor.js';
import '../../define/environment/variables-editor.js';
import '../../md/icons/ui-icon.js';
import '../../md/text-field/ui-filled-text-field.js';
import '../../md/switch/ui-switch.js';
import '../../md/icon-button/ui-icon-button.js';
import '../../md/button/ui-button.js';
import '../../md/divider/ui-divider.js';
import '../../md/tabs/ui-tabs.js';
import '../../md/tabs/ui-tab.js';
import '../../define/authorization/basic-authorization.js';
import '../../define/authorization/bearer-authorization.js';
import '../../define/authorization/ntlm-authorization.js';
import '../../define/authorization/apikey-authorization.js';
import '../../define/authorization/oauth2-authorization.js';
import '../../define/authorization/oidc-authorization.js';
import '../../define/authorization/cc-authorization.js';
let EnvironmentEditor = (() => {
    let _classSuper = ApiElement;
    let _environment_decorators;
    let _environment_initializers = [];
    let _environment_extraInitializers = [];
    let _oauth2RedirectUri_decorators;
    let _oauth2RedirectUri_initializers = [];
    let _oauth2RedirectUri_extraInitializers = [];
    let _encapsulateHelp_decorators;
    let _encapsulateHelp_initializers = [];
    let _encapsulateHelp_extraInitializers = [];
    let _selected_decorators;
    let _selected_initializers = [];
    let _selected_extraInitializers = [];
    return class EnvironmentEditor extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _environment_decorators = [property({ type: Object })];
            _oauth2RedirectUri_decorators = [property({ type: String })];
            _encapsulateHelp_decorators = [state()];
            _selected_decorators = [property({ type: String })];
            __esDecorate(this, null, _environment_decorators, { kind: "accessor", name: "environment", static: false, private: false, access: { has: obj => "environment" in obj, get: obj => obj.environment, set: (obj, value) => { obj.environment = value; } }, metadata: _metadata }, _environment_initializers, _environment_extraInitializers);
            __esDecorate(this, null, _oauth2RedirectUri_decorators, { kind: "accessor", name: "oauth2RedirectUri", static: false, private: false, access: { has: obj => "oauth2RedirectUri" in obj, get: obj => obj.oauth2RedirectUri, set: (obj, value) => { obj.oauth2RedirectUri = value; } }, metadata: _metadata }, _oauth2RedirectUri_initializers, _oauth2RedirectUri_extraInitializers);
            __esDecorate(this, null, _encapsulateHelp_decorators, { kind: "accessor", name: "encapsulateHelp", static: false, private: false, access: { has: obj => "encapsulateHelp" in obj, get: obj => obj.encapsulateHelp, set: (obj, value) => { obj.encapsulateHelp = value; } }, metadata: _metadata }, _encapsulateHelp_initializers, _encapsulateHelp_extraInitializers);
            __esDecorate(this, null, _selected_decorators, { kind: "accessor", name: "selected", static: false, private: false, access: { has: obj => "selected" in obj, get: obj => obj.selected, set: (obj, value) => { obj.selected = value; } }, metadata: _metadata }, _selected_initializers, _selected_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        static get styles() {
            return [elementStyles];
        }
        #environment_accessor_storage = __runInitializers(this, _environment_initializers, new Environment().toJSON()
        /**
         * Redirect URL for the OAuth2 authorization.
         * If can be also set by dispatching `oauth2-redirect-url-changed`
         * with `value` property on the `detail` object.
         * @attribute
         */
        );
        /**
         * The environment schema to edit.
         */
        get environment() { return this.#environment_accessor_storage; }
        set environment(value) { this.#environment_accessor_storage = value; }
        #oauth2RedirectUri_accessor_storage = (__runInitializers(this, _environment_extraInitializers), __runInitializers(this, _oauth2RedirectUri_initializers, void 0));
        /**
         * Redirect URL for the OAuth2 authorization.
         * If can be also set by dispatching `oauth2-redirect-url-changed`
         * with `value` property on the `detail` object.
         * @attribute
         */
        get oauth2RedirectUri() { return this.#oauth2RedirectUri_accessor_storage; }
        set oauth2RedirectUri(value) { this.#oauth2RedirectUri_accessor_storage = value; }
        #encapsulateHelp_accessor_storage = (__runInitializers(this, _oauth2RedirectUri_extraInitializers), __runInitializers(this, _encapsulateHelp_initializers, void 0));
        get encapsulateHelp() { return this.#encapsulateHelp_accessor_storage; }
        set encapsulateHelp(value) { this.#encapsulateHelp_accessor_storage = value; }
        #selected_accessor_storage = (__runInitializers(this, _encapsulateHelp_extraInitializers), __runInitializers(this, _selected_initializers, void 0));
        /**
         * @attribute
         */
        get selected() { return this.#selected_accessor_storage; }
        set selected(value) { this.#selected_accessor_storage = value; }
        constructor() {
            super();
            __runInitializers(this, _selected_extraInitializers);
            this.encapsulateHelp = false;
            this.selected = 'server';
        }
        updateName(value) {
            this.environment.info.name = value;
            this.notifyChange();
            Events.HttpProject.State.nameChanged(this.environment.key, this.environment.kind, this);
        }
        updateEncapsulated(value) {
            this.environment.encapsulated = value;
            this.notifyChange();
        }
        deleteServer() {
            this.environment.server = undefined;
            this.requestUpdate();
            this.notifyChange();
        }
        updateVariables(value) {
            if (value) {
                this.environment.variables = value;
            }
            this.notifyChange();
            // when modifying variables they won't be reflected in the server editor.
            const node = this.shadowRoot?.querySelector('server-editor');
            if (node) {
                node.generateValue();
            }
        }
        handleServerChange(e) {
            const editor = e.target;
            const value = editor.getSchema();
            this.environment.server = value;
            this.notifyChange();
        }
        handleVariableChange(e) {
            const editor = e.target;
            const { variables } = editor;
            this.updateVariables(variables);
        }
        _createServerHandler() {
            const server = new Server();
            this.environment.server = server.toJSON();
            this.requestUpdate();
        }
        handleEncapsulatedChange(e) {
            const input = e.target;
            this.updateEncapsulated(!!input.checked);
        }
        handleNameChange(e) {
            const input = e.target;
            this.updateName(input.value);
            input.checkValidity();
        }
        handleToggleHelp() {
            this.encapsulateHelp = !this.encapsulateHelp;
        }
        handleServerDelete() {
            this.deleteServer();
        }
        handleAuthAdd(e) {
            const target = e.detail.item;
            if (!target) {
                return;
            }
            const selected = target.dataset.type;
            if (!selected) {
                return;
            }
            this.addAuthorization(selected);
        }
        /**
         * Adds a new authorization object to the request for the given type.
         *
         * @returns The created instance of the authorization.
         */
        addAuthorization(type) {
            const cnf = RequestAuthorization.fromTypedConfig(type, {}, false);
            cnf.enabled = true;
            if (!this.environment.authorization) {
                this.environment.authorization = [];
            }
            this.environment.authorization.push(cnf.toJSON());
            this.notifyChange();
            this.requestUpdate();
            return cnf;
        }
        handleAuthChange(e) {
            const editor = e.target;
            const { authorization } = editor;
            this.updateAuthorization(authorization, editor.checkValidity());
        }
        handleAuthDelete(e) {
            const editor = e.target;
            const { authorization } = editor;
            if (!authorization) {
                return;
            }
            this.removeAuthorization(authorization.type);
        }
        /**
         * Updates authorization schema on the editor.
         * @param schema The new schema to replace the old one
         * @param isValid Whether the schema is valid.
         */
        updateAuthorization(schema, isValid) {
            const { authorization } = this.environment;
            if (!authorization) {
                return;
            }
            const index = authorization.findIndex((i) => i.type === schema.type);
            if (index === -1) {
                return;
            }
            schema.valid = isValid;
            authorization[index] = schema;
            this.notifyChange();
        }
        /**
         * Removes authorization schema from the editor.
         * @param type The authorization type to remove.
         */
        removeAuthorization(type) {
            const { authorization } = this.environment;
            if (!authorization) {
                return;
            }
            const index = authorization.findIndex((i) => i.type === type);
            if (index === -1) {
                return;
            }
            authorization.splice(index, 1);
            this.notifyChange();
            this.requestUpdate();
        }
        handleTabSelection(e) {
            const { page } = e.detail.item.dataset;
            if (!page) {
                return;
            }
            this.selected = page;
        }
        render() {
            return html ` ${this.renderHeader()} ${this.renderEnvironmentEditor()} ${this.renderTabs()} ${this.renderPage()} `;
        }
        renderHeader() {
            return html `<div class="section-title">Environment</div>`;
        }
        renderPage() {
            switch (this.selected) {
                case 'authorization':
                    return this.renderAuthorization();
                case 'variables':
                    return this.renderVariables();
                default:
                    return this.renderServerTemplate();
            }
        }
        renderEnvironmentEditor() {
            return html `
      <section aria-label="Environment configuration">${this.renderNameInput()} ${this.renderEncapsulate()}</section>
    `;
        }
        renderNameInput() {
            const { environment } = this;
            return html ` <div class="form-item">
      <ui-filled-text-field
        name="name"
        label="Environment name"
        required
        .value="${live(environment.info.name || '')}"
        @change="${this.handleNameChange}"
      ></ui-filled-text-field>
    </div>`;
        }
        renderEncapsulate() {
            const { encapsulateHelp } = this;
            return html `
      <div class="encapsulate-item">${this.renderEncapsulateInput()} ${this.renderEncapsulateInfoToggle()}</div>
      ${encapsulateHelp
                ? html `
            <div class="help-banner">
              By default when running requests in a folder the application reads all environments up to the project
              root. The variables are then combined into a single object. When <i>encapsulated</i> is enabled, the
              program stops reading environments above the folder the environment is defined.
            </div>
          `
                : ''}
    `;
        }
        renderEncapsulateInput() {
            const { environment } = this;
            return html `
      <label>
        <ui-switch
          name="encapsulated"
          .checked="${environment.encapsulated || false}"
          @change="${this.handleEncapsulatedChange}"
          aria-label="Encapsulate the environment"
        ></ui-switch>
        Encapsulate the environment
      </label>
    `;
        }
        renderEncapsulateInfoToggle() {
            return html `
      <ui-icon-button aria-label="Show or hide help topic" @click="${this.handleToggleHelp}">
        <ui-icon icon="info" role="presentation"></ui-icon>
      </ui-icon-button>
    `;
        }
        renderServerTemplate() {
            const { server } = this.environment;
            return html `
      <section aria-label="Server information" id="server" class="editor-container">
        ${server ? this.renderServerEditor(server) : this.renderNoServer()}
      </section>
    `;
        }
        renderNoServer() {
            return html `
      <div class="section-title">Server</div>
      <p class="empty-info">No server defined.</p>
      <ui-button color="tonal" @click="${this._createServerHandler}">Create server</ui-button>
    `;
        }
        renderServerEditor(server) {
            const { uri, basePath, description, protocol } = server;
            return html `
      <server-editor
        .uri="${uri}"
        .basePath="${basePath}"
        .description="${description}"
        .protocol="${protocol}"
        .variables="${this.environment.variables}"
        @change="${this.handleServerChange}"
        @delete="${this.handleServerDelete}"
      ></server-editor>
    `;
        }
        renderVariables() {
            return html `
      <section aria-label="Variables" id="variables" class="editor-container">${this.renderVariablesEditor()}</section>
    `;
        }
        renderVariablesEditor() {
            const { variables } = this.environment;
            return html `<variables-editor .variables="${variables}" @change="${this.handleVariableChange}"></variables-editor>`;
        }
        renderAuthorization() {
            const { authorization = [] } = this.environment;
            return html `
      <section id="authorization" aria-label="Authorization" class="editor-container">
        <div class="section-title">Authorization</div>
        <p class="auth-info">
          The authorization is applied to all requests in the current folder when the request is executed.
        </p>
        ${this.renderAuthorizationActions(authorization)} ${this.renderAuthorizationList(authorization)}
      </section>
    `;
        }
        renderAuthorizationActions(current = []) {
            const all = ['basic', 'oauth 2', 'open id', 'bearer', 'api key', 'ntlm', 'client certificate'];
            const toRender = all.filter((type) => !current.some((i) => i.type === type));
            return html `
      <ui-dropdown-list verticalAlign="top" @select="${this.handleAuthAdd}" class="auth-dropdown" closeOnOutsideClick>
        <ui-button
          color="tonal"
          title="Add authorization option"
          aria-label="Opens a menu to select authorization option"
          ?disabled="${!toRender.length}"
        >
          <ui-icon icon="arrowDropDown" slot="icon" role="presentation"></ui-icon>
          Add
        </ui-button>
        <ui-list slot="dropdown" role="menu"> ${this.renderAuthorizationOptions(toRender)} </ui-list>
      </ui-dropdown-list>
    `;
        }
        renderAuthorizationOptions(available) {
            return html `
      ${available.map((type) => html ` <ui-list-item role="menuitem" data-type="${type}"> ${authTypeToLabel(type)} </ui-list-item> `)}
    `;
        }
        renderAuthorizationList(authorization = []) {
            if (!Array.isArray(authorization) || !authorization.length) {
                return [this.renderEmptyAuthorization()];
            }
            return authorization.map((item, index) => {
                let content;
                switch (item.type) {
                    case 'basic':
                        content = this.renderBasicAuthorization(item);
                        break;
                    case 'bearer':
                        content = this.renderBearerAuthorization(item);
                        break;
                    case 'ntlm':
                        content = this.renderNtlmAuthorization(item);
                        break;
                    case 'oauth 2':
                        content = this.renderOauthAuthorization(item);
                        break;
                    case 'open id':
                        content = this.renderOidcAuthorization(item);
                        break;
                    case 'client certificate':
                        content = this.renderCCAuthorization(item);
                        break;
                    case 'api key':
                        content = this.renderApiKeyAuthorization(item);
                        break;
                    default:
                }
                if (content) {
                    const isLast = authorization.length === index + 1;
                    return html ` ${content} ${!isLast ? html `<ui-divider></ui-divider>` : ''} `;
                }
                return html ``;
            });
        }
        renderEmptyAuthorization() {
            return html ``;
        }
        renderBasicAuthorization(auth) {
            return html `
      <basic-authorization
        .authorization="${auth}"
        class="auth-panel"
        canDelete
        canToggle
        @change="${this.handleAuthChange}"
        @delete="${this.handleAuthDelete}"
      ></basic-authorization>
    `;
        }
        renderBearerAuthorization(auth) {
            return html `
      <bearer-authorization
        .authorization="${auth}"
        class="auth-panel"
        canDelete
        canToggle
        @change="${this.handleAuthChange}"
        @delete="${this.handleAuthDelete}"
      ></bearer-authorization>
    `;
        }
        renderNtlmAuthorization(auth) {
            return html `
      <ntlm-authorization
        .authorization="${auth}"
        class="auth-panel"
        canDelete
        canToggle
        @change="${this.handleAuthChange}"
        @delete="${this.handleAuthDelete}"
      ></ntlm-authorization>
    `;
        }
        renderOauthAuthorization(auth) {
            return html `
      <oauth2-authorization
        .authorization="${auth}"
        class="auth-panel"
        canDelete
        canToggle
        @change="${this.handleAuthChange}"
        @delete="${this.handleAuthDelete}"
        .defaultRedirectUri="${this.oauth2RedirectUri}"
      ></oauth2-authorization>
    `;
        }
        renderOidcAuthorization(auth) {
            return html `
      <oidc-authorization
        .authorization="${auth}"
        class="auth-panel"
        canDelete
        canToggle
        @change="${this.handleAuthChange}"
        @delete="${this.handleAuthDelete}"
        .defaultRedirectUri="${this.oauth2RedirectUri}"
      ></oidc-authorization>
    `;
        }
        renderCCAuthorization(auth) {
            return html `
      <cc-authorization
        .authorization="${auth}"
        class="auth-panel"
        canDelete
        canToggle
        @change="${this.handleAuthChange}"
        @delete="${this.handleAuthDelete}"
      ></cc-authorization>
    `;
        }
        renderApiKeyAuthorization(auth) {
            return html `
      <apikey-authorization
        .authorization="${auth}"
        class="auth-panel"
        canDelete
        canToggle
        @change="${this.handleAuthChange}"
        @delete="${this.handleAuthDelete}"
      ></apikey-authorization>
    `;
        }
        renderTabs() {
            const { selected: s } = this;
            return html `
      <ui-tabs @select="${this.handleTabSelection}">
        <ui-tab .selected="${s === 'server'}" aria-controls="server" data-page="server">Server</ui-tab>
        <ui-tab .selected="${s === 'variables'}" aria-controls="variables" data-page="variables">Variables</ui-tab>
        <ui-tab .selected="${s === 'authorization'}" aria-controls="authorization" data-page="authorization"
          >Authorization</ui-tab
        >
      </ui-tabs>
    `;
        }
    };
})();
/**
 * An element that renders a form to set up an environment.
 */
export default EnvironmentEditor;
//# sourceMappingURL=EnvironmentEditor.js.map