import { FlowRequestDataEnum, FlowResponseDataEnum, FlowSourceEnum, } from '@api-client/core/models/http-flows/HttpFlows.js';
import * as DataSteps from '@api-client/core/models/http-flows/steps/data/index.js';
import * as CoreAssertions from '@api-client/core/models/http-flows/steps/assertion/index.js';
import * as TransformationSteps from '@api-client/core/models/http-flows/steps/transformation/index.js';
import { AmfNamespace } from '@api-client/core/amf/definitions/Namespace.js';
import { live } from 'lit/directives/live.js';
import { html, nothing } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import ApiElement from '../ApiElement.js';
import '../../md/list/ui-list.js';
import '../../md/list/ui-list-item.js';
import '../../md/dropdown-list/ui-dropdown-list.js';
import '../../md/icons/ui-icon.js';
import '../../md/icon-button/ui-icon-button.js';
import '../../md/text-field/ui-filled-text-field.js';
import '../../md/chip/ui-chip.js';
import '../../md/dialog/ui-dialog.js';
import '../dialog/delete-cookie-action-dialog.js';
import '../dialog/set-cookie-action-dialog.js';
/**
 * The base UI class for HTTP flows and assertions
 * since they are practically the same concept.
 */
export class HttpFlowsUi extends ApiElement {
    /**
     * A chip that is currently being dragged in the UI.
     */
    draggedChip;
    /**
     * Checks whether the dragged element has the required content in the data transfer.
     */
    isValidDropTarget(dataTransfer) {
        if (!dataTransfer) {
            return false;
        }
        const { types } = dataTransfer;
        return types.includes('flow/group') && types.includes('flow/kind');
    }
    /**
     * Handles the suggestion chip drag start event.
     */
    handleChipDragStart(e) {
        const { dataTransfer } = e;
        if (!dataTransfer) {
            return;
        }
        const chip = e.target;
        const { group, kind, source, data, variant } = chip.dataset;
        if (!group || !kind) {
            return;
        }
        this.illustrateDraggedChip(chip, dataTransfer);
        dataTransfer.setData('flow/group', group);
        dataTransfer.setData('flow/kind', kind);
        dataTransfer.setData(`flow/${group}`, '');
        dataTransfer.setData(`flow/${kind}`, '');
        if (source) {
            dataTransfer.setData('flow/source', source);
        }
        if (data) {
            dataTransfer.setData('flow/data', data);
        }
        if (variant) {
            dataTransfer.setData('flow/variant', variant);
        }
        chip.blur();
    }
    /**
     * Handles the suggestion chip drag end event.
     */
    handleChipDragEnd(e) {
        const { draggedChip } = this;
        if (!draggedChip) {
            return;
        }
        e.preventDefault();
        draggedChip.parentElement?.removeChild(draggedChip);
    }
    /**
     * When interacting with a chip an MD ripple effect is generated.
     * This causes the default drag image to include the surrounding ripple effect and
     * everything around. This makes a copy of the chip and sets it as the drag image.
     *
     * Note, the copy of the chip has to be added to the DOM and be there for some time
     * so the browser render it and set as the image. Because of that the copy is removed
     * with the drop and not immediately.
     */
    illustrateDraggedChip(chip, dataTransfer) {
        const copy = chip.cloneNode(true);
        copy.style.position = 'absolute';
        copy.style.top = `-100px`;
        this.draggedChip = copy;
        document.body.appendChild(copy);
        dataTransfer.setDragImage(copy, 0, 0);
    }
    /**
     * Removes all `dragover` classes from elements on the shadow DOM.
     */
    resetDragIndices() {
        const nodes = this.shadowRoot.querySelectorAll('.dragover');
        Array.from(nodes).forEach((n) => n.classList.remove('dragover'));
    }
    /**
     * A handler for the `dragover` event over a valid target.
     * Sets the `dragover` class on the target.
     */
    handleTargetDragOver(e) {
        const { draggedChip } = this;
        if (!draggedChip || e.defaultPrevented || !this.isValidDropTarget(e.dataTransfer)) {
            return;
        }
        e.preventDefault();
        const dt = e.dataTransfer;
        dt.dropEffect = 'copy';
        const target = e.currentTarget;
        target.classList.add('dragover');
    }
    /**
     * A handler for the `dragleave` event over a valid target.
     * Removes the `dragover` class from the target.
     */
    handleTargetDragLeave(e) {
        if (e.defaultPrevented || !this.isValidDropTarget(e.dataTransfer)) {
            return;
        }
        const target = e.currentTarget;
        target.classList.remove('dragover');
    }
    /**
     * Reads the `data-index` and `data-step-index` from the target of the event
     * and calls the `processDrop()` with read values.
     */
    handleDrop(e) {
        const { dataTransfer } = e;
        if (!dataTransfer || e.defaultPrevented || !this.isValidDropTarget(dataTransfer)) {
            return;
        }
        e.preventDefault();
        this.resetDragIndices();
        const { index, stepIndex } = e.target.dataset;
        const assertionOrActionIndex = Number(index);
        if (Number.isNaN(assertionOrActionIndex)) {
            return;
        }
        let typedStepIndex;
        if (stepIndex) {
            const tmp = Number(stepIndex);
            if (!Number.isNaN(tmp)) {
                typedStepIndex = tmp;
            }
        }
        this.processDrop(dataTransfer, assertionOrActionIndex, typedStepIndex);
    }
    /**
     * A logic executed when a suggestion chip drop happens on a valid target.
     *
     * @param dataTransfer The event's dataTransfer object
     * @param assertionOrActionIndex Action's or assertion's index where the drop happened.
     * @param stepIndex The detected index of the step. When not set it adds the step at the end.
     */
    processDrop(dataTransfer, assertionOrActionIndex, stepIndex) {
        const group = dataTransfer.getData('flow/group');
        if (!group) {
            return;
        }
        if (group === 'data-source') {
            this.processDataSourceDrop(dataTransfer, assertionOrActionIndex, stepIndex);
        }
        else if (group === 'transformation') {
            this.processTransformationDrop(dataTransfer, assertionOrActionIndex, stepIndex);
        }
        else if (group === 'assertion') {
            this.processAssertionDrop(dataTransfer, assertionOrActionIndex, stepIndex);
        }
        else if (group === 'action') {
            this.processActionDrop(dataTransfer, assertionOrActionIndex, stepIndex);
        }
    }
    /**
     * Processes dropping of a `data-source` suggestion chip.
     */
    processDataSourceDrop(dataTransfer, assertionOrActionIndex, stepIndex) {
        const target = this.getStepsTarget(assertionOrActionIndex);
        if (!target) {
            return;
        }
        this.setupDataSource(target, dataTransfer, stepIndex);
    }
    /**
     * Processes dropping of a `transformation` suggestion chip.
     */
    processTransformationDrop(dataTransfer, assertionOrActionIndex, stepIndex) {
        const target = this.getStepsTarget(assertionOrActionIndex);
        if (!target) {
            return;
        }
        this.setupTransformation(target, dataTransfer, stepIndex);
    }
    /**
     * Processes dropping of a `assertion` suggestion chip.
     */
    processAssertionDrop(dataTransfer, assertionOrActionIndex, stepIndex) {
        const target = this.getStepsTarget(assertionOrActionIndex);
        if (!target) {
            return;
        }
        this.setupAssertion(target, dataTransfer, stepIndex);
    }
    /**
     * Processes dropping of a `action` suggestion chip.
     */
    processActionDrop(dataTransfer, assertionOrActionIndex, stepIndex) {
        const target = this.getStepsTarget(assertionOrActionIndex);
        if (!target) {
            return;
        }
        this.setupAction(target, dataTransfer, stepIndex);
    }
    setupDataSource(target, dataTransfer, stepIndex) {
        const source = dataTransfer.getData('flow/source');
        const data = dataTransfer.getData('flow/data');
        const step = new DataSteps.ReadDataSourceStep(source, data).toJSON();
        this.appendStep(step, target, stepIndex);
    }
    setupTransformation(target, dataTransfer, stepIndex) {
        let step;
        const kind = dataTransfer.getData('flow/kind');
        if (kind === DataSteps.ReadValueStepKind) {
            step = new DataSteps.ReadValueStep().toJSON();
        }
        else if (kind === TransformationSteps.AsNumberStepKind) {
            step = new TransformationSteps.AsNumberStep().toJSON();
        }
        else if (kind === TransformationSteps.RoundStepKind) {
            step = new TransformationSteps.RoundStep().toJSON();
        }
        else if (kind === TransformationSteps.AsLowerCaseStepKind) {
            step = new TransformationSteps.AsLowerCaseStep().toJSON();
        }
        else if (kind === TransformationSteps.AsUpperCaseStepKind) {
            step = new TransformationSteps.AsUpperCaseStep().toJSON();
        }
        else if (kind === TransformationSteps.TrimStepKind) {
            step = new TransformationSteps.TrimStep().toJSON();
        }
        else if (kind === TransformationSteps.SubstringStepKind) {
            step = new TransformationSteps.SubstringStep().toJSON();
        }
        if (!step) {
            return;
        }
        this.appendStep(step, target, stepIndex);
    }
    setupAssertion(target, dataTransfer, stepIndex) {
        let step;
        const kind = dataTransfer.getData('flow/kind');
        if (kind === CoreAssertions.EqualAssertionKind) {
            step = new CoreAssertions.EqualAssertion().toJSON();
        }
        else if (kind === CoreAssertions.NotEqualAssertionKind) {
            step = new CoreAssertions.NotEqualAssertion().toJSON();
        }
        else if (kind === CoreAssertions.GreaterThanAssertionKind) {
            const instance = new CoreAssertions.GreaterThanAssertion();
            if (dataTransfer.getData('flow/variant') === 'equal') {
                instance.equal = true;
            }
            step = instance.toJSON();
        }
        else if (kind === CoreAssertions.LessThanAssertionKind) {
            const instance = new CoreAssertions.LessThanAssertion();
            if (dataTransfer.getData('flow/variant') === 'equal') {
                instance.equal = true;
            }
            step = instance.toJSON();
        }
        else if (kind === CoreAssertions.IncludesAssertionKind) {
            step = new CoreAssertions.IncludesAssertion().toJSON();
        }
        else if (kind === CoreAssertions.NotIncludesAssertionKind) {
            step = new CoreAssertions.NotIncludesAssertion().toJSON();
        }
        else if (kind === CoreAssertions.MatchesAssertionKind) {
            step = new CoreAssertions.MatchesAssertion().toJSON();
        }
        else if (kind === CoreAssertions.OkAssertionKind) {
            step = new CoreAssertions.OkAssertion().toJSON();
        }
        else if (kind === CoreAssertions.NotOkAssertionKind) {
            step = new CoreAssertions.NotOkAssertion().toJSON();
        }
        else if (kind === CoreAssertions.ToBeAssertionKind) {
            step = new CoreAssertions.ToBeAssertion().toJSON();
        }
        else if (kind === CoreAssertions.NotToBeAssertionKind) {
            step = new CoreAssertions.NotToBeAssertion().toJSON();
        }
        if (!step) {
            return;
        }
        this.appendStep(step, target, stepIndex);
    }
    setupAction(target, dataTransfer, stepIndex) {
        let step;
        const kind = dataTransfer.getData('flow/kind');
        if (kind === DataSteps.SetCookieStepKind) {
            step = new DataSteps.SetCookieStep().toJSON();
        }
        else if (kind === DataSteps.SetVariableStepKind) {
            step = new DataSteps.SetVariableStep().toJSON();
        }
        else if (kind === DataSteps.DeleteCookieStepKind) {
            step = new DataSteps.DeleteCookieStep().toJSON();
        }
        else if (kind === DataSteps.DeleteVariableStepKind) {
            step = new DataSteps.DeleteVariableStep().toJSON();
        }
        if (!step) {
            return;
        }
        this.appendStep(step, target, stepIndex);
    }
    appendStep(step, target, stepIndex) {
        if (stepIndex === undefined) {
            target.steps.push(step);
        }
        else if (stepIndex === -1) {
            target.steps.unshift(step);
        }
        else {
            target.steps.splice(stepIndex, 0, step);
        }
        this.requestUpdate();
        this.notifyChange();
    }
    removeStep(target, stepIndex) {
        target.steps.splice(stepIndex, 1);
        this.notifyChange();
        this.requestUpdate();
    }
    handleSubstringStartChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        input.checkValidity();
        step.start = input.valueAsNumber;
        this.requestUpdate();
        this.notifyChange();
    }
    handleSubstringEndChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        input.checkValidity();
        step.end = input.valueAsNumber;
        this.requestUpdate();
        this.notifyChange();
    }
    handleRoundPrecisionChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        input.checkValidity();
        step.precision = input.valueAsNumber;
        this.requestUpdate();
        this.notifyChange();
    }
    handleReadValueStepChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        input.checkValidity();
        step.path = input.value;
        this.requestUpdate();
        this.notifyChange();
    }
    handleGreaterThanAssertionValueChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        input.checkValidity();
        step.value = Number(input.value);
        this.requestUpdate();
        this.notifyChange();
    }
    handleLessThanAssertionValueChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        input.checkValidity();
        step.value = Number(input.value);
        this.requestUpdate();
        this.notifyChange();
    }
    handleIncludesAssertionValueChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        input.checkValidity();
        step.value = input.value;
        this.requestUpdate();
        this.notifyChange();
    }
    handleToBeAssertionValueChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        input.checkValidity();
        step.value = input.value;
        this.requestUpdate();
        this.notifyChange();
    }
    handleMatchesAssertionValueChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        step.value = input.value;
        this.requestUpdate();
        this.notifyChange();
    }
    handleEqualAssertionValueChange(e) {
        const input = e.target;
        input.checkValidity();
        const assertionOrActionIndex = Number(input.dataset.assertionIndex);
        const stepIndex = Number(input.dataset.stepIndex);
        if (Number.isNaN(assertionOrActionIndex) || Number.isNaN(stepIndex)) {
            return;
        }
        const stepsTarget = this.getStepsTarget(assertionOrActionIndex);
        if (!stepsTarget) {
            return;
        }
        const step = stepsTarget.steps[stepIndex];
        if (!step) {
            return;
        }
        step.value = input.value;
        step.dataType = this.detectInputDataType(stepsTarget.steps.slice(0, stepIndex));
        this.requestUpdate();
        this.notifyChange();
    }
    /**
     * Detects the correct data type for the step value based on previous steps.
     *
     * @param steps The steps before the current step
     * @returns The data type for the step in the AMF namespace.
     */
    detectInputDataType(steps) {
        // we reverse the list so we move from the last step.
        const reversed = [...steps].reverse();
        for (const step of reversed) {
            if (step.kind === TransformationSteps.AsNumberStepKind) {
                return AmfNamespace.aml.vocabularies.shapes.number;
            }
            if (step.kind === DataSteps.ReadDataSourceStepKind) {
                const typed = step;
                if (typed.data === FlowResponseDataEnum.status) {
                    return AmfNamespace.aml.vocabularies.shapes.number;
                }
            }
        }
        return AmfNamespace.w3.xmlSchema.string;
    }
    validateRegexPattern(e) {
        const input = e.target;
        try {
            RegExp(input.value);
            input.setCustomValidity('');
        }
        catch {
            input.setCustomValidity('Pattern is invalid');
        }
        input.reportValidity();
    }
    handleVariableNameChange(e) {
        const step = this.stepFromChangeEvent(e);
        if (!step) {
            return;
        }
        const input = e.target;
        step.name = input.value;
        this.requestUpdate();
        this.notifyChange();
    }
    handleRemoveStep(e) {
        const target = e.currentTarget;
        const assertionOrActionIndex = Number(target.dataset.index);
        const stepIndex = Number(target.dataset.stepIndex);
        if (Number.isNaN(assertionOrActionIndex) || Number.isNaN(stepIndex)) {
            return;
        }
        const stepsTarget = this.getStepsTarget(assertionOrActionIndex);
        if (!stepsTarget) {
            return;
        }
        this.removeStep(stepsTarget, stepIndex);
    }
    handleConfigureDeleteCookieStep(e) {
        const info = this.getEventStepLocation(e);
        if (!info) {
            return;
        }
        const stepsTarget = this.getStepsTarget(info.actionIndex);
        if (!stepsTarget) {
            return;
        }
        const step = stepsTarget.steps[info.stepIndex];
        const dialog = document.createElement('delete-cookie-action-dialog');
        dialog.step = step;
        dialog.modal = true;
        dialog.open = true;
        document.body.appendChild(dialog);
        dialog.addEventListener('close', (ev) => {
            document.parentElement?.removeChild(dialog);
            const typed = ev;
            if (typed.detail.cancelled) {
                return;
            }
            const value = typed.detail.value;
            if (!stepsTarget) {
                return;
            }
            stepsTarget.steps[info.stepIndex] = value;
            this.notifyChange();
            this.requestUpdate();
        });
    }
    handleConfigureSetCookieStep(e) {
        const info = this.getEventStepLocation(e);
        if (!info) {
            return;
        }
        const stepsTarget = this.getStepsTarget(info.actionIndex);
        if (!stepsTarget) {
            return;
        }
        const step = stepsTarget.steps[info.stepIndex];
        const dialog = document.createElement('set-cookie-action-dialog');
        dialog.step = step;
        dialog.modal = true;
        dialog.open = true;
        document.body.appendChild(dialog);
        dialog.addEventListener('close', (ev) => {
            document.parentElement?.removeChild(dialog);
            const typed = ev;
            if (typed.detail.cancelled) {
                return;
            }
            const value = typed.detail.value;
            if (!stepsTarget) {
                return;
            }
            stepsTarget.steps[info.stepIndex] = value;
            this.notifyChange();
            this.requestUpdate();
        });
    }
    getEventStepLocation(e) {
        const button = e.currentTarget;
        const { index: ai, stepIndex: si } = button.dataset;
        const actionIndex = Number(ai);
        const stepIndex = Number(si);
        if (Number.isNaN(actionIndex) || Number.isNaN(stepIndex)) {
            return undefined;
        }
        return {
            actionIndex,
            stepIndex,
        };
    }
    renderBlockChip(label, group, kind, opts = {}) {
        const { data, disabled, source, variant, title } = opts;
        return html `
      <ui-chip
        draggable="true"
        data-group="${group}"
        data-kind="${kind}"
        data-source="${ifDefined(source)}"
        data-data="${ifDefined(data)}"
        data-variant="${ifDefined(variant)}"
        @dragstart="${this.handleChipDragStart}"
        @dragend="${this.handleChipDragEnd}"
        ?disabled="${disabled}"
        title="${ifDefined(title)}"
        >${label}</ui-chip
      >
    `;
    }
    renderDropSpacer(assertionOrActionIndex, stepIndex) {
        return html `<div
      class="drop-target spacer"
      data-index="${assertionOrActionIndex}"
      data-step-index="${stepIndex}"
      @drop="${this.handleDrop}"
      @dragover="${this.handleTargetDragOver}"
      @dragleave="${this.handleTargetDragLeave}"
    ></div>`;
    }
    renderStepPill(label, assertionOrActionIndex, stepIndex, suffix) {
        return html `
      <span class="step-pill with-icon">
        ${label} ${suffix || nothing}
        <ui-icon-button
          title="Remove"
          aria-label="Deletes this step"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </span>
    `;
    }
    renderSteps(item, assertionOrActionIndex) {
        const content = Array.isArray(item.steps) && !!item.steps.length
            ? this.renderStepsList(item.steps, assertionOrActionIndex)
            : this.renderEmptyStep(assertionOrActionIndex);
        return html `
      <div
        class="steps"
        data-index="${assertionOrActionIndex}"
        @drop="${this.handleDrop}"
        @dragover="${this.handleTargetDragOver}"
        @dragleave="${this.handleTargetDragLeave}"
      >
        ${content}
      </div>
    `;
    }
    renderEmptyStep(actionIndex) {
        return html `
      <span
        class="step-pill empty drop-target space-step-left"
        data-index="${actionIndex}"
        @drop="${this.handleDrop}"
        @dragover="${this.handleTargetDragOver}"
        >Empty slot</span
      >
      <span
        class="drop-info drop-target space-step-left"
        data-index="${actionIndex}"
        @drop="${this.handleDrop}"
        @dragover="${this.handleTargetDragOver}"
        >Drop an action here</span
      >
    `;
    }
    renderStepsList(steps, assertionOrActionIndex) {
        const items = [];
        steps.forEach((item, stepIndex) => {
            const content = this.renderStep(item, assertionOrActionIndex, stepIndex);
            if (content) {
                items.push(html `
          <div class="step-unit">${this.renderDropSpacer(assertionOrActionIndex, stepIndex)} ${content}</div>
        `);
            }
        });
        return items;
    }
    renderStep(item, assertionOrActionIndex, stepIndex) {
        const { kind } = item;
        switch (kind) {
            // actions
            case DataSteps.ReadDataSourceStepKind:
                return this.renderReadDataSourceStep(item, assertionOrActionIndex, stepIndex);
            case DataSteps.ReadValueStepKind:
                return this.renderReadValueStep(item, assertionOrActionIndex, stepIndex);
            case DataSteps.DeleteCookieStepKind:
                return this.renderDeleteCookieStep(item, assertionOrActionIndex, stepIndex);
            case DataSteps.SetCookieStepKind:
                return this.renderSetCookieStep(item, assertionOrActionIndex, stepIndex);
            case DataSteps.SetVariableStepKind:
                return this.renderSetVariableStep(item, assertionOrActionIndex, stepIndex);
            case DataSteps.DeleteVariableStepKind:
                return this.renderDeleteVariableStep(item, assertionOrActionIndex, stepIndex);
            // transformations
            case TransformationSteps.AsNumberStepKind:
                return this.renderStepPill('As number', assertionOrActionIndex, stepIndex);
            case TransformationSteps.AsLowerCaseStepKind:
                return this.renderStepPill('To lower case', assertionOrActionIndex, stepIndex);
            case TransformationSteps.AsUpperCaseStepKind:
                return this.renderStepPill('To upper case', assertionOrActionIndex, stepIndex);
            case TransformationSteps.TrimStepKind:
                return this.renderStepPill('Trim', assertionOrActionIndex, stepIndex);
            case TransformationSteps.RoundStepKind:
                return this.renderRoundStep(item, assertionOrActionIndex, stepIndex);
            case TransformationSteps.SubstringStepKind:
                return this.renderSubstringStep(item, assertionOrActionIndex, stepIndex);
            // assertions
            case CoreAssertions.EqualAssertionKind:
                return this.renderEqualAssertion(item, assertionOrActionIndex, stepIndex);
            case CoreAssertions.NotEqualAssertionKind:
                return this.renderNotEqualAssertion(item, assertionOrActionIndex, stepIndex);
            case CoreAssertions.GreaterThanAssertionKind:
                return this.renderGreaterThanAssertion(item, assertionOrActionIndex, stepIndex);
            case CoreAssertions.LessThanAssertionKind:
                return this.renderLessThanAssertion(item, assertionOrActionIndex, stepIndex);
            case CoreAssertions.IncludesAssertionKind:
                return this.renderIncludesAssertion(item, assertionOrActionIndex, stepIndex);
            case CoreAssertions.NotIncludesAssertionKind:
                return this.renderNotIncludesAssertion(item, assertionOrActionIndex, stepIndex);
            case CoreAssertions.MatchesAssertionKind:
                return this.renderMatchesAssertion(item, assertionOrActionIndex, stepIndex);
            case CoreAssertions.OkAssertionKind:
                return this.renderStepPill('Is OK', assertionOrActionIndex, stepIndex);
            case CoreAssertions.NotOkAssertionKind:
                return this.renderStepPill('Is not OK', assertionOrActionIndex, stepIndex);
            case CoreAssertions.ToBeAssertionKind:
                return this.renderToBeAssertion(item, assertionOrActionIndex, stepIndex);
            case CoreAssertions.NotToBeAssertionKind:
                return this.renderNotToBeAssertion(item, assertionOrActionIndex, stepIndex);
            default:
                // eslint-disable-next-line no-console
                console.warn(`Unsupported step`, kind);
                return undefined;
        }
    }
    renderReadDataSourceStep(item, actionIndex, stepIndex) {
        const { data, source } = item;
        if (!data || !source) {
            // invalid configuration
            return undefined;
        }
        let label;
        if (source === FlowSourceEnum.response) {
            if (data === FlowResponseDataEnum.url) {
                label = 'Response URL';
            }
            else if (data === FlowResponseDataEnum.headers) {
                label = 'Response headers';
            }
            else if (data === FlowResponseDataEnum.status) {
                label = 'Status code';
            }
            else if (data === FlowResponseDataEnum.statusText) {
                label = 'Status message';
            }
            else if (data === FlowResponseDataEnum.body) {
                label = 'Response body';
            }
        }
        else if (source === FlowSourceEnum.request) {
            if (data === FlowRequestDataEnum.url) {
                label = 'Request URL';
            }
            else if (data === FlowRequestDataEnum.headers) {
                label = 'Request headers';
            }
            else if (data === FlowRequestDataEnum.body) {
                label = 'Request body';
            }
            else if (data === FlowRequestDataEnum.method) {
                label = 'Request method';
            }
        }
        if (!label) {
            return undefined;
        }
        return this.renderStepPill(label, actionIndex, stepIndex);
    }
    renderReadValueStep(item, assertionOrActionIndex, stepIndex) {
        const pill = this.renderStepPill('Read value', assertionOrActionIndex, stepIndex);
        return html `
      ${pill}
      <ui-filled-text-field
        name="value.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        label="Path to value"
        required
        .value="${live(item.path || '')}"
        class="space-step-left"
        @change="${this.handleReadValueStepChange}"
      ></ui-filled-text-field>
    `;
    }
    renderDeleteCookieStep(item, assertionOrActionIndex, stepIndex) {
        const { name, url } = item;
        let label;
        if (name && url) {
            label = 'by name and URL';
        }
        else if (name) {
            label = 'by name';
        }
        else if (url) {
            label = 'by URL';
        }
        else {
            label = 'all cookies';
        }
        const suffix = html `
      <ui-icon-button
        title="Configure this step"
        aria-label="Configure this step"
        data-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        @click="${this.handleConfigureDeleteCookieStep}"
        ><ui-icon icon="tune" role="presentation"></ui-icon
      ></ui-icon-button>
    `;
        const pill = this.renderStepPill(`Delete cookie (${label})`, assertionOrActionIndex, stepIndex, suffix);
        return pill;
    }
    renderSetCookieStep(item, assertionOrActionIndex, stepIndex) {
        const suffix = html `
      <ui-icon-button
        title="Configure this step"
        aria-label="Configure this step"
        data-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        @click="${this.handleConfigureSetCookieStep}"
        ><ui-icon icon="tune" role="presentation"></ui-icon
      ></ui-icon-button>
    `;
        const pill = this.renderStepPill('Set cookie', assertionOrActionIndex, stepIndex, suffix);
        return pill;
    }
    renderSetVariableStep(item, assertionOrActionIndex, stepIndex) {
        const { name = '' } = item;
        const pill = this.renderStepPill('Set variable', assertionOrActionIndex, stepIndex);
        return html `
      ${pill}
      <ui-filled-text-field
        name="variable.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        label="Variable name"
        required
        .value="${live(name)}"
        @change="${this.handleVariableNameChange}"
        class="space-step-left"
        pattern="[a-zA-Z0-9_]+"
        aria-label="Variable name"
      ></ui-filled-text-field>
    `;
    }
    renderDeleteVariableStep(item, assertionOrActionIndex, stepIndex) {
        const { name = '' } = item;
        const pill = this.renderStepPill('Delete variable', assertionOrActionIndex, stepIndex);
        return html `
      ${pill}
      <ui-filled-text-field
        name="variable.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        label="Variable name"
        required
        .value="${live(name)}"
        @change="${this.handleVariableNameChange}"
        class="space-step-left"
        pattern="[a-zA-Z0-9_]+"
        aria-label="Variable name"
      ></ui-filled-text-field>
    `;
    }
    renderRoundStep(item, assertionOrActionIndex, stepIndex) {
        const pill = this.renderStepPill('Round', assertionOrActionIndex, stepIndex);
        const { precision = 0 } = item;
        return html `
      ${pill}
      <ui-filled-text-field
        name="precision.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        label="Precision"
        required
        .value="${live(String(precision))}"
        @change="${this.handleRoundPrecisionChange}"
        class="space-step-left number-input"
        type="number"
        min="0"
        max="100"
        step="1"
        title="The number of digits to appear after the decimal point. Should be a value between 0 and 100, inclusive."
      ></ui-filled-text-field>
    `;
    }
    renderSubstringStep(item, assertionOrActionIndex, stepIndex) {
        const pill = this.renderStepPill('Substring', assertionOrActionIndex, stepIndex);
        const { start = 0, end } = item;
        return html `
      ${pill}
      <ui-filled-text-field
        name="start.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        label="Start"
        required
        .value="${live(String(start))}"
        @change="${this.handleSubstringStartChange}"
        class="space-step-left number-input"
        type="number"
        step="1"
        title="The index of the first character to include in the returned substring."
      ></ui-filled-text-field>

      <ui-filled-text-field
        name="end.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        label="End"
        .value="${live(end ? String(end) : '')}"
        @change="${this.handleSubstringEndChange}"
        class="space-step-left number-input"
        type="number"
        step="1"
        title="The index of the first character to exclude from the returned substring."
      ></ui-filled-text-field>
    `;
    }
    renderEqualAssertion(item, assertionOrActionIndex, stepIndex) {
        return html `
      <ui-filled-text-field
        name="equal.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.EqualAssertionKind}"
        label="Equal to"
        required
        .value="${live(item.value || '')}"
        @change="${this.handleEqualAssertionValueChange}"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderNotEqualAssertion(item, assertionOrActionIndex, stepIndex) {
        return html `
      <ui-filled-text-field
        name="not-equal.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.NotEqualAssertionKind}"
        label="Not equal to"
        required
        .value="${live(item.value || '')}"
        @change="${this.handleEqualAssertionValueChange}"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderGreaterThanAssertion(item, assertionOrActionIndex, stepIndex) {
        const { equal, value } = item;
        const label = equal ? 'Greater than equal' : 'Greater than';
        const effectiveValue = typeof value === 'number' ? String(value) : '';
        return html `
      <ui-filled-text-field
        name="value.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.GreaterThanAssertionKind}"
        data-variant="${equal ? 'equal' : ''}"
        label="${label}"
        required
        .value="${live(effectiveValue)}"
        @change="${this.handleGreaterThanAssertionValueChange}"
        inputMode="numeric"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderLessThanAssertion(item, assertionOrActionIndex, stepIndex) {
        const { equal, value } = item;
        const label = equal ? 'Less than equal' : 'Less than';
        const effectiveValue = typeof value === 'number' ? String(value) : '';
        return html `
      <ui-filled-text-field
        name="value.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.LessThanAssertionKind}"
        data-variant="${equal ? 'equal' : ''}"
        label="${label}"
        required
        .value="${live(effectiveValue)}"
        @change="${this.handleLessThanAssertionValueChange}"
        inputMode="numeric"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderIncludesAssertion(item, assertionOrActionIndex, stepIndex) {
        const { value } = item;
        return html `
      <ui-filled-text-field
        name="includes.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.IncludesAssertionKind}"
        label="Includes value"
        required
        .value="${live(value || '')}"
        @change="${this.handleIncludesAssertionValueChange}"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderNotIncludesAssertion(item, assertionOrActionIndex, stepIndex) {
        const { value } = item;
        return html `
      <ui-filled-text-field
        name="not-includes.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.NotIncludesAssertionKind}"
        label="Not includes value"
        required
        .value="${live(value || '')}"
        @change="${this.handleIncludesAssertionValueChange}"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderMatchesAssertion(item, assertionOrActionIndex, stepIndex) {
        const { value } = item;
        return html `
      <ui-filled-text-field
        name="matches.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.MatchesAssertionKind}"
        label="Matches regex"
        required
        .value="${live(value || '')}"
        @change="${this.handleMatchesAssertionValueChange}"
        @input="${this.validateRegexPattern}"
        invalidText="Pattern is invalid"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderToBeAssertion(item, assertionOrActionIndex, stepIndex) {
        const { value } = item;
        const types = Object.values(CoreAssertions.ToBeTypes);
        return html `
      <ui-filled-text-field
        name="to-be.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.ToBeAssertionKind}"
        label="To be..."
        required
        .value="${live(value || '')}"
        @change="${this.handleToBeAssertionValueChange}"
        .list="${types}"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderNotToBeAssertion(item, assertionOrActionIndex, stepIndex) {
        const { value } = item;
        const types = Object.values(CoreAssertions.ToBeTypes);
        return html `
      <ui-filled-text-field
        name="not-to-be.${assertionOrActionIndex}.${stepIndex}"
        data-assertion-index="${assertionOrActionIndex}"
        data-step-index="${stepIndex}"
        data-kind="${CoreAssertions.NotToBeAssertionKind}"
        label="Not to be..."
        required
        .value="${live(value || '')}"
        @change="${this.handleToBeAssertionValueChange}"
        .list="${types}"
      >
        <ui-icon-button
          slot="suffix"
          title="Remove assertion"
          aria-label="Deletes this assertion"
          @click="${this.handleRemoveStep}"
          data-index="${assertionOrActionIndex}"
          data-step-index="${stepIndex}"
          ><ui-icon icon="close" role="presentation"></ui-icon
        ></ui-icon-button>
      </ui-filled-text-field>
    `;
    }
    renderResponseDataSourceSuggestions(disabled = false) {
        return html `
      <details class="action-group" open>
        <summary>Data Source</summary>
        <div class="group-content">
          ${this.renderBlockChip('Status code', 'data-source', DataSteps.ReadDataSourceStepKind, {
            source: FlowSourceEnum.response,
            data: FlowResponseDataEnum.status,
            disabled,
            title: 'Reads the response status code and passes it to the next step.',
        })}
          ${this.renderBlockChip('Response headers', 'data-source', DataSteps.ReadDataSourceStepKind, {
            source: FlowSourceEnum.response,
            data: FlowResponseDataEnum.headers,
            disabled,
            title: 'Reads the response headers and passes them to the next step.',
        })}
          ${this.renderBlockChip('Response body', 'data-source', DataSteps.ReadDataSourceStepKind, {
            source: FlowSourceEnum.response,
            data: FlowResponseDataEnum.body,
            disabled,
            title: 'Reads the response body and passes it to the next step.',
        })}
          ${this.renderBlockChip('Status message', 'data-source', DataSteps.ReadDataSourceStepKind, {
            source: FlowSourceEnum.response,
            data: FlowResponseDataEnum.statusText,
            disabled,
            title: 'Reads the response status message and passes it to the next step.',
        })}
        </div>
      </details>
    `;
    }
    renderRequestDataSourceSuggestions(disabled = false) {
        return html `
      <details class="action-group" open>
        <summary>Data Source</summary>
        <div class="group-content">
          ${this.renderBlockChip('Request headers', 'data-source', DataSteps.ReadDataSourceStepKind, {
            source: FlowSourceEnum.request,
            data: FlowRequestDataEnum.headers,
            disabled,
            title: 'Reads the request headers and passes them to the next step.',
        })}
          ${this.renderBlockChip('Request body', 'data-source', DataSteps.ReadDataSourceStepKind, {
            source: FlowSourceEnum.request,
            data: FlowRequestDataEnum.body,
            disabled,
            title: 'Reads the request body and passes it to the next step.',
        })}
          ${this.renderBlockChip('Request method', 'data-source', DataSteps.ReadDataSourceStepKind, {
            source: FlowSourceEnum.request,
            data: FlowRequestDataEnum.method,
            disabled,
            title: 'Reads the request method and passes it to the next step.',
        })}
        </div>
      </details>
    `;
    }
    renderTransformationSuggestions(disabled = false) {
        return html `
      <details class="action-group" open>
        <summary>Transformation</summary>
        <div class="group-content">
          ${this.renderBlockChip('Read value', 'transformation', DataSteps.ReadValueStepKind, {
            disabled,
            title: 'Reads a value from the previous step. Configure the path to the value.',
        })}
          ${this.renderBlockChip('As number', 'transformation', TransformationSteps.AsNumberStepKind, {
            disabled,
            title: 'Transforms the value received from the previous step to a number.',
        })}
          ${this.renderBlockChip('Round', 'transformation', TransformationSteps.RoundStepKind, {
            disabled,
            title: 'Rounds the value received from the previous step with a precision',
        })}
          ${this.renderBlockChip('To lower case', 'transformation', TransformationSteps.AsLowerCaseStepKind, {
            disabled,
            title: 'Transforms the value received from the previous step to a lower case string',
        })}
          ${this.renderBlockChip('To upper case', 'transformation', TransformationSteps.AsUpperCaseStepKind, {
            disabled,
            title: 'Transforms the value received from the previous step to an upper case string',
        })}
          ${this.renderBlockChip('Trim', 'transformation', TransformationSteps.TrimStepKind, {
            disabled,
            title: 'Treats the value received from the previous step as string as trims the whitespace.',
        })}
          ${this.renderBlockChip('Substring', 'transformation', TransformationSteps.SubstringStepKind, {
            disabled,
            title: 'Passes a sub string of the current value to the next step.',
        })}
        </div>
      </details>
    `;
    }
    renderActionSuggestions(disabled = false) {
        return html `
      <details class="action-group" open>
        <summary>Actions</summary>
        <div class="group-content">
          ${this.renderBlockChip('Set cookie', 'action', DataSteps.SetCookieStepKind, {
            disabled,
            title: 'Sets and stores a cookie',
        })}
          ${this.renderBlockChip('Delete cookie', 'action', DataSteps.DeleteCookieStepKind, {
            disabled,
            title: 'Deletes a cookie.',
        })}
          ${this.renderBlockChip('Set variable', 'action', DataSteps.SetVariableStepKind, {
            disabled,
            title: 'Sets a variable during the execution time. It does not store the value.',
        })}
          ${this.renderBlockChip('Unset variable', 'action', DataSteps.DeleteVariableStepKind, {
            disabled,
            title: 'Clears a variable during the execution time. It does not store the value.',
        })}
        </div>
      </details>
    `;
    }
    renderAssertionSuggestions(disabled = false) {
        return html `
      <details class="action-group" open>
        <summary>Assertions</summary>
        <div class="group-content">
          ${this.renderBlockChip('Equal', 'assertion', CoreAssertions.EqualAssertionKind, { disabled })}
          ${this.renderBlockChip('Not equal', 'assertion', CoreAssertions.NotEqualAssertionKind, { disabled })}
          ${this.renderBlockChip('Greater than', 'assertion', CoreAssertions.GreaterThanAssertionKind, { disabled })}
          ${this.renderBlockChip('Greater than equal', 'assertion', CoreAssertions.GreaterThanAssertionKind, {
            disabled,
            variant: 'equal',
        })}
          ${this.renderBlockChip('Less than', 'assertion', CoreAssertions.LessThanAssertionKind, { disabled })}
          ${this.renderBlockChip('Less than equal', 'assertion', CoreAssertions.LessThanAssertionKind, {
            disabled,
            variant: 'equal',
        })}
          ${this.renderBlockChip('Includes', 'assertion', CoreAssertions.IncludesAssertionKind, { disabled })}
          ${this.renderBlockChip('Not includes', 'assertion', CoreAssertions.NotIncludesAssertionKind, { disabled })}
          ${this.renderBlockChip('Matches', 'assertion', CoreAssertions.MatchesAssertionKind, { disabled })}
          ${this.renderBlockChip('OK', 'assertion', CoreAssertions.OkAssertionKind, { disabled })}
          ${this.renderBlockChip('Not OK', 'assertion', CoreAssertions.NotOkAssertionKind, { disabled })}
          ${this.renderBlockChip('To be...', 'assertion', CoreAssertions.ToBeAssertionKind, { disabled })}
          ${this.renderBlockChip('Not to be...', 'assertion', CoreAssertions.NotToBeAssertionKind, { disabled })}
        </div>
      </details>
    `;
    }
}
//# sourceMappingURL=HttpFlowsUi.js.map