{% from "nhsuk/components/error-message/macro.njk" import errorMessage as nhsukErrorMessage %}
{% from "nhsuk/components/hint/macro.njk" import hint as nhsukHint %}
{% from "nhsuk/components/label/macro.njk" import label as nhsukLabel %}
{% from "nhsuk/macros/attributes.njk" import nhsukAttributes %}
{% from "nhsuk/macros/content.njk" import nhsukContent %}

{#- Set classes for this component #}
{%- set classNames = "nhsuk-select" %}
{%- set classNamesFormGroup = "nhsuk-form-group" %}

{#- Support label as string #}
{%- set label = params.label if params.label is mapping and params.label is not escaped else {
  text: params.label if params.label is string else undefined,
  html: params.label if params.label is escaped else undefined
} %}

{#- Support hint as string #}
{%- set hint = params.hint if params.hint is mapping and params.hint is not escaped else {
  text: params.hint if params.hint is string else undefined,
  html: params.hint if params.hint is escaped else undefined
} %}

{#- Support error message as string #}
{%- set errorMessage = params.errorMessage if params.errorMessage is mapping and params.errorMessage is not escaped else {
  text: params.errorMessage if params.errorMessage is string else undefined,
  html: params.errorMessage if params.errorMessage is escaped else undefined
} %}

{#- Support content before input as string #}
{%- set beforeInput = params.formGroup.beforeInput if params.formGroup.beforeInput is mapping and params.formGroup.beforeInput is not escaped else {
  text: params.formGroup.beforeInput if params.formGroup.beforeInput is string else undefined,
  html: params.formGroup.beforeInput if params.formGroup.beforeInput is escaped else undefined
} %}

{#- Support content after input as string #}
{%- set afterInput = params.formGroup.afterInput if params.formGroup.afterInput is mapping and params.formGroup.afterInput is not escaped else {
  text: params.formGroup.afterInput if params.formGroup.afterInput is string else undefined,
  html: params.formGroup.afterInput if params.formGroup.afterInput is escaped else undefined
} %}

{%- if errorMessage.text or errorMessage.html or params.errorMessage is sameas(true) %}
  {%- set classNames = classNames ~ " nhsuk-select--error" %}
  {%- set classNamesFormGroup = classNamesFormGroup ~ " nhsuk-form-group--error" %}
{%- endif %}

{%- if params.classes %}
  {%- set classNames = classNames ~ " " ~ params.classes %}
{%- endif %}

{%- if params.formGroup.classes %}
  {%- set classNamesFormGroup = classNamesFormGroup ~ " " ~ params.formGroup.classes %}
{%- endif %}

{#- a record of other elements that we need to associate with the input using
  aria-describedby – for example hints or error messages #}
{%- set describedBy = params.describedBy if params.describedBy else "" %}
{%- set id = params.id if params.id else params.name %}

{%- set hasBeforeInput = true if beforeInput.text or beforeInput.html else false %}
{%- set hasAfterInput = true if afterInput.text or afterInput.html else false %}

{%- macro _selectElement(params, parent) -%}
<select class="{{ parent.classNames }}" id="{{ parent.id }}" name="{{ params.name }}"
  {%- if params.disabled %} disabled{% endif %}
  {%- if parent.describedBy %} aria-describedby="{{ parent.describedBy }}"{% endif %}
  {{- nhsukAttributes(params.attributes) }}>
{% for item in params.items %}
{%- if item.divider %}
  <hr>
{% elif item %}
  {#- Allow selecting by text content (the value for an option when no value attribute is specified) #}
  {%- set effectiveValue = item.value | default(item.text) %}
  <option {%- if item.value is defined %} value="{{ item.value }}"{% endif %}
    {{- " selected" if item.selected | default((effectiveValue == params.value and item.selected is not sameas(false)) if params.value else false, true) }}
    {{- " disabled" if item.disabled }}
    {{- nhsukAttributes(item.attributes) }}>
    {{- item.text -}}
  </option>
  {% endif %}
{% endfor %}
</select>
{%- endmacro -%}

<div class="{{ classNamesFormGroup }}" {{- nhsukAttributes(params.formGroup.attributes) }}>
  {{ nhsukLabel({
    html: label.html,
    text: label.text,
    visuallyHiddenText: label.visuallyHiddenText,
    caption: label.caption,
    id: label.id,
    for: label.for | default(id),
    size: label.size,
    heading: label.heading,
    isPageHeading: label.isPageHeading,
    classes: label.classes,
    attributes: label.attributes
  }) | trim | indent(2) }}
{% if hint.text or hint.html %}
  {%- set hintId = hint.id | default(id ~ "-hint") %}
  {%- set describedBy = (describedBy ~ " " ~ hintId) | trim %}
  {{ nhsukHint({
    html: hint.html,
    text: hint.text,
    id: hint.id | default(hintId),
    classes: hint.classes,
    attributes: hint.attributes
  }) | trim | indent(2) }}
{% endif %}
{% if errorMessage.text or errorMessage.html %}
  {%- set errorId =errorMessage.id | default(id ~ "-error") %}
  {%- set describedBy = (describedBy ~ " " ~ errorId) | trim %}
  {{ nhsukErrorMessage({
    html: errorMessage.html,
    text: errorMessage.text,
    visuallyHiddenText: errorMessage.visuallyHiddenText,
    id: errorMessage.id | default(errorId),
    classes:errorMessage.classes,
    attributes: errorMessage.attributes
  }) | trim | indent(2) }}
{% endif %}

{%- set content = {
  html: _selectElement(params, {
    id: id,
    describedBy: describedBy,
    classNames: classNames
  }) | trim,
  slots: {
    before: beforeInput,
    after: afterInput
  }
} %}

{%- if hasBeforeInput or hasAfterInput or params.inputWrapper.classes or params.inputWrapper.attributes %}
  <div class="nhsuk-input-wrapper {%- if params.inputWrapper.classes %} {{ params.inputWrapper.classes }}{% endif %}"
    {{- nhsukAttributes(params.inputWrapper.attributes) }}>
    {{ nhsukContent(content) | trim | indent(4) }}
  </div>
{% else %}
  {{ nhsukContent(content) | trim | indent(2) }}
{% endif %}
</div>
