{%- set id = id ?? "checkbox-select-#{random()}" %}
{%- set options = options ?? [] %}
{%- set values = values ?? [] %}
{%- set disabled = disabled ?? false %}
{%- set sortable = sortable ?? false %}

{% set options = options|map((value, key) => value is iterable ? value : {
    label: value,
    value: key,
}) %}

{% if sortable and values|length %}
    {% set options = collect(options)
        .sortBy(o => values|indexOf(o.value, PHP_INT_MAX))
        .all() %}
{% endif %}

{%- set showAllOption = showAllOption ?? false %}
{%- if showAllOption %}
    {%- set allLabel = allLabel ?? "All"|t('app') %}
    {%- set allValue = allValue ?? '*' %}
    {%- set allChecked = (values == allValue) %}
{%- endif %}

{% set containerAttributes = {
    id,
    class: ['checkbox-select']|merge((class ?? [])|explodeClass),
}|merge(containerAttributes ?? [], recursive=true) %}

{%- if block('attr') is defined %}
    {%- set containerAttributes = containerAttributes|merge(('<div ' ~ block('attr') ~ '>')|parseAttr, recursive=true) %}
{% endif %}

{% tag 'fieldset' with containerAttributes %}
    {%- if showAllOption %}
        <div>
            {% include "_includes/forms/checkbox" with {
                describedBy: describedBy ?? false,
                class: ['checkbox-select-item', 'all'],
                label: raw("<b>#{allLabel}</b>"),
                name: name ?? null,
                value: allValue,
                checked: allChecked,
                autofocus: (autofocus ?? false) and not craft.app.request.isMobileBrowser(true),
                targetPrefix: targetPrefix ?? null,
                disabled: disabled
            } only %}
        </div>
    {%- elseif name is defined and (name|length < 3 or name|slice(-2) != '[]') %}
        {{- hiddenInput(name, '') }}
    {%- endif %}
    {%- for key, option in options %}
        {% if not showAllOption or option.value is not defined or option.value != allValue %}
            <div class="checkbox-select-item">
                {% set selected = (showAllOption and allChecked) or (option.value is defined and option.value in values) %}
                {% if sortable and not disabled %}
                    {{ tag('a', {
                        class: {
                            move: true,
                            icon: true,
                            'draggable-handle': true,
                            disabled: not selected,
                        }|filter|keys,
                    }) }}
                {% endif %}
                {% include "_includes/forms/checkbox" with {
                    name: (name ?? false) ? "#{name}[]" : null,
                    checked: selected,
                    disabled: (showAllOption and allChecked) or disabled,
                    targetPrefix: targetPrefix ?? null,
                }|merge(option) only %}
            </div>
        {% endif %}
    {% endfor %}
{% endtag %}

{% if sortable and not disabled %}
    {% js %}
        new Craft.SortableCheckboxSelect($('#{{ id|namespaceInputId }}'));
    {% endjs %}
{% endif %}
