jQuery(document).ready(function($) {

  const CONFIG = {
    ANIMATION_DELAY: 50,
    ANIMATION_DURATION: 300,
    TOAST_DURATION: 3000,
    CARDS_PER_PAGE: 6,
    NOTEBOOKS_PER_PAGE: 4,
  };

  const state = {
    allNotebooks: [],
    allPageCards: [],
    filteredPageCards: null,
    nestedPage: {},
    isSaving: false,
  };

  const el = {
    passwordIcon: document.getElementById('toggle-password-visibility'),
    passwordInput: document.getElementById('mindweco-password'),
    loginBtn: $('#mindweco-knowledge-repository-login-btn'),
    logoutBtn: $('#mindweco-knowledge-repository-sign-out'),
    notebooksGrid: $('.notebooks-grid'),
    selectAllCheckbox: $('#select-all-notebooks'),
    hideLoginRegisterSignIn: $('#login-btn-index_link'),
  };

  function setDisabledState() {
    state.isSaving = true;
    $('.toggle-all-notebooks').prop('disabled', true).css('opacity', '0.5');
    $('.page-notebook-checkbox').prop('disabled', true);
    el.selectAllCheckbox.prop('disabled', true);
  }

  function setEnabledState() {
    state.isSaving = false;
    $('.toggle-all-notebooks').prop('disabled', false).css('opacity', '');
    $('.page-notebook-checkbox').prop('disabled', false);
    el.selectAllCheckbox.prop('disabled', false);
  }


  init();

  function init() {
    window.MindwecoPagination.options.itemsPerPage = CONFIG.CARDS_PER_PAGE;
    window.MindwecoPagination.options.scrollOffset = 100;
    window.MindwecoPagination.options.scrollTarget = '#page-notebooks-cards-container';

    checkTokenAndToggleLoginBtn();
    checkLoginStatusAndLoadNotebooks();
    attachEventListeners();
    setupPasswordToggle();
    setupModalCleanup();
  }

  function attachEventListeners() {
    el.loginBtn.on('click', handleLogin);
    el.logoutBtn.on('click', handleLogout);
    el.selectAllCheckbox.on('change', handleSelectAllNotebooks);

    $('#knowledge-repository-tab').on('click', getNotebooks);
    $(document).on('click', '#get-notebooks', getNotebooks);
    $(document).on('click', '#add-page-based-notebook', handleAddPageBasedNotebook);
    $(document).on('input', '#search-input', handleModalSearch);

    $('#page-based-notebooks-tab, .mindweco-nav-tab[data-tab="page_based_notebooks"]')
      .on('click', function() {
        checkTokenAndToggleLoginBtn();
        setTimeout(loadSavedPageCards, 100);
      });
    $('.mindweco-nav-tab[data-tab="general"]').on('click', checkTokenAndToggleLoginBtn);

    $(document).on('change', '.page-notebook-checkbox', function() {
      if (state.isSaving) return;
      const $cb = $(this);
      const pageId = parseInt($cb.data('page-id'));
      const refId = parseInt($cb.data('notebook-ref'));
      handleNotebookCheckboxChange(pageId, refId, $cb.is(':checked'));
    });

    $(document).on('change', '.notebook-checkbox', function() {
      const $cb = $(this);
      $cb.closest('.notebook-card').toggleClass('checked', $cb.is(':checked'));
      updateSelectAllCheckbox();
    });

    $(document).on('click', '.nb-prev-page', function() {
      changeNestedPage(parseInt($(this).data('page-id')), -1);
    });
    $(document).on('click', '.nb-next-page', function() {
      changeNestedPage(parseInt($(this).data('page-id')), 1);
    });

    $(document).on('click', '.toggle-all-notebooks', function() {
      if (state.isSaving) return;
      handleToggleAll($(this), parseInt($(this).data('page-id')));
    });

    $(document).on('click', '.remove-page-card', function() {
      const pageId = parseInt($(this).data('page-id'));
      MindwecoModal.confirm(
        'Remove page',
        'Are you sure you want to remove this page and all its space links?',
        () => removeSinglePage(pageId),
        'Remove',
        'btn-danger'
      );
    });

    $(document).on('click', '#remove-all-page-notebooks', function() {
      MindwecoModal.confirm(
        'Delete all pages',
        'You are about to delete all pages. This action is permanent.',
        removeAllPages,
        'Delete all',
        'btn-danger'
      );
    });

    $('#search-input-page-notebooks').on('keyup', handlePageCardsSearch);

    $(document).on('click', '.notebooks-grid .notebook-card', handleNotebookCardClick);

    window.toggleNotebook = toggleNotebook;
    window.clearAllNotebooks = clearAllNotebooks;
  }

  function checkTokenAndToggleLoginBtn() {
    return ajax('mindweco_get_notebooks')
      .done(r => {
        const ok = r.success && r.data.notebooks?.length > 0;
        el.hideLoginRegisterSignIn.toggle(!ok);
        el.logoutBtn.toggleClass('d-none', !ok).toggleClass('d-block', ok);
      })
      .fail(() => {
        el.hideLoginRegisterSignIn.show();
        el.logoutBtn.addClass('d-none').removeClass('d-block');
      });
  }

  function handleLogin() {
    const $btn = el.loginBtn;
    const orig = $btn.text();
    const creds = {
      base_url: $('#mindweco-base-url').val(),
      username: $('#mindweco-username').val(),
      password: $('#mindweco-password').val(),
    };
    let err = false;
    if (!creds.username) {
      $('#mindweco-username').next('span').removeClass('d-none').text('* Username is required.');
      err = true;
    } else {
      $('#mindweco-username').next('span').addClass('d-none');
    }
    if (!creds.password || creds.password.length < 6) {
      $('#mindweco-password').parent().next('span').removeClass('d-none')
        .text('* Password must be at least 6 characters.');
      err = true;
    } else {
      $('#mindweco-password').parent().next('span').addClass('d-none');
    }
    if (err) return;

    el.hideLoginRegisterSignIn.hide();
    el.logoutBtn.removeClass('d-none').addClass('d-block');
    setBtnState($btn, true, 'Logging in...');

    ajax('mindweco_knowledge_repository_login', creds, 'POST')
      .done(r => {
        if (!r.success) {
          el.hideLoginRegisterSignIn.show();
          el.logoutBtn.addClass('d-none').removeClass('d-block');
          MindwecoToast.error('Login failed, try again!');
        } else {
          MindwecoToast.success(r.data?.message || 'Login successful');
          getNotebooks();
          $('.mindweco-nav-tab[data-tab="page_based_notebooks"]').click();
        }
      })
      .fail(() => {
        el.hideLoginRegisterSignIn.show();
        el.logoutBtn.addClass('d-none').removeClass('d-block');
        MindwecoToast.error('Login request failed.');
      })
      .always(() => setBtnState($btn, false, orig));
  }

  function handleLogout() {
    const $btn = el.logoutBtn;
    const orig = $btn.html();

    const creds = {
      base_url: $('#mindweco-base-url').val(),
      nonce: mindwecoPlugin.nonce
    };

    setBtnState($btn, true, 'Logging out...');

    el.notebooksGrid.empty();
    $('#page-notebooks-cards-container').empty();
    $('#mindweco-username').val('');
    $('#mindweco-password').val('');
    $('.empty-state-wrapper, .pagination-controls').remove();
    resetState();

    ajax('mindweco_knowledge_repository_logout', creds, 'POST')
      .done((r) => {
        const msg = r.data?.message || (r.success ? 'Logged out successfully' : 'Logout failed');
        MindwecoToast[r.success ? 'success' : 'error'](msg);

        if (r.success) {
          $btn.addClass('d-none');
          el.hideLoginRegisterSignIn.show();
        }
      })
      .fail(() => MindwecoToast.error('Logout request failed.'))
      .always(() => {
        setBtnState($btn, false, orig);
      });
  }

  function resetState() {
    state.allNotebooks = [];
    state.allPageCards = [];
    state.filteredPageCards = null;
    state.currentCardPage = 1;
    state.nestedPage = {};
  }

  function getSavedReferenceIds(savedData) {
    const ids = new Set();

    Object.keys(savedData || {}).forEach(pageId => {
      const pageData = savedData[pageId];
      const notebooks = Array.isArray(pageData?.notebooks) ? pageData.notebooks : [];

      notebooks.forEach(refId => {
        const parsed = parseInt(refId);
        if (!Number.isNaN(parsed)) {
          ids.add(parsed);
        }
      });
    });

    return ids;
  }

  function updateToggleAllButtonIcon(pageId) {
    const card = state.allPageCards.find(c => c.pageId === pageId);
    const $btn = $(`.toggle-all-notebooks[data-page-id="${pageId}"]`);

    if (!$btn.length || !card) {
      return;
    }

    const allSelected = state.allNotebooks.length > 0 &&
      card.savedNotebooks.length === state.allNotebooks.length;
    const iconClass = allSelected ? 'bi-square' : 'bi-check-square-fill';

    $btn.html(`<i class="bi ${iconClass} me-1"></i> Toggle All`);
  }

  function checkLoginStatusAndLoadNotebooks() {
    ajax('mindweco_get_notebooks')
      .done(r => {
        if (r.success && r.data.notebooks?.length > 0) {
          el.hideLoginRegisterSignIn.hide();
          el.logoutBtn.removeClass('d-none').addClass('d-block');
          getSavedReferenceIdsAndRender(r.data.notebooks);
        } else {
          el.hideLoginRegisterSignIn.show();
          el.logoutBtn.addClass('d-none').removeClass('d-block');
        }
      })
      .fail(() => {
        el.hideLoginRegisterSignIn.show();
        el.logoutBtn.addClass('d-none').removeClass('d-block');
      });
  }

  function getNotebooks() {
    ajax('mindweco_get_notebooks')
      .done(r => {
        if (r.success) {
          const nb = r.data.notebooks || [];
          nb.length ? getSavedReferenceIdsAndRender(nb) : showEmptyState('No spaces found.');
        } else {
          handleNotebookError(r.data?.message);
        }
      })
      .fail(() => handleNotebookError('Request failed. Please try again.'));
  }

  function handleAddPageBasedNotebook(e) {
    e.preventDefault();
    const modalEl = document.getElementById('pageBasedNotebookModal');
    if (!modalEl) return;
    new bootstrap.Modal(modalEl, {
      backdrop: 'static',
      keyboard: false
    }).show();
    loadPagesForSelection();
  }

  function getSavedReferenceIdsAndRender(notebooks) {
    state.allNotebooks = notebooks;

    ajax('mindweco_get_all_page_notebooks', {}, 'POST')
      .done(function(r) {
        const savedData = r.success ? (r.data || {}) : {};
        const savedReferenceIds = getSavedReferenceIds(savedData);

        el.notebooksGrid.empty();

        if (!notebooks.length) {
          showEmptyState('No spaces found.');
          return;
        }

        notebooks.forEach(function(nb) {
          const refId = parseInt(nb.referenceId);
          const notebookId = parseInt(nb.id);
          const checked = savedReferenceIds.has(refId);

          const $card = $(`
                    <div class="notebook-card ${ checked ? 'checked' : '' }"
                          id="notebook-wrapper-${ refId }">
                        <input type="checkbox"
                               class="notebook-checkbox"
                               value="${ refId }"
                               id="notebook-${ refId }"
                               data-notebook-ref="${ refId }"
                               data-notebook-id="${ notebookId }"
                               ${ checked ? 'checked' : '' }>
                        <div class="notebook-content">
                            <div class="notebook-text" title="${ escapeHtml( nb.title ) }">${ escapeHtml( nb.title ) }</div>
                            <div class="notebook-meta">
                                <span class="notebook-badge">ID: ${ notebookId }</span>
                                <span class="notebook-badge">Ref: ${ refId }</span>
                            </div>
                        </div>
                    </div>`);

          el.notebooksGrid.append($card);
        });

        updateSelectAllCheckbox();
      })
      .fail(function() {
        showEmptyState('Failed to load notebooks.');
      });
  }

  function loadPagesForSelection() {
    showModalLoading($('#pageBasedNotebookModal .modal-body'));

    $.when(
        ajax('mindweco_get_saved_page_based', {}, 'POST'),
        fetchAllPageNotebooks()
      )
      .done((pagesResp, savedData) => {
        const pd = pagesResp[0];
        const pages = pd.data || [];

        if (!pd.success || !pages.length) {
          showModalError('No published pages were found.');
          return;
        }
        const savedPageIds = Object.keys(savedData)
          .filter(id => {
            const item = savedData[id];
            return item?.notebooks && item.notebooks.length > 0;
          })
          .map(Number);

        renderPagesListForSelection(pages, savedPageIds);
      })
      .fail(() => showModalError('The request for pages failed.'));
  }

  function renderPagesListForSelection(pages, savedPageIds = []) {
    const $body = $('#pageBasedNotebookModal .modal-body');
    const $footer = $('#pageBasedNotebookModal .modal-footer');
    $body.empty();
    $footer.empty();

    $body.append(`
            <div class="d-flex justify-content-between align-items-center mb-3 p-2 bg-light rounded">
                <span class="badge bg-primary" id="selected-pages-count">0 selected</span>
            </div>
            <div class="pages-selection-list"></div>`);
    pages.forEach(p => $body.find('.pages-selection-list').append(createPageItem(p, savedPageIds)));

    $footer.append(`
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
                <i class="bi bi-x-lg me-1"></i> Close
            </button>
            <button type="button" class="btn btn-primary" id="add-selected-pages" disabled>
                <i class="bi bi-plus-lg me-1"></i> Add(<span id="add-count">0</span>)
            </button>`);

    attachPageSelectionHandlers();
    attachModalSearchHandlers();
    updateSearchResultsCount(pages.length, 0);
  }

  function createPageItem(page, savedPageIds) {
    const id = parseInt(page.id);
    const saved = savedPageIds.includes(id);
    return `
            <div class="page-selection-item page_based border rounded p-3 mb-2 ${saved ? 'already-added selected' : ''}"
                 data-page-id="${id}">
                <div class="form-check">
                    <input class="form-check-input page-checkbox" type="checkbox"
                           value="${id}" id="page-checkbox-${id}"
                           data-page-title="${escapeHtml(page.title)}"
                           ${saved ? 'checked disabled' : ''}>
                    <label class="form-check-label w-100 cursor-pointer" for="page-checkbox-${id}">
                        <div class="container-description-added-view d-flex justify-content-between align-items-center">
                            <div class="page-info flex-grow-1">
                                <div class="page-title fw-medium">
                                    <i class="bi bi-file-text me-2 text-primary"></i>
                                    ${escapeHtml(page.title)}
                                </div>
                                ${page.excerpt ? `<small class="text-muted d-block mt-1">${escapeHtml(page.excerpt)}</small>` : ''}
                            </div>
                            <div class="view-added-page text-end ms-2">
                                ${saved ? '<span class="badge bg-success mb-1">Added</span><br>' : ''}
                                <a href="${page.url}" target="_blank" class="btn btn-sm btn-outline-primary btn-fixed-width">
                                    <i class="bi bi-eye me-1"></i> View
                                </a>
                            </div>
                        </div>
                    </label>
                </div>
            </div>`;
  }

  function attachPageSelectionHandlers() {
    $('.page-checkbox').off('change').on('change', function() {
      $(this).closest('.page-selection-item').toggleClass('selected', $(this).is(':checked'));
      updateSelectedPagesCount();
      updateSelectAllCheckboxPages();
    });
    $('#select-all-pages').off('change').on('change', function() {
      $('.page-checkbox:not(:disabled)').prop('checked', $(this).is(':checked')).trigger('change');
    });
    $('#add-selected-pages').off('click').on('click', handleAddSelectedPages);
  }

  function updateSelectAllCheckboxPages() {
    const total = $('.page-checkbox:not(:disabled)').length;
    const checked = $('.page-checkbox:not(:disabled):checked').length;
    $('#select-all-pages')
      .prop('checked', checked === total && total > 0)
      .prop('indeterminate', checked > 0 && checked < total);
  }

  function updateSelectedPagesCount() {
    const c = $('.page-checkbox:not(:disabled):checked').length;
    $('#selected-pages-count').text(`${c} selected`);
    $('#add-count').text(c);
    $('#add-selected-pages').prop('disabled', c === 0);
  }

  function handleAddSelectedPages() {
    const $btn = $(this);
    const sel = collectSelectedPages();
    if (!sel.ids.length) {
      MindwecoToast.warning('No pages selected.');
      return;
    }
    const orig = $btn.html();
    setBtnState($btn, true, '<span class="spinner-border spinner-border-sm me-2"></span>Adding...');
    addMultiplePageCards(sel.ids, sel.titles, () => {
      closeModal('pageBasedNotebookModal');
      setBtnState($btn, false, orig);
    });
  }

  function collectSelectedPages() {
    const ids = [],
      titles = {};
    $('.page-checkbox:not(:disabled):checked').each(function() {
      const id = parseInt($(this).val());
      ids.push(id);
      titles[id] = $(this).data('page-title');
    });
    return {
      ids,
      titles
    };
  }

  function addMultiplePageCards(pageIds, pageTitles, callback) {
    $('.empty-state-wrapper').remove();
    ensurePageContainer();
    MindwecoToast.info(`Adding ${pageIds.length} pages...`);

    const nbPromise = state.allNotebooks.length ?
      Promise.resolve(state.allNotebooks) :
      fetchNotebooks();

    nbPromise
      .then(notebooks => {
        state.allNotebooks = notebooks;
        if (!state.allNotebooks.length) {
          MindwecoToast.warning('No spaces available. Please login first.');
          callback?.();
          return Promise.reject('no-notebooks');
        }

        pageIds.forEach(pageId => {
          if (!state.allPageCards.find(c => c.pageId === pageId)) {
            state.allPageCards.push({
              pageId,
              pageTitle: pageTitles[pageId],
              savedNotebooks: [],
              isPersisted: false
            });
            state.nestedPage[pageId] = 1;
          }
        });
        renderPaginatedCards();
        MindwecoToast.success(`Added ${pageIds.length} page(s) successfully`);
        callback?.();
      })
      .catch(err => {
        if (err !== 'no-notebooks') {
          MindwecoToast.error('Error adding pages');
        }
        callback?.();
      });
  }

  function handleNotebookCheckboxChange(pageId, refId, isChecked) {
    const card = state.allPageCards.find(c => c.pageId === pageId);
    if (!card) return;
    const set = new Set(card.savedNotebooks.map(Number));
    isChecked ? set.add(refId) : set.delete(refId);
    card.savedNotebooks = Array.from(set);

    $(`#notebook-wrapper-${pageId}-${refId}`).toggleClass('checked', isChecked);
    updateNotebookCounts(pageId, card.savedNotebooks.length);
    updateToggleAllButtonIcon(pageId);
    persistNotebooks(pageId, card.savedNotebooks, refId, isChecked);
  }

  function updateNotebookCounts(pageId, count) {
    $(`#count-${pageId}`).text(count);
    $(`#selected-summary-${pageId}`).text(count);
    const $badge = $(`#badge-${pageId}`);
    $badge.addClass('animate-pulse');
    setTimeout(() => $badge.removeClass('animate-pulse'), 500);
  }

  function persistNotebooks(pageId, checkedIds, refId, isChecked) {
    const postData = {
      page_id: pageId,
      notebook_ids: checkedIds
    };
    if (checkedIds.length === 0) postData.notebook_ids_empty = 1;

    setDisabledState();

    ajax('mindweco_save_page_notebooks', postData, 'POST')
      .done(r => {
        if (r.success) {
          const card = state.allPageCards.find(c => c.pageId === pageId);
          if (card) card.isPersisted = true;
          MindwecoToast.success('Spaces saved successfully');
        } else {
          revertCheckbox(pageId, refId, isChecked);
          MindwecoToast.error('Failed to save: ' + (r.data?.message || ''));
        }
      })
      .fail(() => {
        revertCheckbox(pageId, refId, isChecked);
        MindwecoToast.error('Request failed. Please try again.');
      })
      .always(() => setEnabledState());
  }

  function revertCheckbox(pageId, refId, wasChecked) {
    const card = state.allPageCards.find(c => c.pageId === pageId);
    if (card) {
      const set = new Set(card.savedNotebooks.map(Number));
      wasChecked ? set.delete(refId) : set.add(refId);
      card.savedNotebooks = Array.from(set);
      updateNotebookCounts(pageId, card.savedNotebooks.length);
      updateToggleAllButtonIcon(pageId);
    }
    $(`#notebook-${pageId}-${refId}`).prop('checked', !wasChecked);
    $(`#notebook-wrapper-${pageId}-${refId}`).toggleClass('checked', !wasChecked);
  }

  function handleToggleAll($btn, pageId) {
    const card = state.allPageCards.find(c => c.pageId === pageId);
    if (!card) {
      MindwecoToast.info('Card not found');
      return;
    }
    if (!state.allNotebooks.length) {
      MindwecoToast.info('No notebooks available to toggle');
      return;
    }

    const allRefIds = state.allNotebooks.map(nb => parseInt(nb.referenceId));
    const shouldCheckAll = card.savedNotebooks.length < state.allNotebooks.length;

    card.savedNotebooks = shouldCheckAll ? [...allRefIds] : [];

    $(`#notebooks-grid-${pageId} .page-notebook-checkbox`).each(function() {
      const refId = parseInt($(this).data('notebook-ref'));
      const checked = card.savedNotebooks.includes(refId);
      $(this).prop('checked', checked);
      $(`#notebook-wrapper-${pageId}-${refId}`).toggleClass('checked', checked);
    });
    updateNotebookCounts(pageId, card.savedNotebooks.length);
    updateToggleAllButtonIcon(pageId);

    const postData = {
      page_id: pageId,
      notebook_ids: card.savedNotebooks
    };
    if (card.savedNotebooks.length === 0) postData.notebook_ids_empty = 1;

    setDisabledState();

    ajax('mindweco_save_page_notebooks', postData, 'POST')
      .done(r => {
        if (r.success) {
          const card = state.allPageCards.find(c => c.pageId === pageId);
          if (card) card.isPersisted = true;
          MindwecoToast.success(shouldCheckAll ?
            `All ${state.allNotebooks.length} spaces selected` :
            'All spaces deselected');
        } else {
          MindwecoToast.error('Failed to save: ' + (r.data?.message || ''));
          loadSavedPageCards();
        }
      })
      .fail(() => {
        MindwecoToast.error('Request failed. Please try again.');
        loadSavedPageCards();
      })
      .always(() => setEnabledState());
  }

  function getNestedPage(pageId) {
    return state.nestedPage[pageId] || 1;
  }

  function changeNestedPage(pageId, direction) {
    const total = Math.ceil(state.allNotebooks.length / CONFIG.NOTEBOOKS_PER_PAGE);
    const next = getNestedPage(pageId) + direction;
    if (next < 1 || next > total) return;
    state.nestedPage[pageId] = next;
    renderNotebooksForCard(pageId);
  }

  function renderNotebooksForCard(pageId) {
    const $container = $(`#notebooks-container-${pageId}`);
    if (!$container.length) return;
    $container.empty();

    if (!state.allNotebooks.length) {
      $container.html(createEmptyNotebooksMessage());
      return;
    }

    const card = state.allPageCards.find(c => c.pageId === pageId);
    const savedSet = new Set((card ? card.savedNotebooks : []).map(Number));

    const currentNbPage = getNestedPage(pageId);
    const totalNbPages = Math.ceil(state.allNotebooks.length / CONFIG.NOTEBOOKS_PER_PAGE);
    const start = (currentNbPage - 1) * CONFIG.NOTEBOOKS_PER_PAGE;
    const visibleNbs = state.allNotebooks.slice(start, start + CONFIG.NOTEBOOKS_PER_PAGE);

    const $grid = $(`<div class="notebooks-grid-inner" id="notebooks-grid-${pageId}"></div>`);
    visibleNbs.forEach(nb => {
      const refId = parseInt(nb.referenceId);
      const notebookId = parseInt(nb.id);
      const checked = savedSet.has(refId);
      $grid.append(`
                <div class="notebook-card ${checked ? 'checked' : ''}"
                     id="notebook-wrapper-${pageId}-${refId}">
                    <input type="checkbox"
                           class="form-check-input page-notebook-checkbox"
                           data-page-id="${pageId}"
                           data-notebook-ref="${refId}"
                           data-notebook-id="${notebookId}"
                           value="${refId}"
                           id="notebook-${pageId}-${refId}"
                           ${checked ? 'checked' : ''}>
                    <div class="notebook-content">
                        <div class="notebook-text" title="${escapeHtml(nb.title)}">${escapeHtml(nb.title)}</div>
                        <div class="notebook-meta">
                            <span class="notebook-badge">ID: ${notebookId}</span>
                            <span class="notebook-badge">Ref: ${refId}</span>
                        </div>
                    </div>
                </div>`);
    });
    $container.append($grid);

    if (totalNbPages > 1) {
      $container.append(`
                <div class="d-flex justify-content-between align-items-center mt-2 nb-pagination">
                    <button class="btn btn-outline-secondary btn-sm nb-prev-page"
                            data-page-id="${pageId}"
                            ${currentNbPage === 1 ? 'disabled' : ''}>
                        <i class="bi bi-chevron-left"></i>
                    </button>
                    <small class="text-muted">${currentNbPage} / ${totalNbPages}</small>
                    <button class="btn btn-outline-secondary btn-sm nb-next-page"
                            data-page-id="${pageId}"
                            ${currentNbPage === totalNbPages ? 'disabled' : ''}>
                        <i class="bi bi-chevron-right"></i>
                    </button>
                </div>`);
    }

    $container.append(`
            <div class="mt-3 pt-3 border-top d-flex justify-content-between align-items-center">
                <small class="text-muted">
                    <i class="bi bi-list-check me-1"></i>
                    <strong id="selected-summary-${pageId}">${savedSet.size}</strong>
                    of ${state.allNotebooks.length} selected
                </small>
                <button class="btn btn-sm btn-outline-secondary toggle-all-notebooks"
                        data-page-id="${pageId}" type="button">
                    <i class="bi bi-check-square me-1"></i> Toggle All
                </button>
            </div>`);

    updateToggleAllButtonIcon(pageId);
  }

  function renderPageCard(pageId, pageTitle, savedNotebooks, $container) {
    if (!state.nestedPage[pageId]) state.nestedPage[pageId] = 1;
    const count = Array.isArray(savedNotebooks) ? savedNotebooks.length : 0;

    $container.append(`
            <div class="page-notebook-card" id="page-card-${pageId}" data-page-id="${pageId}">
                <div class="card shadow-sm h-100">
                    <div class="card-header d-flex justify-content-between align-items-center">
                        <strong class="flex-grow-1 text-truncate">
                            <i class="bi bi-file-text-fill me-2"></i>
                            <span title="${escapeHtml(pageTitle)}" class="header-title-notebook">
                                ${escapeHtml(pageTitle)}
                            </span>
                        </strong>
                        <div class="d-flex align-items-center gap-2">
                            <span class="badge count-badge-label" id="badge-${pageId}">
                                <span class="count-number" id="count-${pageId}" >${count}</span>
                                <span class="count-label"> spaces</span>
                            </span>
                            <button class="btn btn-sm remove-page-card"
                                    data-page-id="${pageId}" title="Remove this page">
                                <i class="bi bi-x-lg"></i>
                            </button>
                        </div>
                    </div>
                    <div class="card-body" id="card-body-${pageId}">
                        <div id="notebooks-container-${pageId}"></div>
                    </div>
                </div>
            </div>`);

    renderNotebooksForCard(pageId);
  }

  async function loadSavedPageCards() {
    const $c = ensurePageContainer();
    removeStateElements();
    showLoadingState($c);

    try {
      const [notebooks, pagesData] = await Promise.all([
        fetchNotebooks(),
        fetchAllPageNotebooks(),
      ]);
      state.allNotebooks = notebooks || [];
      $('.loading-state-wrapper').remove();
      $c.empty();
      $('.pagination-controls').remove();

      if (!pagesData || !Object.keys(pagesData).length) {
        $c.before(createEmptyStateHTML());
        state.allPageCards = [];
        state.nestedPage = {};
        state.filteredPageCards = null;
        return;
      }

      $('.empty-state-wrapper').remove();
      state.allPageCards = [];
      state.filteredPageCards = null;

      Object.keys(pagesData).forEach(rawId => {
        const pageId = parseInt(rawId);
        const notebooks = pagesData[rawId].notebooks || [];
        state.allPageCards.push({
          pageId,
          pageTitle: pagesData[rawId].title,
          savedNotebooks: notebooks,
        });
        if (!state.nestedPage[pageId]) state.nestedPage[pageId] = 1;
      });

      renderPaginatedCards();

    } catch (err) {
      $('.loading-state-wrapper').remove();
      ensurePageContainer().before(createErrorStateHTML());
      MindwecoToast.error('Error loading');
    }
  }

  function renderPaginatedCards() {
    const $c = $('#page-notebooks-cards-container');

    const source = state.filteredPageCards ?? state.allPageCards;

    if (!source.length) {
      checkAndShowEmptyState();
      return;
    }

    function renderCard(cardData, $container) {
      renderPageCard(
        cardData.pageId,
        cardData.pageTitle,
        cardData.savedNotebooks,
        $container
      );
    }

    if (state.filteredPageCards !== null) {
      window.MindwecoPagination.filter(
        'page-notebooks-cards-container',
        state.filteredPageCards
      );
    } else {
      window.MindwecoPagination.init(
        'page-notebooks-cards-container',
        state.allPageCards,
        renderCard,
        1
      );
    }
  }

  function removeSinglePage(pageId) {
    const $card = $(`#page-card-${pageId}`);
    const pageTitle = $card.find('.header-title-notebook').text();

    function removeFromState() {
      $card.fadeOut(CONFIG.ANIMATION_DURATION, function() {
        $(this).remove();
        state.allPageCards = state.allPageCards.filter(c => c.pageId !== pageId);
        state.filteredPageCards = state.filteredPageCards?.filter(c => c.pageId !== pageId) ?? null;
        delete state.nestedPage[pageId];

        if (!state.allPageCards.length) {
          $('.mindweco-pagination-controls').remove();
          $('#page-notebooks-cards-container').remove();
          checkAndShowEmptyState();
          return;
        }

        window.MindwecoPagination.update(
          'page-notebooks-cards-container',
          state.filteredPageCards ?? state.allPageCards
        );
      });
      MindwecoToast.success(`Page "${pageTitle}" removed successfully.`);
    }

    ajax('mindweco_remove_page_notebooks', {
        page_id: pageId
      }, 'POST')
      .done(r => {
        if (r.success) {
          removeFromState();
        } else {
          MindwecoToast.error(r.data?.message || 'Error while deleting');
        }
      })
      .fail(() => MindwecoToast.error('The request failed. Please try again.'));
  }

  function removeAllPages() {
    if (!state.allPageCards.length) {
      MindwecoToast.info('No pages to remove.');
      return;
    }

    ajax('mindweco_remove_all_page_notebooks', {}, 'POST')
      .done(r => {
        if (r.success) {
          const count = state.allPageCards.length;
          const names = state.allPageCards.map(c => c.pageTitle);

          resetState();

          $('.mindweco-pagination-controls').remove();

          const $cards = $('.page-notebook-card');
          const total = $cards.length;

          if (total === 0) {
            $('#page-notebooks-cards-container').empty();
            $('.empty-state-wrapper').remove();
            checkAndShowEmptyState();
            return;
          }

          let done = 0;
          $cards.fadeOut(CONFIG.ANIMATION_DURATION, function() {
            $(this).remove();
            done++;

            if (done === total) {
              $('#page-notebooks-cards-container').empty();
              $('.empty-state-wrapper').remove();
              checkAndShowEmptyState();
            }
          });

          MindwecoToast.success(
            count === 1 ?
            `Page "${names[0]}" removed.` :
            `${count} pages removed.`
          );
        } else {
          MindwecoToast.error(r.data?.message || 'Error while deleting');
        }
      })
      .fail(() => MindwecoToast.error('The request failed. Please try again.'));
  }

  function handleSelectAllNotebooks() {
    if (state.isSaving) return;
    const checked = $(this).is(':checked');

    $('.notebook-checkbox').each(function() {
      $(this).prop('checked', checked);
      $(this).closest('.notebook-card').toggleClass('checked', checked);
    });
    updateSelectAllCheckbox();

    const allRefIds = checked ? state.allNotebooks.map(nb => parseInt(nb.referenceId)) : [];
    state.allPageCards.forEach(card => {
      card.savedNotebooks = checked ? [...allRefIds] : [];
      updateToggleAllButtonIcon(card.pageId);
    });

    if (!state.allPageCards.length) return;

    const payload = {};
    state.allPageCards.forEach(card => {
      payload[card.pageId] = card.savedNotebooks;
    });

    setDisabledState();

    ajax('mindweco_save_all_page_notebooks', {
        pages_data: JSON.stringify(payload)
      }, 'POST')
      .done(r => {
        if (r.success) MindwecoToast.success('All spaces saved successfully');
        else MindwecoToast.error('Failed to save: ' + (r.data?.message || ''));
      })
      .fail(() => MindwecoToast.error('Request failed. Please try again.'))
      .always(() => setEnabledState());
  }

  function updateSelectAllCheckbox() {
    const total = $('.notebook-checkbox').length;
    const checked = $('.notebook-checkbox:checked').length;
    el.selectAllCheckbox
      .prop('checked', total > 0 && checked === total)
      .prop('indeterminate', checked > 0 && checked < total);
  }

  function toggleNotebook(card, event) {
    const cb = card.querySelector('input[type="checkbox"]');
    if (event?.target.tagName === 'INPUT') {
      card.classList.toggle('checked', cb.checked);
      return;
    }
    cb.checked = !cb.checked;
    card.classList.toggle('checked', cb.checked);
    $(cb).trigger('change');
  }

  function clearAllNotebooks() {
    const checked = $('.notebook-checkbox:checked');
    if (!checked.length) {
      MindwecoToast.info('No notebooks are selected.');
      return;
    }
    el.selectAllCheckbox.prop('checked', false).trigger('change');
    MindwecoToast.success(`Cleared ${checked.length} space(s)`);
  }

  function ajax(action, data = {}, method = 'GET') {
    const params = {
      action,
      nonce: mindwecoDataKnowledgeRepository.nonce,
      ...data
    };
    const url = mindwecoDataKnowledgeRepository.ajax_url;
    return method.toUpperCase() === 'POST' ? $.post(url, params) : $.get(url, params);
  }

  function fetchNotebooks() {
    return new Promise((res, rej) =>
      ajax('mindweco_get_notebooks')
      .done(r => res(r.success ? (r.data.notebooks || []) : []))
      .fail(rej));
  }

  function fetchAllPageNotebooks() {
    return new Promise((res, rej) =>
      ajax('mindweco_get_all_page_notebooks', {}, 'POST')
      .done(r => res(r.success ? (r.data || {}) : {}))
      .fail(rej));
  }

  function ensurePageContainer() {
    let $c = $('#page-notebooks-cards-container');
    if (!$c.length) {
      $('#add-page-based-notebook').parent()
        .after('<div id="page-notebooks-cards-container" class="mt-4"></div>');
      $c = $('#page-notebooks-cards-container');
    }
    return $c;
  }

  function removeStateElements() {
    $('.empty-state-wrapper, .loading-state-wrapper, .error-state-wrapper').remove();
  }

  function checkAndShowEmptyState() {
    if (!state.allPageCards.length && !$('.empty-state-wrapper').length) {
      $('.mindweco-pagination-controls').remove();
      $('#add-page-based-notebook').closest('.d-flex').after(createEmptyStateHTML());
    }
  }

  function showLoadingState($container) {
    $container.before(`
            <div class="d-flex flex-column justify-content-center align-items-center text-center py-5 loading-state-wrapper">
                <div class="spinner-border text-primary" role="status">
                    <span class="visually-hidden">Loading...</span>
                </div>
                <p class="mt-3 text-muted">Loading data...</p>
            </div>`);
  }

  function showEmptyState(msg) {
    el.notebooksGrid.empty();
    var p = document.createElement('p');
    p.style.cssText = 'grid-column:1/-1;text-align:center;padding:2rem;color:#6b7280;';
    p.textContent = msg;
    el.notebooksGrid.append(p);
  }

  function showModalLoading($body) {
    $body.html(`
            <div class="d-flex justify-content-center align-items-center py-5">
                <div class="spinner-border text-primary" role="status">
                    <span class="visually-hidden">Loading...</span>
                </div>
                <span class="ms-3 text-muted">Loading pages...</span>
            </div>`);
  }

  function showModalError(msg) {
    var $body = $('#pageBasedNotebookModal .modal-body');
    $body.empty();
    var div = document.createElement('div');
    div.className = 'alert alert-danger text-center';
    div.setAttribute('role', 'alert');
    var icon = document.createElement('i');
    icon.className = 'bi bi-exclamation-triangle me-2';
    div.appendChild(icon);
    div.appendChild(document.createTextNode(msg));
    $body.append(div);
  }

  function handleNotebookError(msg) {
    el.notebooksGrid.html(`
            <p  class="mindweco-login-space-view-warn">
                ⚠️ You must be logged in to view your spaces.
            </p>`);
    MindwecoToast.error('Error: You should be logged in to view spaces.');
    const $btn = $(`
            <div class="d-flex justify-content-start align-items-center mt-3">
                <a href="#" class="go-login-link">
                    <i class="fa-solid fa-arrow-left"></i><span>Go login first!</span>
                </a>
            </div>`);
    $btn.on('click', e => {
      e.preventDefault();
      $('.mindweco-nav-tab[data-tab="general"]').click();
    });
    el.notebooksGrid.append($btn);
  }

  function createEmptyStateHTML() {
    return `
            <div class="text-center py-5 empty-state-wrapper" >
                <div class="empty-state-circle">
                    <i class="bi bi-inbox inbox-icon-knowledge"></i>
                </div>
                <h4 class="fw-semibold text-info">No Pages Yet</h4>
                <p class="text-muted text-center empty-state-text">
                    You haven't added any pages yet.<br>
                    Click the button above to start adding pages to your space collection.
                </p>
            </div>`;
  }

  function createEmptyNotebooksMessage() {
    return `
            <div class="text-center py-4">
                <i class="bi bi-inbox text-muted fs-2"></i>
                <p class="text-muted mt-2 mb-0">No spaces available.</p>
                <small class="text-muted">Please login to load spaces.</small>
            </div>`;
  }

  function createErrorStateHTML() {
    return `
            <div class="alert alert-danger error-state-wrapper">
                <i class="bi bi-exclamation-triangle me-2"></i>
                Error loading data. Please try again.
            </div>`;
  }

  function setBtnState($btn, disabled, content) {
    $btn.prop('disabled', disabled);
    if (typeof content === 'string') {
      $btn.html(content);
    }
  }

  function closeModal(id) {
    const m = bootstrap.Modal.getInstance(document.getElementById(id));
    if (m) m.hide();
  }

  function setupModalCleanup() {
    $('#pageBasedNotebookModal').on('hidden.bs.modal', function() {
      $('#search-input').val('');
      $('#clear-search').hide();
      $('.page-selection-item').show();
    });
  }

  function escapeHtml(t) {
    if (!t) return '';
    return t.replace(/[&<>"']/g,
      m => ({
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
      } [m]));
  }

  function setupPasswordToggle() {
    const passwordInput = document.getElementById('mindweco-password');
    const passwordIcon = document.getElementById('toggle-password-visibility');

    if (!passwordInput || !passwordIcon) return;

    passwordInput.type = 'password';
    passwordIcon.classList.add('bi-eye-fill');
    passwordIcon.classList.remove('bi-eye-slash-fill');

    $(document).off('click.passwordToggle').on('click.passwordToggle', '#toggle-password-visibility', function() {
      const isPassword = passwordInput.type === 'password';
      passwordInput.type = isPassword ? 'text' : 'password';
      passwordIcon.classList.toggle('bi-eye-fill', !isPassword);
      passwordIcon.classList.toggle('bi-eye-slash-fill', isPassword);
    });
  }

  function attachModalSearchHandlers() {
    let t;
    $('#search-input').off('input keypress')
      .on('input', () => {
        clearTimeout(t);
        t = setTimeout(handleModalSearch, 300);
      })
      .on('keypress', e => {
        if (e.which === 13) {
          e.preventDefault();
          clearTimeout(t);
          handleModalSearch();
        }
      });
  }

  function handleModalSearch() {
    const q = $('#search-input').val()?.trim().toLowerCase() || '';
    let vis = 0,
      hid = 0;
    if (!q) {
      $('.page-selection-item').show();
      vis = $('.page-selection-item').length;
    } else {
      $('.page-selection-item').each(function() {
        const $i = $(this);
        const ok = $i.find('.page-title').text().toLowerCase().includes(q) ||
          $i.find('.text-muted').text().toLowerCase().includes(q) ||
          String($i.data('page-id')).includes(q);
        $i.toggle(ok);
        ok ? vis++ : hid++;
      });
    }
    updateSearchResultsCount(vis, hid);
  }

  function updateSearchResultsCount(vis, hid) {
    var total = vis + hid;
    var $ind = $('#search-results-indicator');
    if (!$ind.length) {
      var indDiv = document.createElement('div');
      indDiv.id = 'search-results-indicator';
      indDiv.className = 'mb-2 small';
      $('#pageBasedNotebookModal .modal-body').prepend(indDiv);
      $ind = $('#search-results-indicator');
    }
    $ind.empty();

    var $span = $(document.createElement('span'));
    var $icon = $(document.createElement('i'));

    if (vis === 0 && hid > 0) {
      $span.addClass('text-warning');
      $icon.addClass('bi bi-exclamation-circle me-1');
      $span.append($icon);
      $span.append(document.createTextNode(
        'No results (' + total + ' total)'
      ));
    } else if (hid > 0) {
      $span.addClass('text-info');
      $icon.addClass('bi bi-funnel me-1');
      $span.append($icon);
      $span.append(document.createTextNode(
        'Showing ' + vis + ' of ' + total
      ));
    } else {
      $span.addClass('text-muted');
      $icon.addClass('bi bi-list-ul me-1');
      $span.append($icon);
      $span.append(document.createTextNode(total + ' pages'));
    }
    $ind.append($span);
  }

  function handlePageCardsSearch() {
    const q = $(this).val().toLowerCase().trim();
    const $container = $('#page-notebooks-cards-container');

    $('.empty-state-wrapper').remove();

    if (q) {
      const filtered = state.allPageCards.filter(c =>
        c.pageTitle.toLowerCase().includes(q)
      );

      state.filteredPageCards = filtered;

      if (!filtered.length) {
        $container.empty().before(`
          <div class="empty-state-wrapper d-flex flex-column align-items-center justify-content-center text-center py-5">
            <div class="mb-3">
              <i class="bi bi-search display-5 text-secondary"></i>
            </div>
            <h5 class="fw-semibold mb-1">No results found</h5>
            <p class="text-muted mb-0">
              Try adjusting your search or keywords.
            </p>
          </div>
        `);
        return;
      }

      window.MindwecoPagination.filter(
        'page-notebooks-cards-container',
        filtered
      );

    } else {
      state.filteredPageCards = null;
      $('.empty-state-wrapper').remove();
      window.MindwecoPagination.clearFilter('page-notebooks-cards-container');
    }
  }

  function handleNotebookCardClick(e) {
    if ($(e.target).is('input[type="checkbox"], a, button, i')) return;
    const $card = $(this);
    const $cb = $card.find('input[type="checkbox"]');
    $cb.prop('checked', !$cb.prop('checked'));
    $card.toggleClass('checked', $cb.prop('checked'));
    $cb.trigger('change');
  }

  $('#mindweco-login-form').on('submit', function(e) {
    e.preventDefault();
  });

  if ($('#tab-page_based_notebooks').is(':visible')) loadSavedPageCards();
});
