{% from "nhsuk/macros/attributes.njk" import nhsukAttributes %}
{% from "nhsuk/components/error-message/macro.njk" import errorMessage -%}
{% from "nhsuk/components/fieldset/macro.njk" import fieldset %}
{% from "nhsuk/components/hint/macro.njk" import hint %}
{% from "nhsuk/components/label/macro.njk" import label %}

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

{%- if params.small and (not params.classes or not "nhsuk-checkboxes--small" in params.classes) %}
  {% set classNames = classNames ~ " nhsuk-checkboxes--small" %}
{% endif %}

{%- if params.inline and (not params.classes or not "nhsuk-checkboxes--inline" in params.classes) %}
  {% set classNames = classNames ~ " nhsuk-checkboxes--inline" %}
{% endif %}

{%- if params.errorMessage %}
  {% 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 %}

{#- If an id 'prefix' is not passed, fall back to using the name attribute
  instead. We need this for error messages and hints as well -#}
{% set idPrefix = params.idPrefix if params.idPrefix else params.name %}

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

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

{%- macro _checkboxItem(params, item, index) %}
  {#- If the user explicitly sets an id, use this instead of the regular idPrefix -#}
  {#- The first id should not have a number suffix so it's easy to link to from the error summary component -#}
  {% set itemId = item.id if item.id else idPrefix ~ ("-" ~ index if index > 1 else "") %}
  {% set itemName = item.name if item.name else params.name %}
  {% set conditionalId = "conditional-" ~ itemId %}
  {%- if item.divider %}
    <div class="nhsuk-checkboxes__divider">{{ item.divider }}</div>
  {% else %}
    {% set isChecked = item.checked | default((item.value in params.values and item.checked != false) if params.values else false, true) %}
    {% set hasHint = true if item.hint.text or item.hint.html %}
    {% set itemHintId = item.hint.id | default(itemId ~ "-item-hint") if hasHint else "" %}
    {% set itemDescribedBy = describedBy if not hasFieldset else "" %}
    {% set itemDescribedBy = (itemDescribedBy ~ " " ~ itemHintId) | trim %}
    {% set itemClasses = "nhsuk-checkboxes__input" ~ (" " ~ item.classes if item.classes) %}
    <div class="nhsuk-checkboxes__item">
      <input class="{{ itemClasses }}" id="{{ itemId }}" name="{{ itemName }}" type="checkbox" value="{{ item.value }}"
        {{- " checked" if isChecked }}
        {{- " disabled" if item.disabled or (item.disabled != false and params.disabled) }}
        {%- if item.exclusive %} data-checkbox-exclusive{% endif -%}
        {%- if item.exclusiveGroup %} data-checkbox-exclusive-group="{{ item.exclusiveGroup }}"{% endif -%}
        {%- if item.conditional.html %} data-aria-controls="{{ conditionalId }}"{% endif -%}
        {%- if itemDescribedBy %} aria-describedby="{{ itemDescribedBy }}"{% endif -%}
        {{- nhsukAttributes(item.attributes) }}>
      {{ label({
        html: item.label.html | default(item.html),
        text: item.label.text | default(item.text),
        id: item.label.id,
        for: itemId,
        classes: "nhsuk-checkboxes__label" ~ (" " ~ item.label.classes if item.label.classes),
        attributes: item.label.attributes
      }) | trim | indent(6) }}
      {% if hasHint %}
      {{ hint({
        html: item.hint.html,
        text: item.hint.text,
        id: item.hint.id | default(itemHintId),
        classes: "nhsuk-checkboxes__hint" ~ (" " ~ item.hint.classes if item.hint.classes),
        attributes: item.hint.attributes
      }) | trim | indent(6) }}
      {% endif %}
    </div>
    {% if item.conditional.html %}
    <div class="nhsuk-checkboxes__conditional {%- if not isChecked %} nhsuk-checkboxes__conditional--hidden{% endif %}" id="{{ conditionalId }}">
      {{ item.conditional.html | safe | trim }}
    </div>
    {% endif %}
  {% endif %}
{% endmacro -%}

{#- Capture the HTML so we can optionally nest it in a fieldset -#}
{% set innerHtml %}
{% if params.hint %}
  {% set hintId = params.hint.id | default(idPrefix ~ "-hint") %}
  {% set describedBy = (describedBy ~ " " ~ hintId) | trim %}
  {{ hint({
    html: params.hint.html,
    text: params.hint.text,
    id: params.hint.id | default(hintId),
    classes: params.hint.classes,
    attributes: params.hint.attributes
  }) | trim | indent(2) }}
{% endif %}
{% if params.errorMessage.text or params.errorMessage.html %}
  {% set errorId = params.errorMessage.id | default(idPrefix ~ "-error") %}
  {% set describedBy = (describedBy ~ " " ~ errorId) | trim %}
  {{ errorMessage({
    html: params.errorMessage.html,
    text: params.errorMessage.text,
    visuallyHiddenText: params.errorMessage.visuallyHiddenText,
    id: params.errorMessage.id | default(errorId),
    classes: params.errorMessage.classes,
    attributes: params.errorMessage.attributes
  }) | trim | indent(2) }}
{% endif %}
  <div
    {{- nhsukAttributes({
      class: classNames,
      id: {
        value: params.id,
        optional: true
      },
      "data-module": "nhsuk-checkboxes"
    }) -}}

    {{- nhsukAttributes(params.attributes) -}}>
    {% 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 params.items %}
      {% if item %}
        {{- _checkboxItem(params, item, loop.index) -}}
      {% 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="{{ classNamesFormGroup }}" {{- nhsukAttributes(params.formGroup.attributes) }}>
{% if hasFieldset %}
  {{ fieldset({
    legend: params.fieldset.legend,
    html: innerHtml | trim,
    id: params.fieldset.id,
    role: params.fieldset.role,
    describedBy: describedBy,
    classes: params.fieldset.classes,
    attributes: params.fieldset.attributes
  }) | trim }}
{% else %}
  {{ innerHtml | safe | trim }}
{% endif %}
</div>
