import { AppState } from "./appState.js";
import { initializeCACertUpload } from "./caCertificate.js";
import { overflowMenu } from "./components/overflow-menu.js";
import { TABLE_TO_ENTITY_TYPE } from "./constants.js";
import { initializeEventDelegation } from "./eventDelegation.js";
import { toggleViewPublic, updateFilterStatus } from "./filters.js";
import { selectTeamFromSelector } from "./formFieldHandlers.js";
import { setupFormValidation } from "./formValidation.js";
import { initGatewaySelect } from "./gateways.js";
import {
  initializeCodeMirrorEditors,
  initializeEventListeners,
  initializeExportImport,
  initializeGlobalSearch,
  initializeSearchInputs,
  initializeTabState,
  initializeToolSelects,
  registerReloadAllResourceSections,
  setupBulkImportModal,
  setupTooltipsWithAlpine,
} from "./initialization.js";
import { llmModelComboboxSelect } from "./llmModels.js";
import { closeModal } from "./modals.js";
import { initializeRealTimeMonitoring } from "./monitoring.js";
import { ensureAddStoreListeners } from "./servers.js";
import { initializeTagFiltering, updateAvailableTags } from "./tags.js";
import {
  hideTeamEditModal,
  initializeAddMembersForms,
  initializePasswordValidation,
  updateDefaultVisibility,
} from "./teams.js";
import { initializeTeamScopingMonitor } from "./tokens.js";
import {
  cleanupToolTestState,
  editTool,
  enrichTool,
  generateToolTestCases,
  loadTools,
  validateTool,
  viewTool,
} from "./tools.js";
import {
  hideUserEditModal,
  performUserSearch,
  registerAdminActionListeners,
} from "./users.js";
import {
  createMemoizedInit,
  safeGetElement,
  showErrorMessage,
  showSuccessMessage,
  updateEditToolUrl,
} from "./utils.js";

((Admin) => {
  // ===================================================================
  // Initialization
  // ===================================================================

  // Initialise 3rd Party and setup Context Forge
  document.addEventListener("DOMContentLoaded", () => {
    console.log("🔐 DOM loaded - initializing secure admin interface...");

    /* ---------------------------------------------------------------------------
    Robust reloadAllResourceSections
    - Replaces each section's full innerHTML with a server-rendered partial
    - Restores saved initial markup on failure
    - Re-runs initializers (Alpine, CodeMirror, select/pills, event handlers)
    --------------------------------------------------------------------------- */

    try {
      // 0. Initialize event delegation system for CSP compliance
      initializeEventDelegation();

      // 1. Initialize Alpine tooltips
      setupTooltipsWithAlpine();

      // 2. Initialize CodeMirror editors first
      initializeCodeMirrorEditors();

      // 3. Reload all resource panels data
      registerReloadAllResourceSections();

      // 4. Initialize tool selects
      initializeToolSelects();
      ensureAddStoreListeners();

      // 5. Set up all event listeners
      initializeEventListeners();

      // 6. Handle initial tab/state
      initializeTabState();

      // 7. Set up form validation
      setupFormValidation();

      // 8. Setup bulk import modal
      try {
        setupBulkImportModal();
      } catch (error) {
        console.error("Error setting up bulk import modal:", error);
      }

      // 9. Initialize export/import functionality
      try {
        initializeExportImport();
      } catch (error) {
        console.error("Error setting up export/import functionality:", error);
      }

      // // ✅ 4.1 Set up tab button click handlers
      // document.querySelectorAll('.tab-button').forEach(button => {
      //     button.addEventListener('click', () => {
      //         const tabId = button.getAttribute('data-tab');

      //         document.querySelectorAll('.tab-panel').forEach(panel => {
      //             panel.classList.add('hidden');
      //         });

      //         safeGetElement(tabId).classList.remove('hidden');
      //     });
      // });

      // Mark as initialized
      AppState.isInitialized = true;

      console.log("✅ Secure initialization complete - XSS protection active");
    } catch (error) {
      console.error("❌ Initialization failed:", error);
      showErrorMessage(
        "Failed to initialize the application. Please refresh the page."
      );
    }
  });

  // Executes MCP tools via SSE streaming. Streams results to UI textarea.
  document.addEventListener("DOMContentLoaded", () => {
    // Use #tool-ops-main-content-wrapper as the event delegation target because
    // #toolBody gets replaced by HTMX swaps. The wrapper survives swaps.
    const toolOpsWrapper = safeGetElement("tool-ops-main-content-wrapper");
    const selectedList = safeGetElement("selectedList");
    const selectedCount = safeGetElement("selectedCount");
    const searchBox = safeGetElement("searchBox");

    let selectedTools = [];
    let selectedToolIds = [];

    const updateSelectedList = function () {
      selectedList.innerHTML = "";
      if (selectedTools.length === 0) {
        selectedList.textContent = "No tools selected";
      } else {
        selectedTools.forEach((tool) => {
          const item = document.createElement("div");
          item.className =
            "flex items-center justify-between bg-indigo-100 text-indigo-800 px-3 py-1 rounded-md";
          item.innerHTML = `
              <span>${tool}</span>
              <button class="text-indigo-500 hover:text-indigo-700 font-bold remove-btn">&times;</button>
          `;
          item.querySelector(".remove-btn").addEventListener("click", () => {
            selectedTools = selectedTools.filter((t) => t !== tool);
            const box = document.querySelector(`
                .tool-checkbox[data-tool="${tool}"]`);
            if (box) {
              box.checked = false;
            }
            updateSelectedList();
          });
          selectedList.appendChild(item);
        });
      }
      selectedCount.textContent = selectedTools.length;
    };

    if (toolOpsWrapper !== null) {
      // ✅ Use event delegation on wrapper (survives HTMX swaps)
      toolOpsWrapper.addEventListener("change", (event) => {
        const cb = event.target;
        if (cb.classList.contains("tool-checkbox")) {
          const toolName = cb.getAttribute("data-tool");
          if (cb.checked) {
            if (!selectedTools.includes(toolName)) {
              selectedTools.push(toolName.split("###")[0]);
              selectedToolIds.push(toolName.split("###")[1]);
            }
          } else {
            selectedTools = selectedTools.filter(
              (t) => t !== toolName.split("###")[0]
            );
            selectedToolIds = selectedToolIds.filter(
              (t) => t !== toolName.split("###")[1]
            );
          }
          updateSelectedList();
        }
      });
    }

    // --- Search logic ---
    if (searchBox !== null) {
      searchBox.addEventListener("input", () => {
        const query = searchBox.value.trim().toLowerCase();
        // Search within #toolBody (which is inside #tool-ops-main-content-wrapper)
        document
          .querySelectorAll("#tool-ops-main-content-wrapper #toolBody tr")
          .forEach((row) => {
            const name = row.dataset.name;
            row.style.display = name && name.includes(query) ? "" : "none";
          });
      });
    }

    // Generic API call for Enrich/Validate
    const callEnrichment = async function () {
      if (selectedTools.length === 0) {
        showErrorMessage("⚠️ Please select at least one tool.");
        return;
      }
      try {
        console.log(selectedToolIds);
        selectedToolIds.forEach((toolId) => {
          console.log(toolId);
          fetch(`/toolops/enrichment/enrich_tool?tool_id=${toolId}`, {
            method: "POST",
            headers: {
              "Cache-Control": "no-cache",
              Pragma: "no-cache",
              "Content-Type": "application/json",
            },
            body: JSON.stringify({ tool_id: toolId }),
          });
        });
        showSuccessMessage("Tool description enrichment has started.");
        // Uncheck all checkboxes
        document.querySelectorAll(".tool-checkbox").forEach((cb) => {
          cb.checked = false;
        });

        // Empty the selected tools array
        selectedTools = [];
        selectedToolIds = [];

        // Update the selected tools list UI
        updateSelectedList();
      } catch (err) {
        //   responseDiv.textContent = `❌ Error: ${err.message}`;
        showErrorMessage(`❌ Error: ${err.message}`);
      }
    };

    const generateBulkTestCases = async function () {
      const testCases = parseInt(
        safeGetElement("gen-bulk-testcase-count").value
      );
      const variations = parseInt(
        safeGetElement("gen-bulk-nl-variation-count").value
      );

      if (!testCases || !variations || testCases < 1 || variations < 1) {
        showErrorMessage(
          "⚠️ Please enter valid numbers for test cases and variations."
        );
        return;
      }

      try {
        for (const toolId of selectedToolIds) {
          fetch(
            `/toolops/validation/generate_testcases?tool_id=${toolId}&number_of_test_cases=${testCases}&number_of_nl_variations=${variations}&mode=generate`,
            {
              method: "POST",
              headers: {
                "Cache-Control": "no-cache",
                Pragma: "no-cache",
                "Content-Type": "application/json",
              },
              body: JSON.stringify({ tool_id: toolId }),
            }
          );
        }
        showSuccessMessage(
          "Test case generation for tool validation has started."
        );
        // Reset selections
        document.querySelectorAll(".tool-checkbox").forEach((cb) => {
          cb.checked = false;
        });
        selectedTools = [];
        selectedToolIds = [];
        updateSelectedList();

        // Close modal immediately after clicking Generate
        closeModal("bulk-testcase-gen-modal");
      } catch (err) {
        showErrorMessage(`❌ Error: ${err.message}`);
      }
    };
    Admin.generateBulkTestCases = generateBulkTestCases;

    const openTestCaseModal = function () {
      if (selectedToolIds.length === 0) {
        showErrorMessage("⚠️ Please select at least one tool.");
        return;
      }

      // Show modal
      document
        .getElementById("bulk-testcase-gen-modal")
        .classList.remove("hidden");
      document
        .getElementById("bulk-generate-btn")
        .addEventListener("click", generateBulkTestCases);
    };

    const clearAllSelections = function () {
      // Uncheck all checkboxes
      document.querySelectorAll(".tool-checkbox").forEach((cb) => {
        cb.checked = false;
      });

      // Empty the selected tools array
      selectedTools = [];
      selectedToolIds = [];

      // Update the selected tools list UI
      updateSelectedList();
    };
    // Button listeners
    const enrichToolsBtn = safeGetElement("enrichToolsBtn");

    if (enrichToolsBtn !== null) {
      document
        .getElementById("enrichToolsBtn")
        .addEventListener("click", () => callEnrichment());
      document
        .getElementById("validateToolsBtn")
        .addEventListener("click", () => openTestCaseModal());
      document
        .getElementById("clearToolsBtn")
        .addEventListener("click", () => clearAllSelections());
    }
  });

  // Prevent manual REST→MCP changes in edit-tool-form
  document.addEventListener("DOMContentLoaded", function () {
    const editToolTypeSelect = safeGetElement("edit-tool-type");
    if (editToolTypeSelect) {
      // Store the initial value for comparison
      editToolTypeSelect.dataset.prevValue = editToolTypeSelect.value;

      editToolTypeSelect.addEventListener("change", function (e) {
        const prevType = this.dataset.prevValue;
        const selectedType = this.value;
        if (prevType === "REST" && selectedType === "MCP") {
          alert("You cannot change integration type from REST to MCP.");
          this.value = prevType;
          // Optionally, reset any dependent fields here
        } else {
          this.dataset.prevValue = selectedType;
        }
      });
    }
  });

  // Initialize gateway select on page load
  document.addEventListener("DOMContentLoaded", function () {
    // Initialize for the create server form
    if (safeGetElement("associatedGateways")) {
      initGatewaySelect(
        "associatedGateways",
        "selectedGatewayPills",
        "selectedGatewayWarning",
        12,
        "selectAllGatewayBtn",
        "clearAllGatewayBtn",
        "searchGateways"
      );
    }
  });

  document.addEventListener("DOMContentLoaded", loadTools);

  // Event delegation for team selector items.
  // Inline onclick attributes are stripped by the innerHTML sanitizer guard,
  // so we use a delegated click listener on the container instead.
  document.addEventListener("DOMContentLoaded", function () {
    const container = document.getElementById("team-selector-items");
    if (container) {
      container.addEventListener("click", function (event) {
        const button = event.target.closest(".team-selector-item");
        if (button) {
          selectTeamFromSelector(button);
        }
      });
    }
  });

  // Event delegation for tool table action buttons (inline onclick stripped by innerHTML sanitizer).
  // Bind to #tool-ops-main-content-wrapper (exists in admin.html at DOMContentLoaded) rather than
  // #toolBody (injected later via HTMX partial) so the listener survives HTMX content swaps.
  document.addEventListener("DOMContentLoaded", function () {
    const wrapper =
      document.getElementById("tool-ops-main-content-wrapper") ||
      document.getElementById("toolBody");
    if (wrapper) {
      wrapper.addEventListener("click", function (e) {
        const btn = e.target.closest("[data-action]");
        if (!btn) return;
        const toolId = btn.dataset.toolId;
        if (!toolId) return;
        switch (btn.dataset.action) {
          case "enrich-tool":
            enrichTool(toolId);
            break;
          case "generate-tool-tests":
            generateToolTestCases(toolId);
            break;
          case "validate-tool":
            validateTool(toolId);
            break;
          case "view-tool":
            viewTool(toolId);
            break;
          case "edit-tool":
            editTool(toolId);
            break;
        }
      });
    }
  });

  /**
   * Close modal when clicking outside of it
   */
  document.addEventListener("DOMContentLoaded", function () {
    const userModal = safeGetElement("user-edit-modal");
    if (userModal) {
      userModal.addEventListener("click", function (event) {
        if (event.target === userModal) {
          hideUserEditModal();
        }
      });
    }

    const teamModal = safeGetElement("team-edit-modal");
    if (teamModal) {
      teamModal.addEventListener("click", function (event) {
        if (event.target === teamModal) {
          hideTeamEditModal();
        }
      });
    }
  });

  /**
   * Create memoized version of search inputs initialization
   * This prevents repeated initialization and provides explicit reset capability
   */
  const {
    init: initializeSearchInputsMemoized,
    debouncedInit: initializeSearchInputsDebounced,
    reset: resetSearchInputsState,
  } = createMemoizedInit(initializeSearchInputs, 300, "SearchInputs");

  // Attach event listener after DOM is loaded or when modal opens
  document.addEventListener("DOMContentLoaded", function () {
    const TypeField = safeGetElement("edit-tool-type");
    if (TypeField) {
      TypeField.addEventListener("change", updateEditToolUrl);
      // Set initial state
      updateEditToolUrl();
    }

    // Initialize default visibility based on URL team_id
    updateDefaultVisibility();

    // Initialize View Public toggle for Add Server modal
    const addServerTeamId = new URL(window.location.href).searchParams.get(
      "team_id"
    );
    if (addServerTeamId) {
      toggleViewPublic(
        "add-server-view-public",
        [
          "associatedGateways",
          "associatedTools",
          "associatedResources",
          "associatedPrompts",
        ],
        addServerTeamId
      );
    }

    // Initialize CA certificate upload immediately
    initializeCACertUpload();

    // Also try to initialize after a short delay (in case the panel loads later)
    setTimeout(initializeCACertUpload, 500);

    // Re-initialize when switching to gateways tab
    const gatewaysTab = document.querySelector('.sidebar-link[data-tab="gateways"]');
    if (gatewaysTab) {
      gatewaysTab.addEventListener("click", function () {
        setTimeout(initializeCACertUpload, 100);
      });
    }

    // Initialize search functionality for all entity types (immediate, no debounce)
    initializeSearchInputsMemoized();
    initializeGlobalSearch();
    // Only initialize password validation if password fields exist on page
    if (document.getElementById("password-field")) {
      initializePasswordValidation();
    }
    initializeAddMembersForms();
    initializeSearchInputsMemoized();

    // Event delegation for team member search - server-side search for unified view
    // This handler is initialized here for early binding, but the actual search logic
    // is in performUserSearch() which is attached when the form is initialized
    const teamSearchTimeouts = {};
    const teamMemberDataCache = {};

    document.body.addEventListener("input", async function (event) {
      const target = event.target;
      if (target.id && target.id.startsWith("user-search-")) {
        const teamId = target.id.replace("user-search-", "");
        const listContainer = safeGetElement(`team-members-list-${teamId}`);

        if (!listContainer) return;

        const query = target.value.trim();

        // Clear previous timeout for this team
        if (teamSearchTimeouts[teamId]) {
          clearTimeout(teamSearchTimeouts[teamId]);
        }

        // Get team member data from cache or script tag
        if (!teamMemberDataCache[teamId]) {
          const teamMemberDataScript = safeGetElement(
            `team-member-data-${teamId}`
          );
          if (teamMemberDataScript) {
            try {
              teamMemberDataCache[teamId] = JSON.parse(
                teamMemberDataScript.textContent || "{}"
              );
              console.log(
                `[Team ${teamId}] Loaded team member data for ${Object.keys(teamMemberDataCache[teamId]).length} members`
              );
            } catch (e) {
              console.error(
                `[Team ${teamId}] Failed to parse team member data:`,
                e
              );
              teamMemberDataCache[teamId] = {};
            }
          } else {
            teamMemberDataCache[teamId] = {};
          }
        }

        // Debounce server call
        teamSearchTimeouts[teamId] = setTimeout(async () => {
          await performUserSearch(
            teamId,
            query,
            listContainer,
            teamMemberDataCache[teamId]
          );
        }, 300);
      }
    });

    // Update available tags when HTMX content loads a table swap.
    // Search inputs live outside the swapped table, so they do NOT need
    // re-initialization here — doing so was causing an infinite loop
    // (clone → set value → input event → reload → swap → repeat).
    document.body.addEventListener("htmx:afterSwap", function (event) {
      const targetId = event.detail.target && event.detail.target.id;
      if (targetId && TABLE_TO_ENTITY_TYPE[targetId]) {
        console.log(`📝 HTMX swap detected in ${targetId}`);
        updateFilterStatus();
      }
    });

    document.body.addEventListener("htmx:afterSettle", function (event) {
      const targetId = event.detail.target && event.detail.target.id;
      const entityType = targetId && TABLE_TO_ENTITY_TYPE[targetId];
      if (entityType) {
        updateAvailableTags(entityType);
      }
    });

    // Initialize search when switching tabs
    document.addEventListener("click", function (event) {
      if (
        event.target.matches('.sidebar-link') ||
        event.target.closest('.sidebar-link')
      ) {
        console.log("🔄 Tab switch detected, resetting search state");
        resetSearchInputsState();
        initializeSearchInputsDebounced();
      }
    });
  });

  // Wire up delegated events on the dropdown once at load time
  document.addEventListener("DOMContentLoaded", () => {
    const ul = document.getElementById("llm-model-dropdown");
    if (!ul) return;
    ul.addEventListener("mousedown", (e) => e.preventDefault());
    ul.addEventListener("click", (e) => {
      const li = e.target.closest("li[data-model-id]");
      if (li) llmModelComboboxSelect(li.dataset.modelId);
    });
  });

  document.addEventListener("DOMContentLoaded", function () {
    initializeRealTimeMonitoring();
  });

  // ===============================================
  // FILTERING FUNCTIONALITY
  // ===============================================

  // Initialize tag filtering when page loads
  document.addEventListener("DOMContentLoaded", function () {
    initializeTagFiltering();

    if (typeof initializeTeamScopingMonitor === "function") {
      initializeTeamScopingMonitor();
    }
  });

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", registerAdminActionListeners);
  } else {
    registerAdminActionListeners();
  }

  /**
   * Rehydrate search inputs and filter status after HTMX content swaps.
   * This ensures that search/tag values from the URL are restored into the
   * input elements after pagination or partial refresh replaces table content.
   */
  document.addEventListener("htmx:afterSettle", function (evt) {
    const target = evt.detail?.target;
    if (!target || !target.id) return;

    // Only rehydrate when a table partial or pagination was swapped
    const isTableSwap =
      target.id.endsWith("-table") ||
      target.id.endsWith("-table-body") ||
      target.id.endsWith("-list-container");
    const isPaginationSwap = target.id.endsWith("-pagination-controls");

    if (isTableSwap || isPaginationSwap) {
      // Search inputs live outside the swapped table content, so they
      // persist across partial refreshes. Only update filter status UI.
      updateFilterStatus();
    }
  });

  // ===================================================================
  // GLOBAL ERROR HANDLERS
  // ===================================================================

  window.addEventListener("error", (e) => {
    console.error("Global error:", e.error, e.filename, e.lineno);
    // Don't show user error for every script error, just log it
  });

  window.addEventListener("unhandledrejection", (e) => {
    console.error("Unhandled promise rejection:", e.reason);
    // Show user error for unhandled promises as they're often more serious
    showErrorMessage("An unexpected error occurred. Please refresh the page.");
  });

  // Enhanced cleanup function for page unload
  window.addEventListener("beforeunload", () => {
    try {
      AppState.reset();
      cleanupToolTestState();
      console.log("✓ Application state cleaned up before unload");
    } catch (error) {
      console.error("Error during cleanup:", error);
    }
  });

  /**
   * Defense-in-depth: audit mutation buttons after every HTMX partial swap.
   *
   * Server-side Jinja2 `can_modify` is the authoritative control. This JS
   * handler is a redundant safety net that hides edit/delete/activate/deactivate
   * buttons when the client-side user context says the current user should not
   * be able to mutate a given row.
   */
  document.addEventListener("htmx:afterSettle", function (_evt) {
    const currentUser = window.CURRENT_USER;
    const isAdmin = Boolean(window.IS_ADMIN);
    const userTeams = window.USER_TEAMS || [];

    if (!currentUser) return;

    // Build a quick lookup: team_id -> role (only "owner" matters for modify)
    const teamRoleMap = {};
    for (let i = 0; i < userTeams.length; i++) {
      if (userTeams[i].id && userTeams[i].role) {
        teamRoleMap[String(userTeams[i].id)] = userTeams[i].role;
      }
    }

    // Known panel table body IDs that contain entity rows
    const tableBodyIds = [
      "tools-table-body",
      "servers-table-body",
      "resources-table-body",
      "prompts-table-body",
      "gateways-table-body",
      "agents-table-body",
      "toolBody",
    ];

    for (let t = 0; t < tableBodyIds.length; t++) {
      const tbody = document.getElementById(tableBodyIds[t]);
      if (!tbody) continue;

      const rows = tbody.querySelectorAll("tr[data-owner-email]");
      for (let r = 0; r < rows.length; r++) {
        const row = rows[r];
        const ownerEmail = row.getAttribute("data-owner-email") || "";
        const teamId = row.getAttribute("data-team-id") || "";
        const visibility = row.getAttribute("data-visibility") || "";

        let canModify = isAdmin;
        if (!canModify && ownerEmail === currentUser) {
          canModify = true;
        }
        if (
          !canModify &&
          visibility === "team" &&
          teamId &&
          teamRoleMap[teamId] === "owner"
        ) {
          canModify = true;
        }

        if (!canModify) {
          // Remove mutation buttons: edit, delete, activate/deactivate, enrich, validate, generate.
          // Match both data-action (tool-ops converted buttons) and inline onclick
          // (other entity tables that still use server-rendered handlers).
          const buttons = row.querySelectorAll(
            "[data-action='edit-tool'], [data-action='enrich-tool'], [data-action='validate-tool'], [data-action='generate-tool-tests'], " +
              "button[onclick*='edit'], button[onclick*='Edit'], button[onclick*='enrich'], button[onclick*='Enrich'], button[onclick*='validate'], " +
              "button[onclick*='Validate'], button[onclick*='generateTool'], button[onclick*='Generate']"
          );
          for (let b = 0; b < buttons.length; b++) {
            buttons[b].remove();
          }
          // Remove delete and state-toggle forms
          const forms = row.querySelectorAll(
            "form[action*='/delete'], form[action*='/state']"
          );
          for (let f = 0; f < forms.length; f++) {
            forms[f].remove();
          }
        }
      }
    }
  });

  // Performance monitoring
  if (window.performance && window.performance.mark) {
    window.performance.mark("app-security-complete");
    console.log("✓ Performance markers available");
  }

  // ===================================================================
  // CHART.JS INSTANCE CLEANUP
  // ===================================================================
  window.addEventListener("beforeunload", () => {
    Admin.chartRegistry.destroyAll();
  });

  // ===================================================================
  // KEYBOARD EVENTS
  // ===================================================================

  // Global event handler for Escape key on modals
  document.addEventListener("keydown", (event) => {
    if (event.key === "Escape") {
      // Find any active modal
      const activeModal = Array.from(AppState.activeModals)[0];
      if (activeModal) {
        closeModal(activeModal);
      }
    }
  });

  // Keyboard shortcuts for pagination (← / →).
  // Registered once here; the previous per-include <script> block registered
  // this listener N times (once per pagination control on the page).
  //
  // Tracks the last-clicked pagination root so that arrow keys target the
  // correct control when multiple pagination components are on the page.
  document.addEventListener("alpine:init", () => {
    // Record which pagination component the user most recently interacted with.
    document.addEventListener("click", (e) => {
      const root = e.target.closest("[data-table-name]");
      if (root) AppState.setLastActivePaginationRoot(root);
    });

    document.addEventListener("keydown", (e) => {
      if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA") {
        return;
      }
      if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;

      e.preventDefault();

      // Use the last-interacted control; fall back to the first visible one.
      let root = AppState.getLastActivePaginationRoot();
      if (!root || root.offsetParent === null) {
        root = Array.from(document.querySelectorAll("[data-table-name]")).find(
          (el) => el.offsetParent !== null
        );
      }
      if (!root) return;

      // Drive navigation through Alpine's reactive data directly so that
      // prevPage() / nextPage()'s own hasPrev / hasNext guards are the
      // authority — avoids relying on DOM button disabled state which may
      // not be evaluated yet after an HTMX swap.
      const data = root._x_dataStack?.[0];
      if (!data) return;
      if (e.key === "ArrowLeft") data.prevPage();
      else data.nextPage();
    });
  });

  // ===================================================================
  // Alpine Components
  // ===================================================================
  document.addEventListener('alpine:init', () => {
    Alpine.data('overflowMenu', (wrapperId = null) => overflowMenu(wrapperId));
  });
})(window.Admin);
