import { initMultiSelect } from '/js/components/app-multiselect-init.js';
import { initMultiSelectCascade } from '/js/components/app-multiselect-cascade.js';
import { initDetailDrawer } from '/js/components/app-detail-drawer.js';
import { createListPageModule } from '/js/core/app-list-page-module.js';
import { escapeHtml, gridFilterMultiCsv, gridFilterText, withCurrentListReturn } from '/js/pages/app-list-utils.js';

createListPageModule({
  configId: 'address-book-index',
  moduleId: 'address-book-index',
  missingGridMessage: 'Address book grid init failed: Grid.js missing',
  initErrorMessage: 'Address book grid init failed',
  setup: ({ config, gridjs, appBase, initListPage }) => {
    const labels = config.labels ?? {};
    const gridSearch = config.gridSearch ?? null;
    const filterSchema = config.filterSchema ?? [];
    const filterChipMeta = config.filterChipMeta ?? [];

    const toolbar = document.querySelector('#address-book-drawer-toolbar');
    const customFilterInputs = Array.from(document.querySelectorAll('[data-address-book-custom-filter]'));
    const tenantDepartmentMap = toolbar?.dataset?.tenantDeptMap
      ? JSON.parse(toolbar.dataset.tenantDeptMap)
      : {};

    const uuidIndex = 0;

    const initialsForName = (name) => {
      const parts = String(name || '')
        .trim()
        .split(/\s+/)
        .filter(Boolean);
      const chars = parts.slice(0, 2).map((value) => value[0] || '').join('').toUpperCase();
      return chars || '?';
    };

    const customFilters = customFilterInputs.map((input) => {
      const param = String(input?.dataset?.addressBookCustomFilterParam || '').trim();
      if (!param) { return null; }
      if (input.dataset.addressBookCustomFilterType === 'multiselect') {
        const targetSelector = input.dataset.addressBookCustomFilterInput || '';
        return gridFilterMultiCsv(targetSelector, param, { default: [] });
      }
      return gridFilterText(input, param, { default: '' });
    }).filter(Boolean);

    const { gridConfig } = initListPage({
      grid: {
        gridjs,
        container: '#address-book-grid',
        dataUrl: 'address-book/data',
        appBase,
        columns: [
          { name: 'UUID', hidden: true },
          {
            name: labels.name || 'Name',
            sort: true,
            formatter: (cell, row) => {
              const nameValue = cell?.name ?? '';
              const email = cell?.email ?? '';
              const avatarUuid = cell?.avatar_uuid ?? '';
              const name = escapeHtml(nameValue || '-');
              const uuid = row?.cells?.[uuidIndex]?.data;
              const editUrl = uuid ? withCurrentListReturn(new URL(`address-book/view/${uuid}`, appBase).toString()) : '';
              const nameNode = editUrl
                ? `<a class="app-grid-link-cell addr-identity-name" href="${escapeHtml(editUrl)}" data-drawer-trigger>${name}</a>`
                : `<span class="addr-identity-name">${name}</span>`;
              const emailNode = email
                ? `<span class="addr-identity-email">${escapeHtml(email)}</span>`
                : '';
              let avatarNode;
              if (!avatarUuid) {
                const initials = escapeHtml(initialsForName(nameValue));
                avatarNode = `<span class="grid-avatar grid-avatar-placeholder addr-identity-avatar">${initials}</span>`;
              } else {
                const src = new URL(`admin/users/avatar-file?uuid=${avatarUuid}&size=64`, appBase).toString();
                const full = new URL(`admin/users/avatar-file?uuid=${avatarUuid}&size=256`, appBase).toString();
                avatarNode = `<a data-fslightbox="address-book-avatars" href="${full}"><img class="grid-avatar addr-identity-avatar" src="${src}" alt="" loading="lazy"></a>`;
              }
              return gridjs.html(`<span class="addr-identity-cell">${avatarNode}<span class="addr-identity-text">${nameNode}${emailNode}</span></span>`);
            },
          },
          {
            name: labels.context || 'Tenant / Department',
            sort: false,
            formatter: (cell) => {
              const tenant = escapeHtml(String(cell?.tenant || ''));
              const department = escapeHtml(String(cell?.department || ''));
              const extra = Number(cell?.extra || 0);
              if (!tenant && !department && !extra) {
                return gridjs.html('<span class="addr-context-cell addr-context-empty">–</span>');
              }
              const parts = [];
              if (tenant) {
                parts.push(`<span class="addr-context-primary">${tenant}</span>`);
              }
              if (department) {
                parts.push(`<span class="addr-context-separator" aria-hidden="true">·</span><span class="addr-context-secondary">${department}</span>`);
              }
              if (extra > 0) {
                const extraLabel = escapeHtml(labels.extraAssignments || 'further assignments');
                parts.push(`<span class="addr-context-extra" title="+${extra} ${extraLabel}">+${extra}</span>`);
              }
              return gridjs.html(`<span class="addr-context-cell">${parts.join('')}</span>`);
            },
          },
          {
            name: labels.phone || 'Phone',
            sort: false,
            formatter: (cell) => {
              const number = String(cell || '').trim();
              if (!number) {
                return gridjs.html('<span class="addr-phone-empty">–</span>');
              }
              const tel = number.replace(/[^+0-9]/g, '');
              const safe = escapeHtml(number);
              return gridjs.html(`<a class="addr-phone-cell" href="tel:${escapeHtml(tel)}">${safe}</a>`);
            },
          },
          {
            name: labels.actions || 'Actions',
            sort: false,
            formatter: (cell, row) => {
              const uuid = row?.cells?.[uuidIndex]?.data;
              if (!uuid) {
                return gridjs.html('');
              }
              const viewUrl = escapeHtml(withCurrentListReturn(new URL(`address-book/view/${uuid}`, appBase).toString()));
              const email = String(cell?.email || '').trim();
              const openLabel = escapeHtml(labels.openDetails || 'Open details');
              const mailLabel = escapeHtml(labels.sendEmail || 'Send email');
              const actions = [
                `<a class="addr-action-button" href="${viewUrl}" data-tooltip="${openLabel}" data-tooltip-pos="left" aria-label="${openLabel}"><i class="bi bi-box-arrow-up-right"></i></a>`,
              ];
              if (email) {
                const safeMail = escapeHtml(email);
                actions.push(`<a class="addr-action-button" href="mailto:${safeMail}" data-tooltip="${mailLabel}" data-tooltip-pos="left" aria-label="${mailLabel}"><i class="bi bi-envelope"></i></a>`);
              }
              return gridjs.html(`<span class="addr-action-cell">${actions.join('')}</span>`);
            },
          },
        ],
        sortColumns: [null, 'display_name', null, null, null],
        paginationLimit: 10,
        language: config.gridLang ?? {},
        mapData: (data) => data.data.map((row) => {
          const phone = (row.phone && String(row.phone).trim()) || (row.mobile && String(row.mobile).trim()) || '';
          return [
            row.uuid,
            {
              name: row.display_name,
              email: row.email || '',
              avatar_uuid: row.has_avatar ? row.uuid : '',
            },
            {
              tenant: row.primary_tenant_label || '',
              department: row.primary_department_label || '',
              extra: row.extra_assignments_count || 0,
            },
            phone,
            { email: row.email || '' },
          ];
        }),
        search: gridSearch,
        filterSchema,
        extraFilters: customFilters,
        urlSync: true,
        rowDataset: (row) => ({
          uuid: row?.cells?.[uuidIndex]?.data,
        }),
        rowInteraction: { linkColumn: false },
        rowDblClick: {
          getUrl: (rowData) => {
            const uuid = rowData?.cells?.[uuidIndex]?.data;
            return uuid ? new URL(`address-book/view/${uuid}`, appBase).toString() : '';
          },
        },
      },
      filters: {
        mode: 'drawer',
        chipMeta: filterChipMeta,
        watchInputs: ['#address-book-search'],
        preserveFilterParamsOnReset: ['tenant'],
        drawer: {
          countExcludeParams: ['tenant'],
        },
        clearMetaOptions: {
          preserveFilterParams: ['tenant'],
        },
      },
    }) || {};

    initMultiSelect().then(() => {
      initMultiSelectCascade({
        parent: '#address-book-tenant-filter',
        child: '#address-book-department-filter',
        map: tenantDepartmentMap,
        mode: 'disable',
        clearInvalid: true,
      });
    });

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

    return gridConfig;
  },
});
