{#
  Table Macros
  ============
  Reusable table components.

  Usage:
    {% from 'shared/macros/tables.html' import table_wrapper, table_header, table_empty_state %}
    {% call table_wrapper() %}
      {{ table_header(['Name', 'Email', 'Status', 'Actions']) }}
      <tbody>...</tbody>
    {% endcall %}
#}


{#
  Table Wrapper
  =============
  Wraps the table with proper overflow and shadow styling.
#}
{% macro table_wrapper(class_extra='') %}
<div class="w-full overflow-hidden rounded-lg shadow-xs {{ class_extra }}">
    <div class="w-full overflow-x-auto">
        <table class="w-full whitespace-no-wrap">
            {{ caller() }}
        </table>
    </div>
</div>
{% endmacro %}


{#
  Table Header
  ============
  Renders the table header row.

  Parameters:
    - columns: List of column names
    - sortable: Whether columns are sortable (default: false) - future enhancement
#}
{% macro table_header(columns) %}
<thead>
    <tr class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800">
        {% for column in columns %}
        <th class="px-4 py-3">{{ column }}</th>
        {% endfor %}
    </tr>
</thead>
{% endmacro %}


{#
  Custom Table Header
  ===================
  Renders a table header with custom content via caller().
  Use this when you need th_sortable or custom th elements.

  Usage:
    {% call table_header_custom() %}
        {{ th_sortable('name', 'Name', 'sortBy', 'sortOrder') }}
        <th class="px-4 py-3">Actions</th>
    {% endcall %}
#}
{% macro table_header_custom() %}
<thead>
    <tr class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800">
        {{ caller() }}
    </tr>
</thead>
{% endmacro %}


{#
  Sortable Table Header Cell (th_sortable)
  ========================================
  Renders a single sortable table header cell for use inside table_header_custom.

  Parameters:
    - key: The data key/column name for sorting
    - label: Display label for the column
    - sort_key_var: Alpine.js variable for current sort key (default: 'sortBy')
    - sort_order_var: Alpine.js variable for sort order (default: 'sortOrder')

  Usage:
    {% call table_header_custom() %}
        {{ th_sortable('name', 'Name', 'sortBy', 'sortOrder') }}
        {{ th_sortable('created_at', 'Created', 'sortBy', 'sortOrder') }}
        <th class="px-4 py-3">Actions</th>
    {% endcall %}

  Required Alpine.js:
    sortBy: '',
    sortOrder: 'asc',
    handleSort(key) {
        if (this.sortBy === key) {
            this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
        } else {
            this.sortBy = key;
            this.sortOrder = 'asc';
        }
        this.loadData();  // or loadSubscriptions(), etc.
    }
#}
{% macro th_sortable(key, label, sort_key_var='sortBy', sort_order_var='sortOrder') %}
<th class="px-4 py-3">
    <button
        @click="handleSort('{{ key }}')"
        class="flex items-center space-x-1 hover:text-gray-700 dark:hover:text-gray-200 transition-colors group"
    >
        <span>{{ label }}</span>
        <span class="flex flex-col">
            <svg
                class="w-3 h-3 -mb-1 transition-colors"
                :class="{{ sort_key_var }} === '{{ key }}' && {{ sort_order_var }} === 'asc' ? 'text-purple-600 dark:text-purple-400' : 'text-gray-300 dark:text-gray-600 group-hover:text-gray-400'"
                fill="currentColor" viewBox="0 0 20 20"
            >
                <path d="M5 12l5-5 5 5H5z"/>
            </svg>
            <svg
                class="w-3 h-3 -mt-1 transition-colors"
                :class="{{ sort_key_var }} === '{{ key }}' && {{ sort_order_var }} === 'desc' ? 'text-purple-600 dark:text-purple-400' : 'text-gray-300 dark:text-gray-600 group-hover:text-gray-400'"
                fill="currentColor" viewBox="0 0 20 20"
            >
                <path d="M15 8l-5 5-5-5h10z"/>
            </svg>
        </span>
    </button>
</th>
{% endmacro %}


{#
  Sortable Table Header
  =====================
  Renders a table header with sortable columns.

  Parameters:
    - columns: List of column definitions [{'label': '', 'key': '', 'sortable': true/false, 'width': ''}]
    - sort_key_var: Alpine.js variable for current sort key (default: 'sortKey')
    - sort_dir_var: Alpine.js variable for sort direction (default: 'sortDir')
    - on_sort: Alpine.js handler when column is clicked (default: 'sortBy')

  Usage:
    {{ sortable_table_header([
        {'label': 'Name', 'key': 'name', 'sortable': true},
        {'label': 'Email', 'key': 'email', 'sortable': true},
        {'label': 'Status', 'key': 'status', 'sortable': false},
        {'label': 'Actions', 'key': 'actions', 'sortable': false, 'width': 'w-24'}
    ]) }}

  Required Alpine.js:
    sortKey: 'name',
    sortDir: 'asc',
    sortBy(key) {
        if (this.sortKey === key) {
            this.sortDir = this.sortDir === 'asc' ? 'desc' : 'asc';
        } else {
            this.sortKey = key;
            this.sortDir = 'asc';
        }
        this.loadItems();
    }
#}
{% macro sortable_table_header(columns, sort_key_var='sortKey', sort_dir_var='sortDir', on_sort='sortBy') %}
<thead>
    <tr class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800">
        {% for col in columns %}
        <th class="px-4 py-3 {{ col.width if col.width else '' }}">
            {% if col.sortable %}
            <button
                @click="{{ on_sort }}('{{ col.key }}')"
                class="flex items-center space-x-1 hover:text-gray-700 dark:hover:text-gray-200 transition-colors group"
            >
                <span>{{ col.label }}</span>
                <span class="flex flex-col">
                    <svg
                        class="w-3 h-3 -mb-1 transition-colors"
                        :class="{{ sort_key_var }} === '{{ col.key }}' && {{ sort_dir_var }} === 'asc' ? 'text-purple-600 dark:text-purple-400' : 'text-gray-300 dark:text-gray-600 group-hover:text-gray-400'"
                        fill="currentColor" viewBox="0 0 20 20"
                    >
                        <path d="M5 12l5-5 5 5H5z"/>
                    </svg>
                    <svg
                        class="w-3 h-3 -mt-1 transition-colors"
                        :class="{{ sort_key_var }} === '{{ col.key }}' && {{ sort_dir_var }} === 'desc' ? 'text-purple-600 dark:text-purple-400' : 'text-gray-300 dark:text-gray-600 group-hover:text-gray-400'"
                        fill="currentColor" viewBox="0 0 20 20"
                    >
                        <path d="M15 8l-5 5-5-5h10z"/>
                    </svg>
                </span>
            </button>
            {% else %}
            {{ col.label }}
            {% endif %}
        </th>
        {% endfor %}
    </tr>
</thead>
{% endmacro %}


{#
  Table Body Wrapper
  ==================
  Wraps the tbody with proper styling.
#}
{% macro table_body() %}
<tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
    {{ caller() }}
</tbody>
{% endmacro %}


{#
  Table Empty State
  =================
  Shows a centered message when the table has no data.

  Parameters:
    - colspan: Number of columns to span
    - icon: Icon name (default: 'inbox')
    - title: Empty state title
    - message: Empty state message
    - show_condition: Alpine.js condition (default: 'true')
    - has_filters: Whether to show filter hint (default: true)
    - x_message: Alpine.js expression for dynamic message (rendered via x-text)
#}
{% macro table_empty_state(colspan, icon='inbox', title='No data found', message='', show_condition='true', has_filters=true, x_message='') %}
<template x-if="{{ show_condition }}">
    <tr>
        <td colspan="{{ colspan }}" class="px-4 py-8 text-center text-gray-600 dark:text-gray-400">
            <div class="flex flex-col items-center">
                <span x-html="$icon('{{ icon }}', 'w-12 h-12 mb-2 text-gray-300')"></span>
                <p class="font-medium">{{ title }}</p>
                {% if x_message %}
                <p class="text-xs mt-1" x-text="{{ x_message }}"></p>
                {% elif message %}
                <p class="text-xs mt-1">{{ message }}</p>
                {% elif has_filters %}
                <p class="text-xs mt-1">Try adjusting your search or filters</p>
                {% endif %}
            </div>
        </td>
    </tr>
</template>
{% endmacro %}


{#
  Table Row
  =========
  A standard table row with hover styling.
#}
{% macro table_row(class_extra='') %}
<tr class="text-gray-700 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 {{ class_extra }}">
    {{ caller() }}
</tr>
{% endmacro %}


{#
  Table Cell
  ==========
  A standard table cell.
#}
{% macro table_cell(class_extra='') %}
<td class="px-4 py-3 {{ class_extra }}">
    {{ caller() }}
</td>
{% endmacro %}


{#
  Table Cell with Text
  ====================
  A simple text cell.

  Parameters:
    - text: Static text or Alpine.js expression for x-text
    - is_dynamic: Whether text is Alpine.js expression (default: false)
    - truncate: Whether to truncate with max-width (default: false)
    - max_width: Max width class (default: 'max-w-xs')
#}
{% macro table_cell_text(text, is_dynamic=false, truncate=false, max_width='max-w-xs') %}
<td class="px-4 py-3 text-sm">
    {% if truncate %}
    <p class="truncate {{ max_width }}" {% if is_dynamic %}x-text="{{ text }}" :title="{{ text }}"{% endif %}>
        {% if not is_dynamic %}{{ text }}{% endif %}
    </p>
    {% else %}
    {% if is_dynamic %}
    <span x-text="{{ text }}"></span>
    {% else %}
    {{ text }}
    {% endif %}
    {% endif %}
</td>
{% endmacro %}


{#
  Table Cell with Avatar
  ======================
  A cell with avatar image and text.

  Parameters:
    - image_src: Image source (Alpine.js expression)
    - title: Primary text (Alpine.js expression)
    - subtitle: Secondary text (Alpine.js expression, optional)
    - fallback_icon: Icon to show if no image (default: 'user')
#}
{% macro table_cell_avatar(image_src, title, subtitle=none, fallback_icon='user') %}
<td class="px-4 py-3">
    <div class="flex items-center text-sm">
        <div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
            <template x-if="{{ image_src }}">
                <img class="object-cover w-full h-full rounded-full" :src="{{ image_src }}" :alt="{{ title }}" loading="lazy">
            </template>
            <template x-if="!{{ image_src }}">
                <div class="flex items-center justify-center w-full h-full bg-gray-200 dark:bg-gray-700 rounded-full">
                    <span x-html="$icon('{{ fallback_icon }}', 'w-4 h-4 text-gray-500')"></span>
                </div>
            </template>
            <div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true"></div>
        </div>
        <div>
            <p class="font-semibold" x-text="{{ title }}"></p>
            {% if subtitle %}
            <p class="text-xs text-gray-600 dark:text-gray-400" x-text="{{ subtitle }}"></p>
            {% endif %}
        </div>
    </div>
</td>
{% endmacro %}


{#
  Table Cell with Date
  ====================
  A cell that formats a date.

  Parameters:
    - date_var: Alpine.js variable containing the date
    - format_func: JavaScript date formatting function (default: 'formatDate')
#}
{% macro table_cell_date(date_var, format_func='formatDate') %}
<td class="px-4 py-3 text-sm">
    <span x-text="{{ format_func }}({{ date_var }})"></span>
</td>
{% endmacro %}


{#
  Table Loading Overlay
  =====================
  An overlay shown while table data is loading.

  Parameters:
    - show_condition: Alpine.js condition (default: 'loading')
    - message: Loading message
#}
{% macro table_loading_overlay(show_condition='loading', message='Loading...') %}
<div x-show="{{ show_condition }}" class="absolute inset-0 bg-white/75 dark:bg-gray-800/75 flex items-center justify-center z-10">
    <div class="text-center">
        <span x-html="$icon('spinner', 'inline w-8 h-8 text-purple-600')"></span>
        <p class="mt-2 text-sm text-gray-600 dark:text-gray-400">{{ message }}</p>
    </div>
</div>
{% endmacro %}


{#
  Numbered Pagination
  ===================
  A numbered pagination component with first/prev/pages/next/last buttons.

  Parameters:
    - page_var: Alpine.js variable for current page (default: 'page')
    - total_var: Alpine.js variable for total items (default: 'total')
    - limit_var: Alpine.js variable for items per page (default: 'limit')
    - on_change: Alpine.js function to call on page change (default: 'loadItems()')
    - show_rows_per_page: Whether to show rows per page selector (default: false)
    - rows_options: List of rows per page options (default: [10, 20, 50, 100])

  Required Alpine.js:
    page: 1,
    total: 0,
    limit: 20,
    get totalPages() { return Math.ceil(this.total / this.limit); },
    getPageNumbers() {
        // Returns array of page numbers to display
        const total = this.totalPages;
        const current = this.page;
        const maxVisible = 5;

        if (total <= maxVisible) {
            return Array.from({length: total}, (_, i) => i + 1);
        }

        const half = Math.floor(maxVisible / 2);
        let start = Math.max(1, current - half);
        let end = Math.min(total, start + maxVisible - 1);

        if (end - start < maxVisible - 1) {
            start = Math.max(1, end - maxVisible + 1);
        }

        return Array.from({length: end - start + 1}, (_, i) => start + i);
    },
    goToPage(p) {
        this.page = p;
        this.loadItems();
    }
#}
{% macro numbered_pagination(page_var='page', total_var='total', limit_var='limit', on_change='loadItems()', show_rows_per_page=false, rows_options=[10, 20, 50, 100]) %}
<div x-show="{{ total_var }} > {{ limit_var }}" class="flex flex-col sm:flex-row items-center justify-between gap-4 mt-4 pt-4 border-t dark:border-gray-700">
    {# Info text #}
    <span class="text-sm text-gray-600 dark:text-gray-400">
        Showing
        <span x-text="(({{ page_var }} - 1) * {{ limit_var }}) + 1"></span>-<span x-text="Math.min({{ page_var }} * {{ limit_var }}, {{ total_var }})"></span>
        of <span x-text="{{ total_var }}"></span> items
    </span>

    {# Pagination controls #}
    <div class="flex items-center gap-1">
        {# First page #}
        <button
            @click="{{ page_var }} = 1; {{ on_change }}"
            :disabled="{{ page_var }} <= 1"
            class="px-2 py-1 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed"
            title="First page"
        >
            <span x-html="$icon('chevron-double-left', 'w-4 h-4')"></span>
        </button>

        {# Previous page #}
        <button
            @click="{{ page_var }}--; {{ on_change }}"
            :disabled="{{ page_var }} <= 1"
            class="px-2 py-1 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed"
            title="Previous page"
        >
            <span x-html="$icon('chevron-left', 'w-4 h-4')"></span>
        </button>

        {# Page numbers #}
        <template x-for="p in getPageNumbers()" :key="p">
            <button
                @click="goToPage(p)"
                class="px-3 py-1 text-sm font-medium rounded-md border transition-colors"
                :class="p === {{ page_var }}
                    ? 'bg-purple-600 text-white border-purple-600 dark:bg-purple-500 dark:border-purple-500'
                    : 'text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-600'"
                x-text="p"
            ></button>
        </template>

        {# Next page #}
        <button
            @click="{{ page_var }}++; {{ on_change }}"
            :disabled="{{ page_var }} >= Math.ceil({{ total_var }} / {{ limit_var }})"
            class="px-2 py-1 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed"
            title="Next page"
        >
            <span x-html="$icon('chevron-right', 'w-4 h-4')"></span>
        </button>

        {# Last page #}
        <button
            @click="{{ page_var }} = Math.ceil({{ total_var }} / {{ limit_var }}); {{ on_change }}"
            :disabled="{{ page_var }} >= Math.ceil({{ total_var }} / {{ limit_var }})"
            class="px-2 py-1 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed"
            title="Last page"
        >
            <span x-html="$icon('chevron-double-right', 'w-4 h-4')"></span>
        </button>
    </div>

    {% if show_rows_per_page %}
    {# Rows per page selector #}
    <div class="flex items-center gap-2">
        <label class="text-sm text-gray-600 dark:text-gray-400">Rows:</label>
        <select
            x-model.number="{{ limit_var }}"
            @change="{{ page_var }} = 1; {{ on_change }}"
            class="px-2 py-1 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md focus:border-purple-400 focus:outline-none"
        >
            {% for opt in rows_options %}
            <option value="{{ opt }}">{{ opt }}</option>
            {% endfor %}
        </select>
    </div>
    {% endif %}
</div>
{% endmacro %}


{#
  Simple Pagination
  =================
  A simpler prev/next pagination without page numbers.
  Use this for quick implementation or when numbered pagination isn't needed.

  Parameters:
    - page_var: Alpine.js variable for current page (default: 'page')
    - total_var: Alpine.js variable for total items (default: 'total')
    - limit_var: Alpine.js variable for items per page (default: 'limit')
    - on_change: Alpine.js function to call on page change (default: 'loadItems()')
#}
{% macro simple_pagination(page_var='page', total_var='total', limit_var='limit', on_change='loadItems()') %}
<div x-show="{{ total_var }} > {{ limit_var }}" class="flex items-center justify-between mt-4 pt-4 border-t dark:border-gray-700">
    <span class="text-sm text-gray-600 dark:text-gray-400">
        Showing
        <span x-text="(({{ page_var }} - 1) * {{ limit_var }}) + 1"></span>-<span x-text="Math.min({{ page_var }} * {{ limit_var }}, {{ total_var }})"></span>
        of <span x-text="{{ total_var }}"></span>
    </span>
    <div class="flex items-center gap-2">
        <button
            @click="{{ page_var }}--; {{ on_change }}"
            :disabled="{{ page_var }} <= 1"
            class="px-3 py-1 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-600 disabled:opacity-50"
        >
            <span x-html="$icon('chevron-left', 'w-4 h-4')"></span>
        </button>
        <button
            @click="{{ page_var }}++; {{ on_change }}"
            :disabled="{{ page_var }} * {{ limit_var }} >= {{ total_var }}"
            class="px-3 py-1 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-600 disabled:opacity-50"
        >
            <span x-html="$icon('chevron-right', 'w-4 h-4')"></span>
        </button>
    </div>
</div>
{% endmacro %}
