import { createListPageModule } from '../core/app-list-page-module.js';
import { initUsersListPage } from './app-users-list.js';
import { bindBulkVisibility } from '../components/app-bulk-selection.js';
import { initDetailDrawer } from '../components/app-detail-drawer.js';
import { buildUrl, badgeHtml, escapeHtml, buildBadgeList, withCurrentListReturn } from './app-list-utils.js';
import { showAsyncFlash, withLoading } from '../components/app-async-flash.js';

createListPageModule({
  configId: 'admin-users-index',
  moduleId: 'admin-users-index',
  missingGridMessage: 'Users grid init failed: Grid.js missing',
  initErrorMessage: 'Users grid init failed',
  setup: ({ config, gridjs, appBase, initListPage }) => {
    const gridSearch = config.gridSearch ?? null;
    const filterSchema = config.filterSchema ?? [];
    const usersFilterChipMeta = config.filterChipMeta ?? [];
    const currentUserUuid = String(config.currentUserUuid || '');
    const canUpdateUsers = config.canUpdateUsers === true;
    const canUpdateSelf = config.canUpdateSelf === true;
    const csrf = config.csrf ?? null;
    const labels = config.labels ?? {};

    const buildBulkUrl = (action) => buildUrl(appBase, `admin/users/bulk/${action}`);

    const rowSelection = gridjs?.plugins?.selection?.RowSelection;
    if (!rowSelection) {
      throw new Error('Grid.js RowSelection plugin is not available.');
    }

    // Layout:
    //   col 0: User compound (display)
    //   col 1: Tenants
    //   col 2: Last login
    //   col 3: State
    //   col 4: UUID (hidden scalar)
    // Selection plugin prepends a checkbox cell, so runtime cells[] are
    // shifted by +1. Cell accessors therefore use indices 1..5 (1-based
    // from the user-visible column order + 1 for the selection col).
    const uuidIndex = 5;
    const activeIndex = 4;
    const canEditRow = (row) => {
      const uuid = String(row?.cells?.[uuidIndex]?.data ?? '');
      if (!uuid) { return false; }
      if (uuid === currentUserUuid) {
        return canUpdateUsers || canUpdateSelf;
      }
      return canUpdateUsers;
    };

    const initialsFromUser = (user) => {
      const parts = [user?.firstName, user?.lastName]
        .map((value) => String(value || '').trim())
        .filter(Boolean);
      const chars = parts.map((value) => value[0] || '').join('').toUpperCase();
      return chars || '?';
    };

    const columns = [
      {
        name: labels.user || 'User',
        sort: true,
        formatter: (cell, row) => {
          const uuid = String(row?.cells?.[uuidIndex]?.data ?? '');
          const firstName = String(cell?.firstName ?? '').trim();
          const lastName = String(cell?.lastName ?? '').trim();
          const email = String(cell?.email ?? '').trim();
          const fullName = [firstName, lastName].filter(Boolean).join(' ') || email || '-';
          const avatarHtml = cell?.hasAvatar && uuid
            ? `<img class="grid-avatar" src="${new URL(`admin/users/avatar-file?uuid=${encodeURIComponent(uuid)}&size=64`, appBase).toString()}" alt="" loading="lazy">`
            : `<span class="grid-avatar grid-avatar-placeholder">${escapeHtml(initialsFromUser(cell))}</span>`;
          const nameEsc = escapeHtml(fullName);
          const emailEsc = escapeHtml(email);
          const subtitle = email && email !== fullName ? `<small>${emailEsc}</small>` : '';
          const inner = `${avatarHtml}<span class="grid-user-profile-text"><strong>${nameEsc}</strong>${subtitle}</span>`;
          if (!uuid) {
            return gridjs.html(`<div class="grid-user-profile">${inner}</div>`);
          }
          const editUrl = escapeHtml(withCurrentListReturn(new URL(`admin/users/edit/${uuid}`, appBase).toString()));
          return gridjs.html(`<a class="grid-user-profile app-grid-link-cell" href="${editUrl}" data-drawer-trigger>${inner}</a>`);
        },
      },
      {
        name: labels.tenants || 'Tenants',
        sort: false,
        formatter: (cell) => gridjs.html(buildBadgeList(cell, { primaryTooltip: labels.primaryTenant || '' })),
      },
      {
        name: labels.lastLogin || 'Last login',
        sort: true,
        formatter: (cell) => badgeHtml(gridjs, cell || labels.never || 'Never'),
      },
      {
        name: labels.state || 'State',
        sort: true,
        formatter: (cell) => cell
          ? gridjs.html(`<span class="badge" data-variant="success">${labels.active || 'Active'}</span>`)
          : gridjs.html(`<span class="badge" data-variant="danger">${labels.inactive || 'Inactive'}</span>`),
      },
      { name: 'UUID', hidden: true },
    ];

    const { gridConfig } = initListPage({
      grid: {
        gridjs,
        container: '#users-grid',
        dataUrl: 'admin/users/data',
        appBase,
        columns,
        sortColumns: ['first_name', null, 'last_login_at', 'active', null],
        paginationLimit: 10,
        language: config.gridLang ?? {},
        mapData: (data) => data.data.map((row) => [
          {
            firstName: row.first_name ?? '',
            lastName: row.last_name ?? '',
            email: row.email ?? '',
            hasAvatar: !!row.has_avatar,
          },
          row.tenants,
          row.last_login,
          row.active,
          row.uuid ?? '',
        ]),
        selection: {
          enabled: true,
          id: 'selectRow',
          component: rowSelection,
          selectAllLabel: labels.selectAll || 'Select all',
          props: {
            id: (row) => String(row.cell(uuidIndex).data ?? ''),
          },
          getSelectedIds: ({ container }) => {
            if (!container) { return []; }
            return Array.from(container.querySelectorAll('.gridjs-tr-selected'))
              .map((row) => row.getAttribute('data-uuid'))
              .filter(Boolean);
          },
        },
        search: gridSearch,
        filterSchema,
        urlSync: true,
        rowDataset: (row) => ({
          uuid: String(row?.cells?.[uuidIndex]?.data ?? ''),
        }),
        rowInteraction: { linkColumn: false },
        rowDblClick: {
          getUrl: (rowData) => {
            if (!canEditRow(rowData)) {
              return '';
            }
            const uuid = String(rowData?.cells?.[uuidIndex]?.data ?? '');
            return uuid ? new URL(`admin/users/edit/${uuid}`, appBase).toString() : '';
          },
        },
      },
      filters: {
        mode: 'drawer',
        chipMeta: usersFilterChipMeta,
        watchInputs: ['#user-search'],
        preserveFilterParamsOnReset: ['tenant'],
        drawer: {
          countExcludeParams: ['tenant'],
        },
        clearMetaOptions: {
          preserveFilterParams: ['tenant'],
        },
      },
    }) || {};

    const usersGridConfig = gridConfig ? { ...gridConfig, indices: { activeIndex, uuidIndex } } : null;
    initUsersListPage({
      gridConfig: usersGridConfig,
      appBase,
      csrf,
      labels,
      exportUrl: config.exportUrl,
      buildBulkUrl,
      bulkDownloadForms: {
        'access-pdf': '#users-access-pdf-bulk-form',
      },
      resetOptions: {
        resetPage: true,
        urlHistoryMode: 'push',
        preserveFilterParams: ['tenant'],
      },
      showFlash: showAsyncFlash,
      withLoading,
    });

    bindBulkVisibility({
      containerSelector: '#users-grid',
      buttonSelector: '[data-users-bulk]',
    });

    initDetailDrawer({
      gridConfig,
      triggerSelector: '[data-drawer-trigger]',
      rowUuidAttr: 'uuid',
      fetchUrl: (uuid) => new URL(`admin/users/view-fragment/${uuid}`, appBase).toString(),
      fullUrl: (uuid) => withCurrentListReturn(new URL(`admin/users/edit/${uuid}`, appBase).toString()),
      hashPrefix: 'user',
    });

    return usersGridConfig;
  },
});
