<template>
  <article class="glass-panel resource-table-panel">
    <div class="resource-toolbar">
      <slot name="toolbar-leading" />
      <label class="search-control">
        <Search :size="15" />
        <input :value="search" :placeholder="searchPlaceholder" @input="$emit('update:search', $event.target.value)" />
        <button v-if="search" class="search-clear" type="button" aria-label="Clear search" @click="$emit('update:search', '')">
          <X :size="13" />
        </button>
      </label>
      <label class="table-density-select">
        <span>Rows</span>
        <select :value="pageSize" @change="$emit('update:pageSize', Number($event.target.value))">
          <option :value="8">8</option>
          <option :value="12">12</option>
          <option :value="20">20</option>
        </select>
      </label>
      <span class="toolbar-count">{{ total }} {{ itemLabel }}</span>
      <slot name="toolbar-actions" />
    </div>
    <div v-if="search || sort" class="resource-filter-strip">
      <span v-if="search">Search: <strong>{{ search }}</strong></span>
      <span v-if="sort">Sort: <strong>{{ activeSortLabel }}</strong> {{ direction }}</span>
    </div>
    <div v-if="rows.length" class="data-table-wrap">
      <table class="data-table resource-table">
        <thead>
          <tr>
            <th v-for="column in columns" :key="column.key">
              <button v-if="column.sortable !== false" type="button" :aria-sort="sortAria(column.key)" @click="$emit('sort', column.key)">
                {{ column.label }}
                <component :is="sortIcon(column.key)" :size="13" />
              </button>
              <template v-else>{{ column.label }}</template>
            </th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="row in rows" :key="row.id">
            <td v-for="column in columns" :key="column.key" :class="column.class">
              <slot :name="`cell-${column.key}`" :row="row" :value="row[column.key]">
                {{ row[column.key] || '-' }}
              </slot>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <div v-else class="resource-empty-shell">
      <slot name="empty">
        <div class="widget-empty">{{ emptyText }}</div>
      </slot>
    </div>
    <div class="pagination">
      <button class="ghost-button compact" :disabled="page <= 1" aria-label="Previous page" @click="$emit('update:page', page - 1)">
        <ChevronLeft :size="15" />Previous
      </button>
      <span>Page {{ Math.min(page, pageCount) }} of {{ pageCount }}</span>
      <button class="ghost-button compact" :disabled="page >= pageCount" aria-label="Next page" @click="$emit('update:page', page + 1)">
        Next<ChevronRight :size="15" />
      </button>
    </div>
  </article>
</template>

<script setup>
import { computed } from 'vue';
import { ArrowDownAZ, ArrowUpAZ, ChevronsUpDown, ChevronLeft, ChevronRight, Search, X } from '@lucide/vue';

const props = defineProps({
  columns: { type: Array, required: true },
  rows: { type: Array, required: true },
  total: { type: Number, required: true },
  search: { type: String, default: '' },
  page: { type: Number, default: 1 },
  pageCount: { type: Number, default: 1 },
  pageSize: { type: Number, default: 8 },
  sort: { type: String, default: '' },
  direction: { type: String, default: 'asc' },
  searchPlaceholder: { type: String, default: 'Search...' },
  itemLabel: { type: String, default: 'items' },
  emptyText: { type: String, default: 'No rows match the current filters.' }
});

defineEmits(['update:search', 'update:page', 'update:pageSize', 'sort']);

const activeSortLabel = computed(() => props.columns.find((column) => column.key === props.sort)?.label || props.sort);

function sortIcon(key) {
  if (props.sort !== key) return ChevronsUpDown;
  return props.direction === 'asc' ? ArrowUpAZ : ArrowDownAZ;
}

function sortAria(key) {
  if (props.sort !== key) return 'none';
  return props.direction === 'asc' ? 'ascending' : 'descending';
}
</script>
