{{!
  Copyright IBM Corp. 2016, 2025
  SPDX-License-Identifier: BUSL-1.1
}}

{{! template-lint-configure simple-unless "warn" }}
<div class="field" data-test-field={{@attr.name}}>
  {{#if this.isHdsFormField}}
    {{! •••••••••••••••••••••••••••••••••••••••••••••••••••••••• }}
    {{!                  HDS COMPONENTS - START                  }}
    {{! •••••••••••••••••••••••••••••••••••••••••••••••••••••••• }}
    {{#if @attr.options.possibleValues}}
      {{#if (eq @attr.options.editType "radio")}}
        <Hds::Form::Radio::Group
          @name={{@attr.name}}
          @layout={{if (or this.hasRadioSubText this.hasRadioHelpText) "vertical" "horizontal"}}
          data-test-input-group={{@attr.name}}
          as |G|
        >
          <G.Legend data-test-form-field-label={{@attr.name}}>{{this.labelString}}</G.Legend>
          {{#if this.helpTextString}}
            <G.HelperText data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</G.HelperText>
          {{/if}}
          {{#if @attr.options.subText}}
            <G.HelperText data-test-help-text={{@attr.options.subText}}>
              {{@attr.options.subText}}
              {{#if @attr.options.docLink}}
                <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>
                  See our documentation
                </DocLink>
                for help.
              {{/if}}
            </G.HelperText>
          {{/if}}
          {{#each (path-or-array @attr.options.possibleValues @model) as |val|}}
            <G.RadioField
              @id={{or val.id (this.radioValue val)}}
              @value={{this.radioValue val}}
              checked={{if (eq (this.radioValue val) (get @model this.valuePath)) "checked"}}
              disabled={{and @attr.options.editDisabled (not @model.isNew)}}
              {{on "change" (fn this.setAndBroadcastRadio val)}}
              data-test-radio={{or val.id (this.radioValue val)}}
              as |F|
            >
              <F.Label data-test-input-group-item-label={{or val.label val.value val}}>
                {{or val.label val.value val}}
              </F.Label>
              {{! Note: if we have both `subText` and `helpText`, we display only the `subText` because in these situations, the helpText is likely there to clarify or improve upon the OpenAPI-generated text }}
              {{#if this.hasRadioSubText}}
                <F.HelperText data-test-help-text={{val.subText}}>{{val.subText}}</F.HelperText>
              {{else if this.hasRadioHelpText}}
                <F.HelperText data-test-help-text={{val.helpText}}>{{val.helpText}}</F.HelperText>
              {{/if}}
            </G.RadioField>
          {{/each}}
          {{#if this.validationError}}
            <G.Error data-test-validation-error={{this.valuePath}}>{{this.validationError}}</G.Error>
          {{/if}}
        </Hds::Form::Radio::Group>
      {{else if (eq @attr.options.editType "checkboxList")}}
        <Hds::Form::Checkbox::Group @name={{@attr.name}} data-test-input-group={{@attr.name}} as |G|>
          <G.Legend data-test-form-field-label>{{this.labelString}}</G.Legend>
          {{#if this.helpTextString}}
            <G.HelperText data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</G.HelperText>
          {{/if}}
          {{#if @attr.options.subText}}
            <G.HelperText data-test-help-text={{@attr.options.subText}}>
              {{@attr.options.subText}}
              {{#if @attr.options.docLink}}
                <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>See our documentation</DocLink>
                for help.
              {{/if}}
            </G.HelperText>
          {{/if}}
          {{#each @attr.options.possibleValues as |option|}}
            <G.CheckboxField
              @id={{option}}
              @value={{option}}
              checked={{includes option (get @model this.valuePath)}}
              {{on "change" this.setAndBroadcastChecklist}}
              data-test-checkbox={{option}}
              as |F|
            >
              <F.Label data-test-input-group-item-label={{option}}>{{option}}</F.Label>
            </G.CheckboxField>
          {{/each}}
          {{#if this.validationError}}
            <G.Error data-test-validation-error={{this.valuePath}}>{{this.validationError}}</G.Error>
          {{/if}}
        </Hds::Form::Checkbox::Group>
      {{else}}
        <Hds::Form::Select::Field
          name={{@attr.name}}
          @id={{@attr.name}}
          @isInvalid={{this.validationError}}
          {{on "change" this.onChangeWithEvent}}
          data-test-input={{@attr.name}}
          as |F|
        >
          <F.Label data-test-form-field-label>{{this.labelString}}</F.Label>
          {{#if this.helpTextString}}
            <F.HelperText data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</F.HelperText>
          {{/if}}
          {{#if @attr.options.subText}}
            <F.HelperText data-test-help-text={{@attr.options.subText}}>
              {{@attr.options.subText}}
              {{#if @attr.options.docLink}}
                <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>See our documentation</DocLink>
                for help.
              {{/if}}
            </F.HelperText>
          {{/if}}
          <F.Options>
            {{#if @attr.options.noDefault}}
              <option value="">
                Select one
              </option>
            {{/if}}
            {{#each (path-or-array @attr.options.possibleValues @model) as |val|}}
              <option selected={{loose-equal (get @model this.valuePath) (or val.value val)}} value={{or val.value val}}>
                {{or val.displayName val}}
              </option>
            {{/each}}
          </F.Options>
          {{#if this.validationError}}
            <F.Error data-test-validation-error={{this.valuePath}}>{{this.validationError}}</F.Error>
          {{/if}}
        </Hds::Form::Select::Field>
      {{/if}}
    {{else}}
      {{#if (eq @attr.options.editType "dateTimeLocal")}}
        <Hds::Form::TextInput::Field
          @type="datetime-local"
          name={{@attr.name}}
          @id={{@attr.name}}
          @value={{date-format (get @model this.valuePath) "yyyy-MM-dd'T'HH:mm"}}
          @isInvalid={{this.validationError}}
          {{on "focusout" this.onChangeWithEvent}}
          data-test-input={{@attr.name}}
          as |F|
        >
          <F.Label data-test-form-field-label>{{this.labelString}}</F.Label>
          {{#if this.helpTextString}}
            <F.HelperText data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</F.HelperText>
          {{/if}}
          {{#if @attr.options.subText}}
            <F.HelperText data-test-help-text={{@attr.options.subText}}>
              {{@attr.options.subText}}
              {{#if @attr.options.docLink}}
                <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>See our documentation</DocLink>
                for help.
              {{/if}}
            </F.HelperText>
          {{/if}}
          {{#if this.validationError}}
            <F.Error data-test-validation-error={{this.valuePath}}>{{this.validationError}}</F.Error>
          {{/if}}
        </Hds::Form::TextInput::Field>

      {{else if (or (eq @attr.type "number") (eq @attr.type "string"))}}
        {{#if (eq @attr.options.editType "password")}}
          <Hds::Form::TextInput::Field
            @type="password"
            name={{@attr.name}}
            {{! TODO: about this visibility toggle, see: https://hashicorp.atlassian.net/browse/VAULT-34870 }}
            @hasVisibilityToggle={{false}}
            @value={{get @model this.valuePath}}
            @isInvalid={{this.validationError}}
            placeholder={{@attr.options.placeholder}}
            {{! Prevents browsers from auto-filling }}
            autocomplete="new-password"
            spellcheck="false"
            {{on "input" this.onChangeWithEvent}}
            data-test-input={{@attr.name}}
            as |F|
          >
            <F.Label data-test-form-field-label>{{this.labelString}}</F.Label>
            {{#if this.helpTextString}}
              <F.HelperText data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</F.HelperText>
            {{/if}}
            {{#if @attr.options.subText}}
              <F.HelperText data-test-help-text={{@attr.options.subText}}>
                {{@attr.options.subText}}
                {{#if @attr.options.docLink}}
                  <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>See our documentation</DocLink>
                  for help.
                {{/if}}
              </F.HelperText>
            {{/if}}
            {{#if this.validationError}}
              <F.Error data-test-validation-error={{this.valuePath}}>{{this.validationError}}</F.Error>
            {{/if}}
          </Hds::Form::TextInput::Field>
        {{else if (eq @attr.options.editType "textarea")}}
          <Hds::Form::Textarea::Field
            name={{@attr.name}}
            @id={{@attr.name}}
            @value={{or (get @model this.valuePath) @attr.options.defaultValue}}
            @isInvalid={{this.validationError}}
            placeholder={{@attr.options.placeholder}}
            {{on "input" this.onChangeWithEvent}}
            data-test-input={{@attr.name}}
            as |F|
          >
            <F.Label data-test-form-field-label>{{this.labelString}}</F.Label>
            {{#if this.helpTextString}}
              <F.HelperText data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</F.HelperText>
            {{/if}}
            {{#if @attr.options.subText}}
              <F.HelperText data-test-help-text={{@attr.options.subText}}>
                {{@attr.options.subText}}
                {{#if @attr.options.docLink}}
                  <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>See our documentation</DocLink>
                  for help.
                {{/if}}
              </F.HelperText>
            {{/if}}
            {{#if this.validationError}}
              <F.Error data-test-validation-error={{this.valuePath}}>{{this.validationError}}</F.Error>
            {{/if}}
          </Hds::Form::Textarea::Field>
        {{else}}
          <Hds::Form::TextInput::Field
            name={{@attr.name}}
            @id={{@attr.name}}
            @value={{get @model this.valuePath}}
            @isInvalid={{this.validationError}}
            readonly={{this.isReadOnly}}
            disabled={{and @attr.options.editDisabled (not @model.isNew)}}
            autocomplete="off"
            spellcheck="false"
            placeholder={{@attr.options.placeholder}}
            maxLength={{@attr.options.characterLimit}}
            {{on "change" this.onChangeWithEvent}}
            {{on "input" this.onChangeWithEvent}}
            {{on "keyup" this.handleKeyUp}}
            data-test-input={{@attr.name}}
            as |F|
          >
            <F.Label data-test-form-field-label>{{this.labelString}}</F.Label>
            {{#if this.helpTextString}}
              <F.HelperText data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</F.HelperText>
            {{/if}}
            {{#if @attr.options.subText}}
              <F.HelperText data-test-help-text={{@attr.options.subText}}>
                {{@attr.options.subText}}
                {{#if @attr.options.docLink}}
                  <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>See our documentation</DocLink>
                  for help.
                {{/if}}
              </F.HelperText>
            {{/if}}
            {{#if @attr.options.characterLimit}}
              <F.CharacterCount @maxLength={{@attr.options.characterLimit}} />
            {{/if}}
            {{#if this.validationError}}
              <F.Error data-test-validation-error={{this.valuePath}}>{{this.validationError}}</F.Error>
            {{/if}}
          </Hds::Form::TextInput::Field>
        {{/if}}
      {{else if (or (eq @attr.type "boolean") (eq @attr.options.editType "boolean"))}}
        <Hds::Form::Checkbox::Field
          name={{@attr.name}}
          @id={{@attr.name}}
          checked={{get @model this.valuePath}}
          disabled={{this.disabled}}
          {{on "change" this.onChangeWithEvent}}
          data-test-input={{@attr.name}}
          as |F|
        >
          <F.Label data-test-form-field-label>{{this.labelString}}</F.Label>
          {{#if (or this.helpTextString @attr.options.subText)}}
            <F.HelperText>
              {{#if this.helpTextString}}
                <span data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</span>
              {{/if}}
              {{#if @attr.options.subText}}
                <span data-test-help-text={{@attr.options.subText}}>
                  {{@attr.options.subText}}
                  {{#if @attr.options.docLink}}
                    <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>Learn more here.</DocLink>
                  {{/if}}
                </span>
              {{/if}}
            </F.HelperText>
          {{/if}}
          {{#if this.validationError}}
            <F.Error data-test-validation-error={{this.valuePath}}>{{this.validationError}}</F.Error>
          {{/if}}
        </Hds::Form::Checkbox::Field>
      {{/if}}
    {{/if}}
    {{! •••••••••••••••••••••••••••••••••••••••••••••••••••••••• }}
    {{!                  HDS COMPONENTS - END                  }}
    {{! •••••••••••••••••••••••••••••••••••••••••••••••••••••••• }}
  {{else}}
    {{! ≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠ }}
    {{!                NON-HDS COMPONENTS - START                }}
    {{! ≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠ }}
    {{#unless this.hideLabel}}
      <FormFieldLabel
        for={{@attr.name}}
        @label={{this.labelString}}
        @helpText={{this.helpTextString}}
        @subText={{@attr.options.subText}}
        @docLink={{@attr.options.docLink}}
      />
    {{/unless}}
    {{#if (eq @attr.options.editType "searchSelect")}}
      <div class="form-section">
        <SearchSelect
          @id={{@attr.name}}
          @models={{@attr.options.models}}
          @onChange={{this.setAndBroadcast}}
          @inputValue={{get @model this.valuePath}}
          @wildcardLabel={{@attr.options.wildcardLabel}}
          @label={{this.labelString}}
          @labelClass={{if @attr.options.isSectionHeader "title is-4" "is-label"}}
          @subText={{@attr.options.subText}}
          @helpText={{this.helpTextString}}
          @fallbackComponent={{@attr.options.fallbackComponent}}
          @selectLimit={{@attr.options.selectLimit}}
          @backend={{@model.backend}}
          @disallowNewItems={{@attr.options.onlyAllowExisting}}
          class={{if this.validationError "dropdown-has-error-border"}}
        />
      </div>
    {{else if (eq @attr.options.editType "mountAccessor")}}
      <MountAccessorSelect
        @name={{@attr.name}}
        @label={{this.labelString}}
        @helpText={{this.helpTextString}}
        @value={{get @model this.valuePath}}
        @onChange={{this.setAndBroadcast}}
      />
    {{else if (eq @attr.options.editType "kv")}}
      {{! KV Object Editor }}
      <KvObjectEditor
        @value={{get @model this.valuePath}}
        @onChange={{this.setAndBroadcast}}
        @label={{this.labelString}}
        @labelClass={{if @attr.options.isSectionHeader "title is-4" "is-label"}}
        @helpText={{this.helpTextString}}
        @subText={{@attr.options.subText}}
        @onKeyUp={{this.handleKeyUp}}
        @keyPlaceholder={{@attr.options.keyPlaceholder}}
        @valuePlaceholder={{@attr.options.valuePlaceholder}}
        @isSingleRow={{@attr.options.isSingleRow}}
        @allowWhiteSpace={{@attr.options.allowWhiteSpace}}
        class="{{if this.validationError 'error-border-child-inputs'}} {{if @attr.options.isSectionHeader 'form-section'}}"
      />
    {{else if (eq @attr.options.editType "file")}}
      {{! File Input }}
      <div class="has-bottom-margin-m" data-test-input={{@attr.name}}>
        <TextFile
          @label={{this.labelString}}
          @subText={{@attr.options.subText}}
          @helpText={{this.helpTextString}}
          @docLink={{@attr.options.docLink}}
          @onChange={{this.setFile}}
          @validationError={{this.validationError}}
        />
      </div>
    {{else if (eq @attr.options.editType "ttl")}}
      {{! TTL Picker }}
      <div class="field">
        {{#let (or (get @model this.valuePath) @attr.options.setDefault) as |initialValue|}}
          <TtlPicker
            data-test-input={{@attr.name}}
            class={{if this.validationError "ttl-picker-form-field-error"}}
            @onChange={{this.setAndBroadcastTtl}}
            @label={{this.labelString}}
            @helperTextDisabled={{or @attr.options.helperTextDisabled "Vault will use the default lease duration."}}
            @helperTextEnabled={{or @attr.options.helperTextEnabled "Lease will expire after"}}
            @description={{@attr.helpText}}
            @initialValue={{initialValue}}
            @initialEnabled={{if (eq initialValue "0s") false initialValue}}
            @hideToggle={{@attr.options.hideToggle}}
          />
        {{/let}}
      </div>
    {{else if (eq @attr.options.editType "regex")}}
      {{! Regex Validated Input }}
      <RegexValidator
        @attr={{@attr}}
        @labelString={{this.labelString}}
        @value={{or (get @model this.valuePath) @attr.options.defaultValue}}
        @onChange={{this.onChangeWithEvent}}
      />
    {{else if (eq @attr.options.editType "toggleButton")}}
      {{! Togglable Input }}
      <Toggle
        @name="toggle-{{@attr.name}}"
        @onChange={{this.toggleButton}}
        @checked={{if @attr.options.isOppositeValue (not this.toggleInputEnabled) this.toggleInputEnabled}}
        data-test-toggle={{@attr.name}}
        disabled={{this.disabled}}
        aria-describedby={{concat @attr.name "-helper-text"}}
      >
        <span class="has-text-weight-bold is-large">{{this.labelString}}</span><br />
        <div class="description has-text-grey" data-test-toggle-subtext>
          <span id={{concat @attr.name "-helper-text"}}>
            {{#if this.toggleInputEnabled}}
              {{if @attr.options.isOppositeValue @attr.options.helperTextDisabled @attr.options.helperTextEnabled}}
            {{else}}
              {{if @attr.options.isOppositeValue @attr.options.helperTextEnabled @attr.options.helperTextDisabled}}
            {{/if}}
          </span>
        </div>
      </Toggle>
    {{else if (eq @attr.options.editType "optionalText")}}
      {{! Togglable Text Input }}
      <Toggle
        @name="show-{{@attr.name}}"
        @onChange={{this.toggleTextShow}}
        @checked={{this.showToggleTextInput}}
        data-test-toggle={{@attr.name}}
        aria-describedby={{concat @attr.name "-helper-text"}}
      >
        <span class="ttl-picker-label is-large" id={{concat @attr.name "-helper-text"}}>{{this.labelString}}</span><br />
        <div class="description has-text-grey">
          {{#if this.showToggleTextInput}}
            <span>
              {{@attr.options.subText}}
              {{#if @attr.options.docLink}}
                <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>
                  See our documentation
                </DocLink>
                for help.
              {{/if}}
            </span>
          {{else}}
            <span>
              {{or @attr.options.defaultSubText "Vault will use the engine default."}}
              {{#if @attr.options.docLink}}
                <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>
                  See our documentation
                </DocLink>
                for help.
              {{/if}}
            </span>
          {{/if}}
        </div>
        {{#if this.showToggleTextInput}}
          <input
            data-test-input={{@attr.name}}
            id={{@attr.name}}
            autocomplete="off"
            spellcheck="false"
            value={{or (get @model this.valuePath) @attr.options.defaultValue}}
            onchange={{this.onChangeWithEvent}}
            class="input"
            maxLength={{@attr.options.characterLimit}}
          />
        {{/if}}
      </Toggle>
    {{else if (eq @attr.options.editType "stringArray")}}
      <StringList
        class={{if this.validationError "string-list-form-field-error"}}
        data-test-input={{@attr.name}}
        @label={{this.labelString}}
        @helpText={{this.helpTextString}}
        @inputValue={{get @model this.valuePath}}
        @onChange={{this.setAndBroadcast}}
        @attrName={{@attr.name}}
        @subText="{{@attr.options.subText}} Add one item per row."
      />
    {{else if (eq @attr.options.sensitive true)}}
      <MaskedInput
        @name={{@attr.name}}
        @value={{or (get @model this.valuePath) @attr.options.defaultValue}}
        @allowCopy={{if @attr.options.noCopy false true}}
        @onChange={{this.setAndBroadcast}}
        @onKeyUp={{@onKeyUp}}
      />
    {{else if (or (eq @attr.type "number") (eq @attr.type "string"))}}
      <div class="control">
        {{#if (eq @attr.options.editType "json")}}
          {{! JSON Editor }}
          {{#let (get @model this.valuePath) as |value|}}
            <JsonEditor
              data-test-input={{@attr.name}}
              @title={{this.labelString}}
              @value={{if
                value
                (if (eq @attr.options.mode "ruby") value (stringify (jsonify value)))
                @attr.options.defaultValue
              }}
              @valueUpdated={{fn this.editorUpdated true}}
              @helpText={{this.helpTextString}}
              @mode={{@attr.options.mode}}
              @example={{@attr.options.example}}
              @onSetup={{fn (mut this.codemirrorEditor)}}
            >
              {{#if @attr.options.allowReset}}
                <Hds::Button
                  @text="Clear"
                  @icon="reload"
                  @color="secondary"
                  disabled={{not value}}
                  {{on "click" (fn this.editorUpdated true "")}}
                  data-test-json-clear-button
                />
              {{/if}}
            </JsonEditor>
          {{/let}}
          {{#if @attr.options.subText}}
            <p class="sub-text">
              {{@attr.options.subText}}
              {{#if @attr.options.docLink}}
                <DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>
                  See our documentation
                </DocLink>
                for help.
              {{/if}}
            </p>
          {{/if}}
        {{/if}}
      </div>
    {{else if (eq @attr.type "object")}}
      <JsonEditor
        @title={{this.labelString}}
        @value={{if (get @model this.valuePath) (stringify (get @model this.valuePath)) this.emptyData}}
        @valueUpdated={{fn this.editorUpdated false}}
        @helpText={{this.helpTextString}}
        @example={{@attr.options.example}}
      />
    {{else if (eq @attr.options.editType "yield")}}
      {{yield}}
    {{/if}}
    {{#if this.validationError}}
      <AlertInline
        @type="danger"
        @message={{this.validationError}}
        @paddingTop={{not-eq @attr.options.editType "ttl"}}
        data-test-validation-error={{this.valuePath}}
        class={{if (eq @attr.options.editType "stringArray") "has-top-margin-negative-xxl"}}
      />
    {{/if}}
    {{! ≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠ }}
    {{!                NON-HDS COMPONENTS - END                  }}
    {{! ≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠ }}
  {{/if}}
  {{! ~~~~~~~~~~~~~~ COMMON PART - START ~~~~~~~~~~~~~~ }}
  {{#if this.validationWarning}}
    <AlertInline
      @type="warning"
      @message={{this.validationWarning}}
      @paddingTop={{if (and (not this.validationError) (eq @attr.options.editType "ttl")) false true}}
      data-test-validation-warning={{this.valuePath}}
      class={{if (and (not this.validationError) (eq @attr.options.editType "stringArray")) "has-top-margin-negative-xxl"}}
    />
  {{/if}}
  {{! ~~~~~~~~~~~~~~ COMMON PART - END ~~~~~~~~~~~~~~ }}
</div>