{%- set static = static ?? false %}
{%- set fullWidth = fullWidth ?? true %}
{%- set cols = cols ?? [] %}
{%- set rows = rows ?? [] %}
{%- set initJs = not static and (initJs ?? true) -%}
{%- set minRows = minRows ?? null %}
{%- set maxRows = maxRows ?? null %}
{%- set describedBy = describedBy ?? null %}

{%- set totalRows = rows|length %}
{%- set staticRows = static or (staticRows ?? false) or (minRows == 1 and maxRows == 1 and totalRows == 1) %}
{%- set allowAdd = (allowAdd ?? false) and not staticRows %}
{%- set allowReorder = (allowReorder ?? false) and not staticRows %}
{%- set allowDelete = (allowDelete ?? false) and not staticRows %}

{% if not static %}
    {{ hiddenInput(name, '') }}
{% endif %}

{% macro cellClass(fullWidth, col, class) %}
    {{- (class is iterable ? class : [class])|merge([
        "#{col.type}-cell",
        col.type in [
            'autosuggest',
            'color',
            'date',
            'email',
            'multiline',
            'number',
            'singleline',
            'template',
            'time',
            'url',
        ] ? 'textual' : null,
        fullWidth and (col.thin ?? false) ? 'thin' : null,
        col.info is defined ? 'has-info' : null,
    ]|filter)|join(' ') -}}
{% endmacro %}

{% set tableAttributes = {
    id: id,
    class: [
        'editable',
        fullWidth ? 'fullwidth',
        static ? 'static',
        totalRows == 0 ? 'hidden',
    ]|filter,
} %}

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

<span aria-live="assertive" class="visually-hidden" data-status-message></span>
{% tag 'table' with tableAttributes %}
    {% for col in cols %}
        <col>
    {% endfor %}
    {% if (allowDelete and allowReorder) %}
        <colgroup span="2"></colgroup>
    {% else %}
        {% if allowDelete %}<col>{% endif %}
        {% if allowReorder %}<col>{% endif %}
    {% endif %}
    <thead>
        <tr>
            {% for col in cols %}
                {%- switch col.type %}
                    {%- case 'time' %}
                        {%- do view.registerAssetBundle('craft\\web\\assets\\timepicker\\TimepickerAsset') %}
                    {%- case 'template' %}
                        {%- do view.registerAssetBundle("craft\\web\\assets\\vue\\VueAsset") %}
                {%- endswitch %}
                {% set columnHeadingId = "#{id}-heading-#{loop.index}" %}
                <th id="{{ columnHeadingId }}" scope="col" class="{{ _self.cellClass(fullWidth, col, col.class ?? []) }}">
                    {%- if col.headingHtml is defined %}
                        {{- col.headingHtml|raw }}
                    {%- elseif col.heading ?? false %}
                        {{- col.heading }}
                    {%- else %}
                        &nbsp;
                    {%- endif %}
                    {%- if col.info is defined -%}
                        <span class="info">{{ col.info|md|raw }}</span>
                    {%- endif -%}
                </th>
            {% endfor %}
            {% if (allowDelete or allowReorder) %}
                <th colspan="{{ not allowDelete or not allowReorder ? 1 : 2 }}" scope="colgroup"><span class="visually-hidden">{{ 'Row actions'|t('app') }}</span></th>
            {% endif %}
        </tr>
    </thead>
    <tbody>
        {% for rowId, row in rows %}
            {% set rowNumber = loop.index %}
            <tr data-id="{{ rowId }}">
                {% for colId, col in cols %}
                    {% set cell = row[colId] is defined ? row[colId] : (defaultValues[colId] ?? null) %}
                    {% set value = cell.value is defined ? cell.value : cell %}
                    {% if col.type == 'heading' %}
                        <th scope="row" class="{{ _self.cellClass(fullWidth, col, cell.class ?? col.class ?? []) }}"{% if col.width ?? false %} width="{{ col.width }}"{% endif %}>{{ value|raw }}</th>
                    {% elseif col.type == 'html' %}
                        <td class="{{ _self.cellClass(fullWidth, col, cell.class ?? col.class ?? []) }}"{% if col.width ?? false %} width="{{ col.width }}"{% endif %}>{{ value|raw }}</td>
                    {% else %}
                        {% set headingId = "#{id}-heading-#{loop.index}" %}
                        {% set hasErrors = cell.hasErrors ?? false %}
                        {% set cellName = name~'['~rowId~']['~colId~']' %}
                        {% set isCode = (col.code ?? false) or col.type == 'color' %}
                        <td class="{{ _self.cellClass(fullWidth, col, col.class ?? []) }} {% if isCode %}code{% endif %} {% if hasErrors %}error{% endif %}"{% if col.width ?? false %} width="{{ col.width }}"{% endif %}>
                            {% block tablecell %}
                                {%- switch col.type -%}
                                    {%- case 'checkbox' -%}
                                        <div class="checkbox-wrapper">
                                            {% include "_includes/forms/checkbox" with {
                                                name: cellName,
                                                value:  col.value ?? 1,
                                                checked: value is not empty,
                                                disabled: static,
                                                labelledBy: headingId,
                                                describedBy: describedBy,
                                            } only %}
                                        </div>
                                    {%- case 'color' -%}
                                        {% include "_includes/forms/color" with {
                                            name: cellName,
                                            value: value,
                                            small: true,
                                            disabled: static,
                                            labelledBy: headingId,
                                            describedBy: describedBy,
                                        } only %}
                                    {%- case 'date' -%}
                                        {% include "_includes/forms/date" with {
                                            name: cellName,
                                            value: value,
                                            disabled: static,
                                            labelledBy: headingId,
                                            describedBy: describedBy,
                                        } only %}
                                    {%- case 'lightswitch' -%}
                                        {% include "_includes/forms/lightswitch" with {
                                            name: cellName,
                                            on: value,
                                            value: col.value ?? 1,
                                            small: true,
                                            disabled: static,
                                            labelledBy: headingId,
                                            describedBy: describedBy,
                                        } only %}
                                    {% case 'select' -%}
                                        {% include "_includes/forms/select" with {
                                            class: 'small',
                                            name: cellName,
                                            options: cell.options ?? col.options,
                                            value: value,
                                            disabled: static,
                                            labelledBy: headingId,
                                            describedBy: describedBy,
                                        } only %}
                                    {%- case 'time' -%}
                                        {% include "_includes/forms/time" with {
                                            name: cellName,
                                            value: value,
                                            disabled: static,
                                            labelledBy: headingId,
                                            describedBy: describedBy,
                                        } only %}
                                    {%- case 'email' or 'url' -%}
                                        {% include "_includes/forms/text" with {
                                            type: col.type,
                                            name: cellName,
                                            placeholder: col.placeholder ?? null,
                                            value:  value,
                                            disabled: static,
                                            labelledBy: headingId,
                                            describedBy: describedBy,
                                        } only %}
                                    {%- case 'autosuggest' or 'template' -%}
                                        {% include "_includes/forms/autosuggest" with {
                                            name: cellName,
                                            suggestions: col.type == 'template' ? craft.cp.getTemplateSuggestions() : [],
                                            suggestEnvVars: col.suggestEnvVars ?? false,
                                            suggestAliases: col.suggestAliases ?? false,
                                            value: value,
                                            disabled: static,
                                            labelledBy: headingId,
                                            describedBy: describedBy,
                                        } only %}
                                    {%- default -%}
                                        {% if static %}
                                            <pre class="disabled">{{ value }}</pre>
                                        {% else %}
                                            <textarea aria-labelledby="{{ headingId }}" aria-describedby="{{ describedBy }}" name="{{ cellName }}" rows="{{ col.rows ?? 1 }}"{% if col.placeholder is defined %} placeholder="{{ col.placeholder }}"{% endif %}>{{ value }}</textarea>
                                        {% endif %}
                                {%- endswitch -%}
                            {% endblock %}
                        </td>
                    {% endif %}
                {% endfor %}
                {% if allowReorder -%}
                    <td class="thin action"><a class="move icon" title="{{ 'Reorder'|t('app') }}" aria-label="{{ 'Reorder'|t('app') }}" type="button" role="button"></a></td>
                {%- endif -%}
                {%- if allowDelete -%}
                    <td class="thin action">
                        {{ tag('button', {
                            class: [
                                'delete',
                                'icon',
                                minRows and totalRows <= minRows ? 'disabled' : null,
                            ]|filter,
                            type: 'button',
                            disabled: minRows and totalRows <= minRows,
                            title: 'Delete'|t('app'),
                            aria: {
                                label: 'Delete row {index}'|t('app', {
                                    index: rowNumber,
                                }),
                            }
                        }) }}
                    </td>
                {%- endif -%}
            </tr>
        {% endfor %}
    </tbody>
{% endtag %}

{% if allowAdd %}
    {% set buttonText = addRowLabel ?? "Add a row"|t('app') %}
    <button type="button" class="btn dashed add icon" aria-label="{{ buttonText }}">{{ buttonText }}</button>
{% endif %}

{% if initJs %}
    {% set jsId = id|namespaceInputId|e('js') %}
    {% set jsName = name|namespaceInputName|e('js') %}
    {% set jsCols = cols|json_encode %}
    {% set defaultValues = defaultValues ?? null %}
    {% js %}
        new Craft.EditableTable("{{ jsId }}", "{{ jsName }}", {{ jsCols|raw }}, {
            defaultValues: {{ defaultValues ? defaultValues|json_encode|raw : '{}' }},
            allowAdd: {{ allowAdd ? 'true' : 'false' }},
            allowDelete: {{ allowDelete ? 'true' : 'false' }},
            allowReorder: {{ allowReorder ? 'true' : 'false' }},
            minRows: {{ minRows ? minRows : 'null' }},
            maxRows: {{ maxRows ? maxRows : 'null' }}
        });
    {% endjs %}
{% endif %}
