export function initUsersListPage(options = {}) {
  const {
    gridConfig,
    appBase,
    csrf,
    labels = {},
    selectors = {},
    bulkDownloadForms = {},
    exportPath = 'admin/users/export',
    listPath = 'admin/users',
    buildBulkUrl,
    showFlash,
    withLoading
  } = options;

  if (!gridConfig) {return;}

  const exportSelector = selectors.exportButton || '[data-users-export]';
  const resetSelector = selectors.resetButton || '[data-users-reset]';
  const bulkSelector = selectors.bulkButtons || '[data-users-bulk]';

  const resolveBulkUrl = buildBulkUrl
    ? buildBulkUrl
    : (action) => new URL(`admin/users/bulk/${action}`, appBase).toString();

  const postAction = async (url, data = {}) => {
    const body = new URLSearchParams({ ...data, [csrf.key]: csrf.token });
    return fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json',
        'X-Requested-With': 'fetch'
      },
      body
    });
  };

  const exportButton = document.querySelector(exportSelector);
  if (exportButton) {
    exportButton.addEventListener('click', () => {
      const exportUrl = new URL(exportPath, appBase);
      const dataUrl = new URL(gridConfig.baseUrl());
      dataUrl.searchParams.forEach((value, key) => exportUrl.searchParams.set(key, value));
      const sortParams = gridConfig.getSortParams ? gridConfig.getSortParams() : null;
      if (sortParams && sortParams.order) {
        exportUrl.searchParams.set('order', sortParams.order);
        exportUrl.searchParams.set('dir', sortParams.dir || 'asc');
      }
      window.location.href = exportUrl.toString();
    });
  }

  const resetButton = document.querySelector(resetSelector);
  if (resetButton) {
    resetButton.addEventListener('click', () => {
      if (typeof gridConfig.resetFilters === 'function') {
        gridConfig.resetFilters();
      } else {
        gridConfig.updateGrid();
      }
    });
  }

  const bulkButtons = Array.from(document.querySelectorAll(bulkSelector));
  if (bulkButtons.length) {
    bulkButtons.forEach((button) => {
      button.addEventListener('click', async () => {
        const action = button.getAttribute('data-users-bulk') || '';
        const ids = gridConfig.selection?.getSelectedIds?.() || [];
        const validActions = ['activate', 'deactivate', 'delete', 'send-access', 'access-pdf'];
        if (!ids.length || !validActions.includes(action)) {
          if (action && !validActions.includes(action)) {
            console.warn(`Unsupported users bulk action: ${action}`);
          }
          return;
        }
        const confirmTexts = {
          'activate': labels.bulkActivateConfirm,
          'deactivate': labels.bulkDeactivateConfirm,
          'delete': labels.bulkDeleteConfirm,
          'send-access': labels.bulkSendAccessConfirm,
          'access-pdf': labels.bulkAccessPdfConfirm
        };
        const confirmText = confirmTexts[action];
        if (confirmText && !window.confirm(confirmText)) {
          return;
        }

        const downloadFormSelector = bulkDownloadForms?.[action];
        if (downloadFormSelector) {
          const downloadForm = document.querySelector(downloadFormSelector);
          if (!downloadForm) {
            window.location.href = new URL(listPath, appBase).toString();
            return;
          }
          const uuidsInput = downloadForm.querySelector('input[name="uuids"]');
          if (uuidsInput) {
            uuidsInput.value = ids.join(',');
          }
          downloadForm.submit();
          return;
        }

        const executeBulk = async () => {
          const url = resolveBulkUrl(action);
          const response = await postAction(url, { uuids: ids.join(',') });
          const data = await response.json().catch(() => null);
          if (response.ok && data && data.ok) {
            gridConfig.selection?.clear?.();
            gridConfig.grid?.forceRender();

            if (showFlash && labels.bulkMessages) {
              const msg = labels.bulkMessages[action];
              if (msg) {
                const count = data.count ?? 0;
                const failed = data.failed ?? 0;
                let text = msg.success.replace('%d', count);
                if (failed > 0 && msg.partial) {
                  text = msg.partial.replace('%d', count).replace('%f', failed);
                }
                showFlash('success', text);
              }
            }
          } else {
            if (showFlash && labels.bulkMessages) {
              const msg = labels.bulkMessages[action];
              if (msg?.error) {
                showFlash('error', msg.error);
              } else {
                window.location.href = new URL(listPath, appBase).toString();
              }
            } else {
              window.location.href = new URL(listPath, appBase).toString();
            }
          }
        };

        if (withLoading) {
          await withLoading(executeBulk);
        } else {
          await executeBulk();
        }
      });
    });
  }
}
