<script setup>
import { ref, computed, watch } from 'vue';
import { router } from '@inertiajs/vue3';
import DataTableToolbar from './DataTableToolbar.vue';
import SkeletonTable from '../Skeleton/SkeletonTable.vue';
import EmptyState from '../EmptyState.vue';
import Pagination from '../Pagination.vue';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import {
  faChevronLeft,
  faChevronRight,
  faSort,
  faSortUp,
  faSortDown,
} from '@fortawesome/free-solid-svg-icons';

const props = defineProps({
  // Data
  rows: { type: Array, default: () => [] },
  columns: {
    type: Array,
    required: true,
    validator: (cols) =>
      cols.every(
        (col) => col.key && col.label && typeof col.key === 'string' && typeof col.label === 'string'
      ),
  },
  
  // Pagination (for server-side)
  meta: {
    type: Object,
    default: null,
    validator: (meta) =>
      !meta ||
      (typeof meta.current_page === 'number' &&
        typeof meta.per_page === 'number' &&
        typeof meta.total === 'number' &&
        typeof meta.last_page === 'number'),
  },
  
  // Sorting
  sort: {
    type: Object,
    default: () => ({ key: null, direction: null }),
  },
  
  // Search
  search: { type: String, default: '' },
  
  // Loading state
  loading: { type: Boolean, default: false },
  
  // Client-side pagination (when meta is null)
  pageSize: { type: Number, default: 10 },
  pageSizeOptions: { type: Array, default: () => [10, 25, 50, 100] },
  
  // Routing (for server-side)
  routeName: { type: String, default: null },
  routeParams: { type: Object, default: () => ({}) },
  pageParamName: { type: String, default: 'page' },
  onlyProps: { type: Array, default: () => [] },
  
  // Features
  showToolbar: { type: Boolean, default: true },
  showSearch: { type: Boolean, default: false },
  showPageSize: { type: Boolean, default: false },
  showPagination: { type: Boolean, default: true },
  showFilters: { type: Boolean, default: false },
  showExport: { type: Boolean, default: false },
  showAdd: { type: Boolean, default: false }, // Show add buttons dropdown
  showOptions: { type: Boolean, default: false }, // Show custom options slot
  showSelectedCount: { type: Boolean, default: false }, // Show selected count badge
  showOptionsMenu: { type: Boolean, default: false }, // Show options menu (three dots)
  compactToolbar: { type: Boolean, default: false }, // Compact mode: move search/page size to menu
  hasActiveFilters: { type: Boolean, default: false }, // External indicator for active filters
  rowKey: { type: [String, Function], default: 'uuid' },
  selectable: { type: Boolean, default: false },
  striped: { type: Boolean, default: false },
  hoverable: { type: Boolean, default: true },
  
  // Empty state
  emptyText: { type: String, default: 'Ni podatkov' },
  emptyIcon: { type: [String, Object, Array], default: null },
  emptyDescription: { type: String, default: null },
  
  // Actions
  showActions: { type: Boolean, default: false },
  actionsPosition: { type: String, default: 'right', validator: (v) => ['left', 'right'].includes(v) },
  
  // Mobile
  mobileCardView: { type: Boolean, default: true },
  mobileBreakpoint: { type: Number, default: 768 }, // Tailwind md breakpoint
  
  // State preservation
  preserveState: { type: Boolean, default: true },
  preserveScroll: { type: Boolean, default: true },
});

const emit = defineEmits([
  'update:search',
  'update:sort',
  'update:page',
  'update:pageSize',
  'row:click',
  'row:select',
  'selection:change',
]);

// Determine if this is server-side (has meta and routeName)
const isServerSide = computed(() => !!(props.meta && props.routeName));
const isClientSide = computed(() => !isServerSide.value);

// Row key helper
function keyOf(row) {
  if (typeof props.rowKey === 'function') return props.rowKey(row);
  if (typeof props.rowKey === 'string' && row && row[props.rowKey] != null)
    return row[props.rowKey];
  return row?.uuid ?? row?.id ?? Math.random().toString(36).slice(2);
}

// Client-side sorting
const sortedRows = computed(() => {
  if (isServerSide.value || !props.sort?.key || !props.sort?.direction) {
    return props.rows;
  }
  
  const key = props.sort.key;
  const direction = props.sort.direction;
  const sorted = [...props.rows];
  
  sorted.sort((a, b) => {
    let aVal = a?.[key];
    let bVal = b?.[key];
    
    // Handle nulls/undefined
    if (aVal == null) return 1;
    if (bVal == null) return -1;
    
    // Handle dates
    if (aVal instanceof Date || (typeof aVal === 'string' && aVal.match(/\d{4}-\d{2}-\d{2}/))) {
      aVal = new Date(aVal);
      bVal = new Date(bVal);
    }
    
    // Handle numbers
    if (typeof aVal === 'number' && typeof bVal === 'number') {
      return direction === 'asc' ? aVal - bVal : bVal - aVal;
    }
    
    // Handle strings
    const aStr = String(aVal).toLowerCase();
    const bStr = String(bVal).toLowerCase();
    if (direction === 'asc') {
      return aStr.localeCompare(bStr);
    }
    return bStr.localeCompare(aStr);
  });
  
  return sorted;
});

// Client-side pagination
const currentPage = computed(() => {
  if (isServerSide.value) return props.meta?.current_page ?? 1;
  return internalPage.value;
});

const internalPage = ref(1);
// Use computed for pageSize to always reflect the correct value
// For server-side: use meta.per_page, for client-side: use internal state or props.pageSize
const internalPageSize = computed({
  get: () => {
    if (isServerSide.value && props.meta?.per_page) {
      return props.meta.per_page;
    }
    return internalPageSizeState.value ?? props.pageSize;
  },
  set: (value) => {
    internalPageSizeState.value = value;
  }
});

// Internal state for client-side or when user changes page size before server responds
const internalPageSizeState = ref(null);

const totalPages = computed(() => {
  if (isServerSide.value) return props.meta?.last_page ?? 1;
  return Math.ceil(sortedRows.value.length / internalPageSize.value);
});

const paginatedRows = computed(() => {
  if (isServerSide.value) return props.rows;
  
  const start = (currentPage.value - 1) * internalPageSize.value;
  const end = start + internalPageSize.value;
  return sortedRows.value.slice(start, end);
});

// Client-side search
const filteredRows = computed(() => {
  if (isServerSide.value || !internalSearch.value) {
    return paginatedRows.value;
  }
  
  const searchTerm = internalSearch.value.toLowerCase();
  return paginatedRows.value.filter((row) => {
    return props.columns.some((col) => {
      const value = row?.[col.key];
      if (value == null) return false;
      return String(value).toLowerCase().includes(searchTerm);
    });
  });
});

// Search handling
const internalSearch = ref(props.search);
watch(
  () => props.search,
  (newVal) => {
    internalSearch.value = newVal;
  }
);

// Selection
const selectedRows = ref(new Set());
const isAllSelected = computed(() => {
  if (filteredRows.value.length === 0) return false;
  return filteredRows.value.every((row) => selectedRows.value.has(keyOf(row)));
});
const isSomeSelected = computed(() => {
  return (
    selectedRows.value.size > 0 &&
    filteredRows.value.some((row) => selectedRows.value.has(keyOf(row)))
  );
});

function toggleSelectAll() {
  if (isAllSelected.value) {
    filteredRows.value.forEach((row) => {
      selectedRows.value.delete(keyOf(row));
    });
  } else {
    filteredRows.value.forEach((row) => {
      selectedRows.value.add(keyOf(row));
    });
  }
  emit('selection:change', Array.from(selectedRows.value));
}

function toggleSelectRow(row) {
  const key = keyOf(row);
  if (selectedRows.value.has(key)) {
    selectedRows.value.delete(key);
  } else {
    selectedRows.value.add(key);
  }
  emit('row:select', row, selectedRows.value.has(key));
  emit('selection:change', Array.from(selectedRows.value));
}

// Sorting
function toggleSort(col) {
  if (!col.sortable) return;
  
  if (isServerSide.value) {
    const current = props.sort || { key: null, direction: null };
    let direction = 'asc';
    if (current.key === col.key) {
      direction =
        current.direction === 'asc' ? 'desc' : current.direction === 'desc' ? null : 'asc';
    }
    emit('update:sort', { key: direction ? col.key : null, direction });
    doServerRequest({ sort: direction ? col.key : null, direction, page: 1 });
  } else {
    const current = props.sort || { key: null, direction: null };
    let direction = 'asc';
    if (current.key === col.key) {
      direction =
        current.direction === 'asc' ? 'desc' : current.direction === 'desc' ? null : 'asc';
    }
    emit('update:sort', { key: direction ? col.key : null, direction });
  }
}

function getSortIcon(col) {
  if (props.sort?.key !== col.key) return faSort;
  if (props.sort?.direction === 'asc') return faSortUp;
  if (props.sort?.direction === 'desc') return faSortDown;
  return faSort;
}

// Server-side request
function doServerRequest(overrides = {}) {
  // Preserve existing query parameters from URL
  const existingParams = Object.fromEntries(
    new URLSearchParams(window.location.search).entries()
  );
  
  const q = {
    ...existingParams, // Preserve all existing query parameters
    per_page: overrides.perPage ?? props.meta?.per_page ?? internalPageSizeState.value ?? internalPageSize.value,
    sort: overrides.sort ?? props.sort?.key ?? existingParams.sort ?? null,
    direction: overrides.direction ?? props.sort?.direction ?? existingParams.direction ?? null,
    search: overrides.search ?? internalSearch.value ?? existingParams.search ?? '',
  };
  
  const pageParam = props.pageParamName || 'page';
  q[pageParam] = overrides.page ?? props.meta?.current_page ?? 1;
  if (pageParam !== 'page') {
    delete q.page;
  }
  
  // Clean nulls and empty strings
  Object.keys(q).forEach((k) => {
    if (q[k] === null || q[k] === undefined || q[k] === '') delete q[k];
  });
  
  const url = route(props.routeName, props.routeParams || {});
  router.get(
    url,
    q,
    {
      preserveScroll: props.preserveScroll,
      preserveState: props.preserveState,
      replace: true,
      only: props.onlyProps.length ? props.onlyProps : undefined,
      onSuccess: () => {
        // Scroll to top of table after server request completes
        setTimeout(() => {
          const tableElement = document.querySelector('[data-table-container]');
          if (tableElement) {
            tableElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
          } else {
            window.scrollTo({ top: 0, behavior: 'smooth' });
          }
        }, 100);
      },
    }
  );
}

function handleSearchChange(value) {
  internalSearch.value = value;
  emit('update:search', value);
  
  if (isServerSide.value) {
    clearTimeout(searchTimer.value);
    searchTimer.value = setTimeout(() => {
      doServerRequest({ search: value, page: 1 });
    }, 300);
  }
}

function handlePageSizeChange(size) {
  const newSize = Number(size);
  internalPageSizeState.value = newSize;
  emit('update:pageSize', newSize);
  
  if (isServerSide.value) {
    // Reset to page 1 when changing page size to avoid being on a non-existent page
    doServerRequest({ perPage: newSize, page: 1 });
  } else {
    // Calculate total pages with new size
    const newTotalPages = Math.ceil(sortedRows.value.length / newSize);
    // If current page exceeds new total, reset to last page or page 1
    const targetPage = currentPage.value > newTotalPages && newTotalPages > 0 ? newTotalPages : 1;
    internalPage.value = targetPage;
    emit('update:page', targetPage);
  }
}

function handlePageChange(page) {
  if (isServerSide.value) {
    doServerRequest({ page });
  } else {
    internalPage.value = page;
    emit('update:page', page);
  }
  
  // Scroll to top of table after page change
  setTimeout(() => {
    const tableElement = document.querySelector('[data-table-container]');
    if (tableElement) {
      tableElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
    } else {
      window.scrollTo({ top: 0, behavior: 'smooth' });
    }
  }, isServerSide.value ? 100 : 50);
}

const searchTimer = ref(null);

// Mobile detection
const isMobile = ref(false);
if (typeof window !== 'undefined') {
  const checkMobile = () => {
    isMobile.value = window.innerWidth < props.mobileBreakpoint;
  };
  checkMobile();
  window.addEventListener('resize', checkMobile);
}

// Display rows
const displayRows = computed(() => {
  if (isServerSide.value || !internalSearch.value) {
    return paginatedRows.value;
  }
  return filteredRows.value;
});

const total = computed(() => {
  if (isServerSide.value) return props.meta?.total ?? 0;
  return internalSearch.value ? filteredRows.value.length : sortedRows.value.length;
});

const from = computed(() => {
  if (isServerSide.value) return props.meta?.from ?? 0;
  return total.value === 0 ? 0 : (currentPage.value - 1) * internalPageSize.value + 1;
});

const to = computed(() => {
  if (isServerSide.value) return props.meta?.to ?? 0;
  return Math.min(currentPage.value * internalPageSize.value, total.value);
});

// Export functionality
function handleExport(format) {
  const data = displayRows.value.map((row) => {
    const exported = {};
    props.columns.forEach((col) => {
      exported[col.label] = row?.[col.key] ?? '';
    });
    return exported;
  });

  if (format === 'csv') {
    exportToCSV(data);
  } else if (format === 'xlsx') {
    exportToXLSX(data);
  }
}

function exportToCSV(data) {
  if (data.length === 0) return;

  const headers = Object.keys(data[0]);
  const csvContent = [
    headers.join(','),
    ...data.map((row) =>
      headers
        .map((header) => {
          const value = row[header];
          if (value == null) return '';
          const stringValue = String(value).replace(/"/g, '""');
          return `"${stringValue}"`;
        })
        .join(',')
    ),
  ].join('\n');

  const blob = new Blob(['\uFEFF' + csvContent], { type: 'text/csv;charset=utf-8;' });
  const link = document.createElement('a');
  const url = URL.createObjectURL(blob);
  link.setAttribute('href', url);
  link.setAttribute('download', `export_${new Date().toISOString().split('T')[0]}.csv`);
  link.style.visibility = 'hidden';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

function exportToXLSX(data) {
  // For XLSX, we'll use a CSV-like format or alert user to install xlsx library
  // Simple implementation: use CSV format with .xlsx extension
  exportToCSV(data);
  // In production, you might want to use a library like 'xlsx' or 'exceljs'
}

// Generate visible page numbers with ellipsis
function getVisiblePages() {
  const pages = [];
  const total = totalPages.value;
  const current = currentPage.value;
  const maxVisible = 7;
  
  if (total <= maxVisible) {
    for (let i = 1; i <= total; i++) {
      pages.push(i);
    }
    return pages;
  }
  
  // Always show first page
  pages.push(1);
  
  // Calculate start and end
  let start = Math.max(2, current - 1);
  let end = Math.min(total - 1, current + 1);
  
  // Adjust if near start
  if (current <= 3) {
    end = Math.min(4, total - 1);
  }
  
  // Adjust if near end
  if (current >= total - 2) {
    start = Math.max(2, total - 3);
  }
  
  // Add ellipsis after first page if needed
  if (start > 2) {
    pages.push('...');
  }
  
  // Add middle pages
  for (let i = start; i <= end; i++) {
    pages.push(i);
  }
  
  // Add ellipsis before last page if needed
  if (end < total - 1) {
    pages.push('...');
  }
  
  // Always show last page
  if (total > 1) {
    pages.push(total);
  }
  
  return pages;
}
</script>

<template>
  <div class="w-full space-y-4">
    <!-- Toolbar -->
    <DataTableToolbar
      v-if="showToolbar"
      :search="internalSearch"
      :show-search="showSearch"
      :show-page-size="showPageSize"
      :page-size="internalPageSize"
      :page-size-options="pageSizeOptions"
      :selected-count="selectedRows.size"
      :show-selected-count="showSelectedCount"
      :show-export="showExport"
      :show-add="showAdd"
      :show-options="showOptions"
      :show-filters="showFilters"
      :show-options-menu="showOptionsMenu"
      :has-active-filters="hasActiveFilters"
      :compact="compactToolbar"
      @update:search="handleSearchChange"
      @update:page-size="handlePageSizeChange"
      @export="handleExport"
    >
      <template #add>
        <slot name="toolbar-add" />
      </template>
      <template #options>
        <slot name="toolbar-options" />
      </template>
      <template #filters>
        <slot name="toolbar-filters" />
      </template>
      <template #actions>
        <slot name="toolbar-actions" />
      </template>
    </DataTableToolbar>

    <!-- Table Container -->
    <div
      data-table-container
      class="relative overflow-hidden"
    >
      <!-- Desktop Table View -->
      <div v-if="!isMobile || !mobileCardView" class="overflow-x-auto">
        <table class="min-w-full divide-y divide-gray-200">
          <!-- Header -->
          <thead>
            <tr>
              <!-- Select All Checkbox -->
              <th
                v-if="selectable"
                class="w-12 px-6 py-3 text-left"
                scope="col"
              >
                <input
                  type="checkbox"
                  :checked="isAllSelected"
                  :indeterminate="isSomeSelected && !isAllSelected"
                  @change="toggleSelectAll"
                  class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
                />
              </th>

              <!-- Column Headers -->
              <th
                v-for="col in columns"
                :key="col.key"
                scope="col"
                class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500"
                :class="[
                  col.class,
                  col.align === 'right' ? 'text-right' : col.align === 'center' ? 'text-center' : 'text-left',
                ]"
              >
                <button
                  v-if="col.sortable"
                  type="button"
                  class="group inline-flex items-center gap-1.5 hover:text-gray-700 transition-colors"
                  @click="toggleSort(col)"
                  :aria-sort="sort?.key === col.key ? sort.direction || 'none' : 'none'"
                >
                  <span>{{ col.label }}</span>
                  <FontAwesomeIcon
                    :icon="getSortIcon(col)"
                    class="w-3 h-3 transition-colors"
                    :class="{
                      'text-gray-700': sort?.key === col.key,
                      'text-gray-400 group-hover:text-gray-500': sort?.key !== col.key,
                    }"
                  />
                </button>
                <span v-else>{{ col.label }}</span>
              </th>

              <!-- Actions Column -->
              <th
                v-if="showActions || $slots.actions"
                scope="col"
                class="relative w-px px-6 py-3"
              >
                <span class="sr-only">Actions</span>
              </th>
            </tr>
          </thead>

          <!-- Body -->
          <tbody class="divide-y divide-gray-200 bg-white">
            <!-- Loading State -->
            <template v-if="loading">
              <tr>
                <td :colspan="columns.length + (selectable ? 1 : 0) + (showActions ? 1 : 0)" class="px-6 py-4">
                  <SkeletonTable :rows="5" :cols="columns.length" />
                </td>
              </tr>
            </template>

            <!-- Empty State -->
            <template v-else-if="!loading && displayRows.length === 0">
              <tr>
                <td
                  :colspan="columns.length + (selectable ? 1 : 0) + (showActions ? 1 : 0)"
                  class="px-6 py-12 text-center"
                >
                  <EmptyState
                    :icon="emptyIcon"
                    :title="emptyText"
                    :description="emptyDescription"
                    size="sm"
                  />
                </td>
              </tr>
            </template>

            <!-- Rows -->
            <template v-else>
              <tr
                v-for="(row, idx) in displayRows"
                :key="keyOf(row)"
                @click="(e) => { const interactive = e.target.closest('button, a, [role=button], [data-dropdown], .relative'); if (interactive) return; $emit('row:click', row, idx); }"
                class="transition-colors"
                :class="{
                  'cursor-pointer': !!$attrs.onRowClick,
                  'bg-gray-50': striped && idx % 2 === 1,
                  'hover:bg-gray-50': hoverable && !selectedRows.has(keyOf(row)),
                  'bg-primary-50': selectedRows.has(keyOf(row)),
                }"
              >
                <!-- Select Checkbox -->
                <td v-if="selectable" class="px-6 py-4 whitespace-nowrap">
                  <input
                    type="checkbox"
                    :checked="selectedRows.has(keyOf(row))"
                    @click.stop="toggleSelectRow(row)"
                    class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
                  />
                </td>

                <!-- Data Cells -->
                <td
                  v-for="col in columns"
                  :key="col.key"
                  class="px-6 py-4 whitespace-nowrap text-sm"
                  :class="[
                    col.class,
                    col.align === 'right'
                      ? 'text-right text-gray-900'
                      : col.align === 'center'
                      ? 'text-center text-gray-900'
                      : 'text-left text-gray-900',
                  ]"
                >
                  <slot
                    :name="`cell-${col.key}`"
                    :row="row"
                    :column="col"
                    :value="row?.[col.key]"
                    :index="idx"
                  >
                    <slot name="cell" :row="row" :column="col" :value="row?.[col.key]" :index="idx">
                      <span>{{ row?.[col.key] ?? '—' }}</span>
                    </slot>
                  </slot>
                </td>

                <!-- Actions Cell -->
                <td
                  v-if="showActions || $slots.actions"
                  class="relative whitespace-nowrap py-4 pl-3 pr-6 text-right text-sm font-medium"
                >
                  <slot name="actions" :row="row" :index="idx">
                    <slot name="row-actions" :row="row" :index="idx" />
                  </slot>
                </td>
              </tr>
            </template>
          </tbody>
        </table>
      </div>

      <!-- Mobile Card View -->
      <div v-else-if="isMobile && mobileCardView" class="divide-y divide-gray-200">
        <template v-if="loading">
          <div class="p-4">
            <SkeletonTable :rows="3" :cols="1" />
          </div>
        </template>

        <template v-else-if="!loading && displayRows.length === 0">
          <div class="p-6">
            <EmptyState
              :icon="emptyIcon"
              :title="emptyText"
              :description="emptyDescription"
              size="sm"
            />
          </div>
        </template>

        <template v-else>
          <div
            v-for="(row, idx) in displayRows"
            :key="keyOf(row)"
            @click="$emit('row:click', row, idx)"
            class="p-4 space-y-2 hover:bg-gray-50 transition-colors"
            :class="{ 'cursor-pointer': !!$attrs.onRowClick }"
          >
            <slot name="mobile-card" :row="row" :index="idx">
              <!-- Default mobile card layout -->
              <div
                v-for="col in columns.slice(0, 3)"
                :key="col.key"
                class="flex justify-between items-start"
              >
                <span class="text-xs font-medium text-gray-500 uppercase tracking-wide">
                  {{ col.label }}
                </span>
                <span class="text-sm text-gray-900 text-right">
                  <slot
                    :name="`cell-${col.key}`"
                    :row="row"
                    :column="col"
                    :value="row?.[col.key]"
                    :index="idx"
                  >
                    {{ row?.[col.key] ?? '—' }}
                  </slot>
                </span>
              </div>
              <div v-if="showActions || $slots.actions" class="pt-2 border-t border-gray-100">
                <slot name="actions" :row="row" :index="idx">
                  <slot name="row-actions" :row="row" :index="idx" />
                </slot>
              </div>
            </slot>
          </div>
        </template>
      </div>
    </div>

    <!-- Pagination -->
    <div v-if="showPagination && totalPages > 1">
      <!-- Use existing Pagination component for server-side -->
      <template v-if="isServerSide && meta?.links">
        <Pagination
          :links="meta.links"
          :from="from"
          :to="to"
          :total="total"
        />
      </template>

      <!-- Custom pagination for client-side -->
      <template v-else>
        <div class="flex flex-1 justify-between sm:hidden">
          <button
            @click="handlePageChange(currentPage - 1)"
            :disabled="currentPage <= 1"
            class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
          >
            Prejšnja
          </button>
          <button
            @click="handlePageChange(currentPage + 1)"
            :disabled="currentPage >= totalPages"
            class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
          >
            Naslednja
          </button>
        </div>

        <div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
          <div>
            <p class="text-sm text-gray-700">
              Prikazano
              <span class="font-medium">{{ from }}</span>
              do
              <span class="font-medium">{{ to }}</span>
              od
              <span class="font-medium">{{ total }}</span>
              rezultatov
            </p>
          </div>
          <div>
            <nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
              <button
                @click="handlePageChange(currentPage - 1)"
                :disabled="currentPage <= 1"
                class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed"
              >
                <span class="sr-only">Prejšnja</span>
                <FontAwesomeIcon :icon="faChevronLeft" class="h-5 w-5" />
              </button>

              <template v-for="page in getVisiblePages()" :key="page">
                <button
                  v-if="page !== '...'"
                  @click="handlePageChange(page)"
                  :aria-current="page === currentPage ? 'page' : undefined"
                  class="relative inline-flex items-center px-4 py-2 text-sm font-semibold focus:z-20"
                  :class="
                    page === currentPage
                      ? 'z-10 bg-primary-600 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600'
                      : 'text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:outline-offset-0'
                  "
                >
                  {{ page }}
                </button>
                <span
                  v-else
                  class="relative inline-flex items-center px-4 py-2 text-sm font-semibold text-gray-700 ring-1 ring-inset ring-gray-300"
                >
                  ...
                </span>
              </template>

              <button
                @click="handlePageChange(currentPage + 1)"
                :disabled="currentPage >= totalPages"
                class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed"
              >
                <span class="sr-only">Naslednja</span>
                <FontAwesomeIcon :icon="faChevronRight" class="h-5 w-5" />
              </button>
            </nav>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

