<!-- htmlhint doctype-first:false, tag-pair:false -->
<!-- Reusable Pagination Controls for Admin UI -->
<!--
  Usage:
    Set variables before including this template:
    - pagination: dict with page, per_page, total_items, total_pages, has_next, has_prev
    - base_url: string like '/admin/tools'
    - hx_target: string like '#tools-list'
    - hx_indicator: string like '#tools-loading'
    - table_name: string like 'tools' (for namespaced URL params)
    - query_params: optional dict of additional query parameters
-->

<div
  data-base-url="{{ base_url }}"
  x-data="{
  currentPage: {{ pagination.page }},
  perPage: {{ pagination.per_page }},
  totalItems: {{ pagination.total_items }},
  totalPages: {{ pagination.total_pages }},
  hasNext: {{ 'true' if pagination.has_next else 'false' }},
  hasPrev: {{ 'true' if pagination.has_prev else 'false' }},
  targetSelector: '{{ hx_target|default('#tools-table') }}',
  swapStyle: '{{ hx_swap|default('innerHTML') }}',
  tableName: '{{ table_name|default('') }}',
  baseUrl: '',

  // Initialize from data attributes and URL parameters (namespaced per table)
  init() {
    this.baseUrl = $el.dataset.baseUrl || '';
    if (!this.tableName) return;
    const urlParams = new URLSearchParams(window.location.search);
    const prefix = this.tableName + '_';
    const urlPageSize = parseInt(urlParams.get(prefix + 'size'), 10);
    if (urlPageSize && [10, 25, 50, 100, 200, 500].includes(urlPageSize)) {
      this.perPage = urlPageSize;
    }
  },

  // Navigate to specific page
  goToPage(page) {
    if (page >= 1 && page <= this.totalPages && page !== this.currentPage) {
      this.currentPage = page;
      this.loadPage(page);
    }
  },

  // Navigate to previous page
  prevPage() {
    if (this.hasPrev) {
      this.goToPage(this.currentPage - 1);
    }
  },

  // Navigate to next page
  nextPage() {
    if (this.hasNext) {
      this.goToPage(this.currentPage + 1);
    }
  },

  // Change page size
  changePageSize(size) {
    this.perPage = parseInt(size, 10);
    this.currentPage = 1;
    this.loadPage(1);
  },

  // Update browser URL with current pagination state (namespaced per table)
  // Preserves params from other tables to avoid mixing/overwriting
  updateBrowserUrl(page, includeInactive) {
    if (!this.tableName) return;
    const currentUrl = new URL(window.location.href);
    const newParams = new URLSearchParams(currentUrl.searchParams);
    const prefix = this.tableName + '_';

    // Update current table's params only
    newParams.set(prefix + 'page', page);
    newParams.set(prefix + 'size', this.perPage);
    if (includeInactive !== undefined) {
      newParams.set(prefix + 'inactive', includeInactive.toString());
    }

    const newUrl = currentUrl.pathname + '?' + newParams.toString() + currentUrl.hash;
    safeReplaceState({}, '', newUrl);
  },

  // Load page via HTMX
  loadPage(page) {
    const url = new URL(this.baseUrl, window.location.origin);
    url.searchParams.set('page', page);
    url.searchParams.set('per_page', this.perPage);

    // Dynamically get include_inactive from the checkbox if it exists
    // Map target selector to checkbox ID (handle special cases)
    // Examples: #servers-table -> show-inactive-servers
    //           #servers-table-body -> show-inactive-servers
    //           #resources-list-container -> show-inactive-resources
    //           #agents-table -> show-inactive-a2a-agents
    let checkboxId = this.targetSelector
      .replace('#', 'show-inactive-')
      .replace(/-table-body$/, '')
      .replace(/-table$/, '')
      .replace(/-list-container$/, '');
    if (checkboxId === 'show-inactive-agents') {
      checkboxId = 'show-inactive-a2a-agents';
    }
    const checkbox = document.getElementById(checkboxId);
    let includeInactive = undefined;
    if (checkbox) {
      includeInactive = checkbox.checked;
      url.searchParams.set('include_inactive', includeInactive.toString());
    }

    // Preserve other query parameters
    {% if query_params %}
    {% for key, value in query_params.items() %}
    {% if key != 'include_inactive' and value is not none %}
    url.searchParams.set({{ key | tojson }}, {{ value | tojson }});
    {% endif %}
    {% endfor %}
    {% endif %}

    // Preserve team_id from current URL (if present) - this ensures team filter
    // is maintained during pagination
    const currentUrlParams = new URLSearchParams(window.location.search);
    const teamIdFromUrl = currentUrlParams.get('team_id');
    if (teamIdFromUrl) {
      url.searchParams.set('team_id', teamIdFromUrl);
    }

    // Update browser URL for bookmarking/sharing (with namespaced params)
    this.updateBrowserUrl(page, includeInactive);

    // Scroll to the top of the table before loading new content
    const targetElement = document.querySelector(this.targetSelector);
    if (targetElement) {
      // Find the parent section/panel to scroll to
      const panel = targetElement.closest('.tab-panel, .bg-white, .shadow');
      if (panel) {
        panel.scrollIntoView({ behavior: 'smooth', block: 'start' });
      } else {
        targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
      }
    }

    // Trigger HTMX request - use innerHTML so we only replace tbody content (rows)
    // The OOB swap will handle the pagination controls separately
    htmx.ajax('GET', url.toString(), {
      target: this.targetSelector,
      swap: this.swapStyle,
      indicator: '{{ hx_indicator|default('#loading') }}'
    });
  }
}"
  class="flex flex-col sm:flex-row items-center justify-between gap-4 py-4 border-t border-gray-200 dark:border-gray-700"
>
  <!-- Page Size Selector -->
  <div class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300">
    <span>Show:</span>
    <select
      x-model="perPage"
      @change="changePageSize($event.target.value)"
      class="px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400"
    >
      <option value="10">10</option>
      <option value="25">25</option>
      <option value="50">50</option>
      <option value="100">100</option>
      <option value="200">200</option>
      <option value="500">500</option>
    </select>
    <span>per page</span>
  </div>

  <!-- Page Info -->
  <div class="text-sm text-gray-700 dark:text-gray-300">
    <span
      x-text="totalItems === 0 ? 'No items found' : `Showing ${Math.min((currentPage - 1) * perPage + 1, totalItems)} - ${Math.min(currentPage * perPage, totalItems)} of ${totalItems.toLocaleString()} items`"
    ></span>
  </div>

  <!-- Page Navigation (hidden when there are no pages) -->
  <template x-if="totalPages > 0">
    <div class="flex items-center gap-2">
      <!-- First Page Button -->
      <button
        @click="goToPage(1)"
        :disabled="!hasPrev"
        :class="hasPrev ? 'text-indigo-600 dark:text-indigo-400 hover:bg-indigo-50 dark:hover:bg-indigo-900/20' : 'text-gray-400 dark:text-gray-600 cursor-not-allowed'"
        class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 disabled:opacity-50 transition-colors"
        title="First Page"
      >
        ⏮️
      </button>

      <!-- Previous Page Button -->
      <button
        @click="prevPage()"
        :disabled="!hasPrev"
        :class="hasPrev ? 'text-indigo-600 dark:text-indigo-400 hover:bg-indigo-50 dark:hover:bg-indigo-900/20' : 'text-gray-400 dark:text-gray-600 cursor-not-allowed'"
        class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 disabled:opacity-50 transition-colors"
        title="Previous Page"
      >
        ◀️ Prev
      </button>

      <!-- Page Number Display -->
      <div class="flex items-center gap-1">
        <!-- Show first page if not near start -->
        <template x-if="currentPage > 3">
          <button
            @click="goToPage(1)"
            class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 text-gray-700 dark:text-gray-300"
          >
            1
          </button>
        </template>

        <!-- Ellipsis if needed -->
        <template x-if="currentPage > 4">
          <span class="px-2 text-gray-500 dark:text-gray-500">...</span>
        </template>

        <!-- Show 2 pages before current -->
        <template x-for="i in [currentPage - 2, currentPage - 1]" :key="i">
          <button
            x-show="i >= 1"
            @click="goToPage(i)"
            class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 text-gray-700 dark:text-gray-300"
            x-text="i"
          ></button>
        </template>

        <!-- Current Page (highlighted) -->
        <button
          class="px-3 py-1 rounded-md border-2 border-indigo-600 dark:border-indigo-400 bg-indigo-50 dark:bg-indigo-900/20 font-semibold text-indigo-700 dark:text-indigo-300"
          disabled
          x-text="currentPage"
        ></button>

        <!-- Show 2 pages after current -->
        <template x-for="i in [currentPage + 1, currentPage + 2]" :key="i">
          <button
            x-show="i <= totalPages"
            @click="goToPage(i)"
            class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 text-gray-700 dark:text-gray-300"
            x-text="i"
          ></button>
        </template>

        <!-- Ellipsis if needed -->
        <template x-if="currentPage < totalPages - 3">
          <span class="px-2 text-gray-500 dark:text-gray-500">...</span>
        </template>

        <!-- Show last page if not near end -->
        <template x-if="currentPage < totalPages - 2">
          <button
            @click="goToPage(totalPages)"
            class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 text-gray-700 dark:text-gray-300"
            x-text="totalPages"
          ></button>
        </template>
      </div>

      <!-- Next Page Button -->
      <button
        @click="nextPage()"
        :disabled="!hasNext"
        :class="hasNext ? 'text-indigo-600 dark:text-indigo-400 hover:bg-indigo-50 dark:hover:bg-indigo-900/20' : 'text-gray-400 dark:text-gray-600 cursor-not-allowed'"
        class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 disabled:opacity-50 transition-colors"
        title="Next Page"
      >
        Next ▶️
      </button>

      <!-- Last Page Button -->
      <button
        @click="goToPage(totalPages)"
        :disabled="!hasNext"
        :class="hasNext ? 'text-indigo-600 dark:text-indigo-400 hover:bg-indigo-50 dark:hover:bg-indigo-900/20' : 'text-gray-400 dark:text-gray-600 cursor-not-allowed'"
        class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 disabled:opacity-50 transition-colors"
        title="Last Page"
      >
        ⏭️
      </button>
    </div>
  </template>

  <!-- Keyboard Shortcuts Helper (Optional) -->
  <div class="hidden sm:block text-xs text-gray-500 dark:text-gray-500">
    <span class="inline-flex items-center gap-1">
      <kbd
        class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded"
        >←</kbd
      >
      <span>/</span>
      <kbd
        class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded"
        >→</kbd
      >
      <span>to navigate</span>
    </span>
  </div>
</div>

<!-- Keyboard Navigation Support -->
<script>
  document.addEventListener("alpine:init", () => {
    // Add keyboard shortcuts for pagination
    document.addEventListener("keydown", (e) => {
      // Only handle if not in an input field
      if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA")
        return;

      if (e.key === "ArrowLeft") {
        e.preventDefault();
        // Trigger previous page - the Alpine.js component will check hasPrev
        const prevBtn = document.querySelector('[\\@click="prevPage()"]');
        if (prevBtn && !prevBtn.disabled) prevBtn.click();
      } else if (e.key === "ArrowRight") {
        e.preventDefault();
        // Trigger next page - the Alpine.js component will check hasNext
        const nextBtn = document.querySelector('[\\@click="nextPage()"]');
        if (nextBtn && !nextBtn.disabled) nextBtn.click();
      }
    });
  });
</script>
