{% from "../../macros/attributes.njk" import govukAttributes %}
{% from "../error-message/macro.njk" import govukErrorMessage %}
{% from "../fieldset/macro.njk" import govukFieldset %}
{% from "../hint/macro.njk" import govukHint %}
{% from "../input/macro.njk" import govukInput %}

{#- 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.fieldset.describedBy if params.fieldset.describedBy else "" %}

{#- fieldset is false by default -#}
{% set hasFieldset = true if params.fieldset else false %}

{%- set dateInputDay = params.day | default({
  name: "day",
  value: params.values.day,
  classes: "govuk-input--width-2"
}) -%}

{%- set dateInputMonth = params.month | default({
  name: "month",
  value: params.values.month,
  classes: "govuk-input--width-2"
}) -%}

{%- set dateInputYear = params.year | default({
  name: "year",
  value: params.values.year,
  classes: "govuk-input--width-4"
}) -%}

{%- if params.items | length %}
  {% set dateInputItems = params.items %}
{% else %}
  {% set dateInputItems = [
    dateInputDay,
    dateInputMonth,
    dateInputYear
  ] %}
{% endif %}

{%- macro _dateInputItem(params, item, anyItemHasError) %}
{% set itemName = item.name %}
{% set itemValue = item.value %}
{% set itemWidth = 2 %}
{% set itemClasses = "" %}
{% set itemHasError = true if item.error or (item.classes and "govuk-input--error" in item.classes) else false %}

{%- if item is sameas(dateInputDay) or (item.name and item.name in ["day", dateInputDay.name]) %}
  {% set itemName = item.name | default("day") %}
  {% set itemValue = item.value | default(dateInputDay.value) %}
{% elif item is sameas(dateInputMonth) or (item.name and item.name in ["month", dateInputMonth.name]) %}
  {% set itemName = item.name | default("month") %}
  {% set itemValue = item.value | default(dateInputMonth.value) %}
{% elif item is sameas(dateInputYear) or (item.name and item.name in ["year", dateInputYear.name]) %}
  {% set itemName = item.name | default("year") %}
  {% set itemValue = item.value | default(dateInputYear.value) %}
  {% set itemWidth = 4 %}
{% endif %}

{%- if (not item.classes or not "govuk-input--error" in item.classes) and (
  itemHasError or (item.error != false and params.errorMessage and not anyItemHasError)
) %}
  {% set itemClasses = (itemClasses + " govuk-input--error") | trim %}
{% endif -%}

{%- if not item.classes or not "govuk-input--width-" in item.classes %}
  {% set itemClasses = (itemClasses + " govuk-input--width-" + itemWidth) | trim %}
{% endif %}

{%- if item.classes %}
  {% set itemClasses = (itemClasses + " " + item.classes) | trim %}
{% endif %}

{%- set namePrefix = (params.namePrefix + "-") if params.namePrefix else "" -%}

<div class="govuk-date-input__item">
  {{ govukInput({
    label: {
      text: item.label if item.label else itemName | capitalize,
      classes: "govuk-date-input__label"
    },
    id: item.id if item.id else (params.id + "-" + itemName),
    classes: "govuk-date-input__input" + (" " + itemClasses if itemClasses),
    name: namePrefix + itemName,
    value: itemValue | default(params.values[namePrefix + itemName]),
    type: "text",
    inputmode: item.inputmode if item.inputmode else "numeric",
    autocomplete: item.autocomplete,
    pattern: item.pattern,
    attributes: item.attributes
  }) | trim | indent(2) }}
</div>
{%- endmacro -%}

{#- Determine if any date input item has an error #}
{%- set anyItemHasError = false %}
{% for item in dateInputItems %}
  {% set anyItemHasError = true if item.error or (item.classes and "govuk-input--error" in item.classes) else anyItemHasError %}
{% endfor -%}

{#- Capture the HTML so we can optionally nest it in a fieldset -#}
{% set innerHtml %}
{% if params.hint %}
  {% set hintId = params.id + "-hint" %}
  {% set describedBy = describedBy + " " + hintId if describedBy else hintId %}
  {{ govukHint({
    id: hintId,
    classes: params.hint.classes,
    attributes: params.hint.attributes,
    html: params.hint.html,
    text: params.hint.text
  }) | trim | indent(2) }}
{% endif %}
{% if params.errorMessage %}
  {% set errorId = params.id + "-error" %}
  {% set describedBy = describedBy + " " + errorId if describedBy else errorId %}
  {{ govukErrorMessage({
    id: errorId,
    classes: params.errorMessage.classes,
    attributes: params.errorMessage.attributes,
    html: params.errorMessage.html,
    text: params.errorMessage.text,
    visuallyHiddenText: params.errorMessage.visuallyHiddenText
  }) | trim | indent(2) }}
{% endif %}
  <div class="govuk-date-input {%- if params.classes %} {{ params.classes }}{% endif %}"
    {{- govukAttributes(params.attributes) -}}
    {%- if params.id %} id="{{ params.id }}"{% endif %}>
    {% if params.formGroup.beforeInputs %}
    {{ params.formGroup.beforeInputs.html | safe | trim | indent(4) if params.formGroup.beforeInputs.html else params.formGroup.beforeInputs.text }}
    {% endif %}
    {% for item in dateInputItems %}
      {% if item %}
        {{- _dateInputItem(params, item, anyItemHasError) | trim | indent(4, true) }}
      {% endif %}
    {% endfor %}
    {% if params.formGroup.afterInputs %}
    {{ params.formGroup.afterInputs.html | safe | trim | indent(4) if params.formGroup.afterInputs.html else params.formGroup.afterInputs.text }}
    {% endif %}
  </div>
{% endset -%}

<div class="govuk-form-group {%- if params.errorMessage %} govuk-form-group--error{% endif %} {%- if params.formGroup.classes %} {{ params.formGroup.classes }}{% endif %}" {{- govukAttributes(params.formGroup.attributes) }}>
{% if hasFieldset %}
  {# We override the fieldset's role to 'group' because otherwise JAWS does not
    announce the description for a fieldset comprised of text inputs, but
    adding the role to the fieldset always makes the output overly verbose for
    radio buttons or checkboxes. -#}
  {{ govukFieldset({
    describedBy: describedBy,
    classes: params.fieldset.classes,
    role: 'group',
    attributes: params.fieldset.attributes,
    legend: params.fieldset.legend,
    html: innerHtml | trim
  }) | trim | indent(2) }}
{% else %}
  {{ innerHtml | safe | trim }}
{% endif %}
</div>
