/**
 * Alpine.js Pagination Component
 *
 * Provides client-side pagination for large lists.
 */

document.addEventListener('alpine:init', () => {

  const basePagination = (
    items,
    currentPage,
    totalPages,
    totalItems,
    perPage,
    isReviewed,
    instanceId
  ) => ({
    items,
    currentPage,
    totalPages,
    totalItems,
    perPage,
    isReviewed,
    instanceId,

    get paginatedItems() {
      return this.items;
    },

    get showingStart() {
      if (this.totalItems === 0) return 0;
      return (this.currentPage - 1) * this.perPage + 1;
    },

    get showingEnd() {
      if (this.totalItems === 0) return 0;
      return Math.min((this.currentPage - 1) * this.perPage + this.items.length, this.totalItems);
    },

    nextPage() {
      if (this.currentPage < this.totalPages) {
        this.fetchPage(this.currentPage + 1);
      }
    },

    prevPage() {
      if (this.currentPage > 1) {
        this.fetchPage(this.currentPage - 1);
      }
    },

    goToPage(page) {
      if (page >= 1 && page <= this.totalPages) {
        this.fetchPage(page);
      }
    },

    get pageNumbers() {
      const pages = [];
      const total = this.totalPages;
      const current = this.currentPage;

      if (total === 0) {
        return pages;
      }

      if (total <= 7) {
        for (let i = 1; i <= total; i++) {
          pages.push({ page: i, isEllipsis: false, key: `${this.instanceId}-page-${i}` });
        }
      } else {
        pages.push({ page: 1, isEllipsis: false, key: `${this.instanceId}-page-1` });

        let rangeStart;
        let rangeEnd;

        if (current <= 4) {
          rangeStart = 2;
          rangeEnd = 5;
        } else if (current >= total - 3) {
          rangeStart = total - 4;
          rangeEnd = total - 1;
        } else {
          rangeStart = current - 1;
          rangeEnd = current + 1;
        }

        if (rangeStart > 2) {
          pages.push({ page: '...', isEllipsis: true, key: `${this.instanceId}-ellipsis-start` });
        }

        for (let i = rangeStart; i <= rangeEnd; i++) {
          pages.push({ page: i, isEllipsis: false, key: `${this.instanceId}-page-${i}` });
        }

        if (rangeEnd < total - 1) {
          pages.push({ page: '...', isEllipsis: true, key: `${this.instanceId}-ellipsis-end` });
        }

        pages.push({ page: total, isEllipsis: false, key: `${this.instanceId}-page-${total}` });
      }

      return pages;
    }
  });

  Alpine.data('paginatedList',
    (items, options = {}) => ({
      ...basePagination(items,1, 0, 0, options.perPage || 50, options.isReviewed || false, options.instanceId || Math.random().toString(36).substring(2, 9),),

      init() {
        this.fetchPage(1);
      },

      async fetchPage(page) {
        this.totalItems = this.items.length;
        this.totalPages = Math.ceil(this.items.length / this.perPage);
        this.currentPage = page

        const start = page * this.perPage - this.perPage;
        const end = page * this.perPage;
        return this.items.slice(start, end);
      }

    })
  );

  Alpine.data('remotePaginatedList', (options = {}) => ({
    items: [],
    currentPage: 1,
    totalPages: 0,
    totalItems: 0,
    perPage: options.perPage || 50,
    endpoint: options.endpoint || '',
    isReviewed: options.isReviewed || false,
    instanceId: options.instanceId || Math.random().toString(36).substring(2, 9),
    isLoading: false,
    error: null,

    init() {
      if (this.endpoint) {
        this.fetchPage(1);
      }
    },

    get paginatedItems() {
      return this.items;
    },

    get showingStart() {
      if (this.totalItems === 0) return 0;
      return (this.currentPage - 1) * this.perPage + 1;
    },

    get showingEnd() {
      if (this.totalItems === 0) return 0;
      return Math.min((this.currentPage - 1) * this.perPage + this.items.length, this.totalItems);
    },

    async fetchPage(page) {
      if (!this.endpoint) {
        return;
      }

      this.isLoading = true;
      this.error = null;
      this.$dispatch('loading-start');

      try {
        const url = new URL(this.endpoint, window.location.origin);
        // Preserve existing query parameters and add pagination params
        url.searchParams.set('page', page.toString());
        url.searchParams.set('page_size', this.perPage.toString());

        const response = await fetch(url.toString(), {
          headers: { Accept: 'application/json' },
          credentials: 'same-origin'
        });

        if (!response.ok) {
          throw new Error(`Failed to load ${this.endpoint} (status ${response.status})`);
        }

        const data = await response.json();
        this.items = data.items || [];
        this.totalItems = data.total_items || 0;
        this.totalPages = data.total_pages || 0;
        this.currentPage = data.page || page;
        this.perPage = data.page_size || this.perPage;

        // Dispatch event for parent components (e.g., tab count updates)
        this.$dispatch('items-loaded', { totalItems: this.totalItems });
      } catch (err) {
        console.error(err);
        this.error = `Unable to load ${this.endpoint}. Please try again.`;
      } finally {
        this.isLoading = false;
        this.$dispatch('loading-end');
      }
    },

    nextPage() {
      if (this.currentPage < this.totalPages) {
        this.fetchPage(this.currentPage + 1);
      }
    },

    prevPage() {
      if (this.currentPage > 1) {
        this.fetchPage(this.currentPage - 1);
      }
    },

    goToPage(page) {
      if (page >= 1 && page <= this.totalPages) {
        this.fetchPage(page);
      }
    },

    get pageNumbers() {
      const pages = [];
      const total = this.totalPages;
      const current = this.currentPage;

      if (total === 0) {
        return pages;
      }

      if (total <= 7) {
        for (let i = 1; i <= total; i++) {
          pages.push({ page: i, isEllipsis: false, key: `${this.instanceId}-page-${i}` });
        }
      } else {
        pages.push({ page: 1, isEllipsis: false, key: `${this.instanceId}-page-1` });

        let rangeStart;
        let rangeEnd;

        if (current <= 4) {
          rangeStart = 2;
          rangeEnd = 5;
        } else if (current >= total - 3) {
          rangeStart = total - 4;
          rangeEnd = total - 1;
        } else {
          rangeStart = current - 1;
          rangeEnd = current + 1;
        }

        if (rangeStart > 2) {
          pages.push({ page: '...', isEllipsis: true, key: `${this.instanceId}-ellipsis-start` });
        }

        for (let i = rangeStart; i <= rangeEnd; i++) {
          pages.push({ page: i, isEllipsis: false, key: `${this.instanceId}-page-${i}` });
        }

        if (rangeEnd < total - 1) {
          pages.push({ page: '...', isEllipsis: true, key: `${this.instanceId}-ellipsis-end` });
        }

        pages.push({ page: total, isEllipsis: false, key: `${this.instanceId}-page-${total}` });
      }

      return pages;
    }
  }));
});
