(function() {
  if (window.MindwecoPagination) return;

  class MindwecoPaginationComponent {
    /**
     * @param {object} options
     * @param {number} options.itemsPerPage
     * @param {number} options.scrollOffset
     * @param {number} options.scrollDuration
     * @param {string} options.scrollTarget
     */
    constructor(options = {}) {
      this.options = {
        itemsPerPage: 4,
        scrollOffset: 100,
        scrollDuration: 300,
        scrollTarget: null,
        ...options
      };
      this._instances = {};
    }

    _getOrCreateInstance(containerId) {
      if (!this._instances[containerId]) {
        this._instances[containerId] = {
          currentPage: 1,
          allItems: [],
          filteredItems: null,
          renderFn: null,
          containerId: containerId
        };
      }
      return this._instances[containerId];
    }

    init(containerId, items, renderFn, page = 1) {
      const instance = this._getOrCreateInstance(containerId);
      instance.allItems = items || [];
      instance.filteredItems = null;
      instance.renderFn = renderFn;
      instance.currentPage = page;
      this._render(instance);
    }

    filter(containerId, filteredItems) {
      const instance = this._getOrCreateInstance(containerId);
      instance.filteredItems = filteredItems;
      instance.currentPage = 1;
      this._render(instance);
    }

    clearFilter(containerId) {
      const instance = this._getOrCreateInstance(containerId);
      instance.filteredItems = null;
      instance.currentPage = 1;
      this._render(instance);
    }

    update(containerId, items) {
      const instance = this._getOrCreateInstance(containerId);
      if (!instance.renderFn) {
        return;
      }
      instance.allItems = items || [];
      instance.filteredItems = null;
      instance.currentPage = 1;
      this._render(instance);
    }

    append(containerId, newItems) {
      const instance = this._getOrCreateInstance(containerId);
      instance.allItems = [...instance.allItems, ...(newItems || [])];
      instance.filteredItems = null;
      this._render(instance);
    }

    remove(containerId, predicateFn) {
      const instance = this._getOrCreateInstance(containerId);
      if (!instance.renderFn) {
        return;
      }
      instance.allItems = instance.allItems.filter(item => !predicateFn(item));
      instance.filteredItems = null;
      const totalPages = this._getTotalPages(instance);
      if (instance.currentPage > totalPages && totalPages > 0) {
        instance.currentPage = totalPages;
      }
      this._render(instance);
    }

    goToPage(containerId, page) {
      const instance = this._getOrCreateInstance(containerId);
      const totalPages = this._getTotalPages(instance);
      if (page < 1 || page > totalPages) return;
      instance.currentPage = page;
      this._render(instance);
    }

    getState(containerId) {
      const instance = this._getOrCreateInstance(containerId);
      const items = instance.filteredItems ?? instance.allItems;
      return {
        currentPage: instance.currentPage,
        totalPages: this._getTotalPages(instance),
        totalItems: items.length,
        itemsPerPage: this.options.itemsPerPage
      };
    }

    destroy(containerId) {
      this._removePagination(containerId);
      delete this._instances[containerId];
    }

    initNested(containerId, items, renderFn, itemsPerPage = 4) {
      const instance = this._getOrCreateInstance(containerId);
      instance.allItems = items || [];
      instance.filteredItems = null;
      instance.renderFn = renderFn;
      instance.currentPage = 1;
      instance.itemsPerPage = itemsPerPage;
      instance.isNested = true;
      this._renderNested(instance);
    }

    _getTotalPagesNested(instance) {
      const items = this._getActiveItems(instance);
      const perPage = instance.itemsPerPage || this.options.itemsPerPage;
      return Math.max(1, Math.ceil(items.length / perPage));
    }

    _renderNested(instance) {
      const { containerId, currentPage, renderFn } = instance;
      const $container = jQuery('#' + containerId);
      if (!$container.length) return;
      const items = this._getActiveItems(instance);
      const perPage = instance.itemsPerPage || this.options.itemsPerPage;
      const totalPages = this._getTotalPagesNested(instance);
      const startIndex = (currentPage - 1) * perPage;
      const pageItems = items.slice(startIndex, startIndex + perPage);
      $container.find('.notebooks-grid-paginated').remove();
      $container.find('.nested-pagination').remove();
      const $grid = jQuery('<div class="notebooks-grid notebooks-grid-paginated"></div>');
      pageItems.forEach(item => renderFn(item, $grid));
      $container.prepend($grid);
      if (totalPages > 1) {
        this._renderNestedPagination(instance, containerId, currentPage, totalPages, items.length);
      }
    }

    _renderNestedPagination(instance, containerId, currentPage, totalPages, totalItems) {
      const perPage = instance.itemsPerPage || this.options.itemsPerPage;
      const from = (currentPage - 1) * perPage + 1;
      const to = Math.min(currentPage * perPage, totalItems);
      const $pag = jQuery(
        '<div class="nested-pagination d-flex align-items-center justify-content-between mt-2 pt-2 border-top">' +
          '<button class="btn btn-sm btn-outline-secondary nested-prev" ' + (currentPage === 1 ? 'disabled' : '') + '>' +
            '<i class="bi bi-chevron-left"></i>' +
          '</button>' +
          '<small class="text-muted">' +
            from + '-' + to + ' of ' + totalItems +
            ' <span class="badge bg-secondary ms-1">' + currentPage + '/' + totalPages + '</span>' +
          '</small>' +
          '<button class="btn btn-sm btn-outline-secondary nested-next" ' + (currentPage === totalPages ? 'disabled' : '') + '>' +
            '<i class="bi bi-chevron-right"></i>' +
          '</button>' +
        '</div>'
      );
      jQuery('#' + containerId).append($pag);
      $pag.find('.nested-prev').off('click').on('click', function(e) {
        e.stopPropagation();
        if (instance.currentPage <= 1) return;
        instance.currentPage--;
        this._renderNested(instance);
      }.bind(this));
      $pag.find('.nested-next').off('click').on('click', function(e) {
        e.stopPropagation();
        if (instance.currentPage >= totalPages) return;
        instance.currentPage++;
        this._renderNested(instance);
      }.bind(this));
    }

    _getActiveItems(instance) {
      return instance.filteredItems ?? instance.allItems;
    }

    _getTotalPages(instance) {
      const items = this._getActiveItems(instance);
      return Math.max(1, Math.ceil(items.length / this.options.itemsPerPage));
    }

    _render(instance) {
      const { containerId, currentPage, renderFn } = instance;
      const $container = jQuery('#' + containerId);
      if (!$container.length) return;
      const items = this._getActiveItems(instance);
      const totalPages = this._getTotalPages(instance);
      const perPage = this.options.itemsPerPage;
      const startIndex = (currentPage - 1) * perPage;
      const endIndex = Math.min(startIndex + perPage, items.length);
      const pageItems = items.slice(startIndex, endIndex);
      $container.empty();
      this._removePagination(containerId);

      if (items.length === 0) {
        $container.show().addClass('is-empty');  
        this._renderEmptyState($container, instance.filteredItems !== null);
        return;
      }

      $container.show().removeClass('is-empty');  
      pageItems.forEach(item => renderFn(item, $container));
      if (totalPages > 1) {
        this._renderPagination(containerId, currentPage, totalPages, items.length);
      }
    }

    _renderEmptyState($container, isFiltered) {
      const $wrapper = $container.parent(); 
      $wrapper.find('.mindweco-pagination-empty').remove();
      const emptyStateHtml = isFiltered
        ? '<div class="mindweco-pagination-empty text-center py-5">' +
            '<div class="empty-state-wrapper">' +
              '<div class="empty-state-circle">' +
                '<i class="bi bi-search inbox-icon-knowledge"></i>' +
              '</div>' +
              '<h5 class="fw-bold mb-3">No Results Found</h5>' +
              '<p class="text-muted mb-0">We could not find any items matching your search criteria.</p>' +
            '</div>' +
          '</div>'
        : '<div class="mindweco-pagination-empty text-center py-5">' +
            '<div class="empty-state-wrapper">' +
              '<div class="empty-state-circle">' +
                '<i class="bi bi-inbox inbox-icon-knowledge"></i>' +
              '</div>' +
              '<h5 class="fw-bold mb-3">Nothing Here Yet</h5>' +
              '<p class="text-muted mb-0">There are no items to display at the moment.</p>' +
            '</div>' +
          '</div>';
      $container.html(emptyStateHtml);  
    }

    _renderPagination(containerId, currentPage, totalPages, totalItems) {
      const paginationId = 'mindweco-pagination-' + containerId;
      const prevDisabled = currentPage === 1 ? 'disabled' : '';
      const nextDisabled = currentPage === totalPages ? 'disabled' : '';
      const html =
        '<div class="mindweco-pagination-controls d-flex justify-content-center align-items-center mt-4 gap-3"' +
            ' id="' + paginationId + '" data-container="' + containerId + '">' +
          '<button class="btn-pagination-nav ' + prevDisabled + '" ' + prevDisabled + '>' +
            '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">' +
              '<path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/>' +
            '</svg>' +
          '</button>' +
          '<div class="pagination-counter">' +
            '<span class="current-page">' + currentPage + '</span>' +
            '<span class="divider">/</span>' +
            '<span class="total-pages">' + totalPages + '</span>' +
          '</div>' +
          '<button class="btn-pagination-nav ' + nextDisabled + '" ' + nextDisabled + '>' +
            '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">' +
              '<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>' +
            '</svg>' +
          '</button>' +
        '</div>';
      jQuery('#' + containerId).after(html);
      this._attachPaginationEvents(containerId, paginationId);
    }

    _attachPaginationEvents(containerId, paginationId) {
      const $pagination = jQuery('#' + paginationId);
      const instance = this._instances[containerId];
      $pagination.find('.btn-pagination-nav').first().off('click').on('click', function() {
        if (instance.currentPage <= 1) return;
        instance.currentPage--;
        this._render(instance);
        this._scrollToContainer(containerId);
      }.bind(this));
      $pagination.find('.btn-pagination-nav').last().off('click').on('click', function() {
        const totalPages = this._getTotalPages(instance);
        if (instance.currentPage >= totalPages) return;
        instance.currentPage++;
        this._render(instance);
        this._scrollToContainer(containerId);
      }.bind(this));
    }

    _removePagination(containerId) {
      jQuery('#mindweco-pagination-' + containerId).remove();
    }

    _scrollToContainer(containerId) {
      const target = this.options.scrollTarget
        ? jQuery(this.options.scrollTarget)
        : jQuery('#' + containerId);
      if (!target.length) return;
      jQuery('html, body').animate({
        scrollTop: target.offset().top - this.options.scrollOffset
      }, this.options.scrollDuration);
    }
  }

  window.MindwecoPagination = new MindwecoPaginationComponent();
})();