import { initMultiSelect } from '../components/app-multiselect-init.js';
import { initMultiSelectCascade } from '../components/app-multiselect-cascade.js';
import { initStandardListPage } from '../core/app-grid-factory.js';
import { readPageConfig } from '../core/app-page-config.js';
import { warnOnce } from '../core/app-dom.js';
import { getAppBase, escapeHtml, buildBadgeList, gridFilterMultiCsv, gridFilterText } from './app-list-utils.js';

const config = readPageConfig('address-book-index');
if (config) {
  const appBase = getAppBase();
  const gridSearch = config.gridSearch ?? null;
  const filterSchema = config.filterSchema ?? [];
  const filterChipMeta = config.filterChipMeta ?? [];
  const labels = config.labels ?? {};

  const toolbar = document.querySelector('#address-book-drawer-toolbar');
  const saveFilterButton = document.querySelector('[data-address-book-save-filter]');
  const saveFilterForm = document.querySelector('#address-book-save-filter-form');
  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 normalizeCommaSeparated = (value) => {
    if (Array.isArray(value)) {return value.filter(Boolean);}
    return String(value || '')
      .split(',')
      .map((item) => item.trim())
      .filter(Boolean);
  };

  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 gridOptions = {
    gridjs: window.gridjs,
    container: '#address-book-grid',
    dataUrl: 'address-book/data',
    appBase,
    columns: [
      { name: 'UUID', hidden: true },
      {
        name: labels.name || 'Name',
        sort: true,
        formatter: (cell) => {
          const nameValue = typeof cell === 'object' && cell !== null
            ? (cell.name ?? '')
            : cell;
          const avatarUuid = typeof cell === 'object' && cell !== null
            ? (cell.avatar_uuid ?? '')
            : '';
          const name = escapeHtml(nameValue || '-');
          if (!avatarUuid) {
            const initials = escapeHtml(initialsForName(nameValue));
            return gridjs.html(`<span class="grid-name-cell"><span class="grid-avatar grid-avatar-placeholder">${initials}</span><span>${name}</span></span>`);
          }
          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();
          return gridjs.html(`<span class="grid-name-cell"><a data-fslightbox="address-book-avatars" href="${full}"><img class="grid-avatar" src="${src}" alt="" loading="lazy"></a><span>${name}</span></span>`);
        },
      },
      { name: labels.email || 'Email', sort: true },
      { name: labels.phone || 'Phone', sort: false },
      { name: labels.mobile || 'Mobile', sort: false },
      { name: labels.shortDial || 'Short dial', sort: false },
      { name: labels.tenants || 'Tenants', sort: false, formatter: (cell) => gridjs.html(buildBadgeList(cell)) },
      { name: labels.departments || 'Departments', sort: false, formatter: (cell) => gridjs.html(buildBadgeList(cell)) },
      { name: labels.roles || 'Roles', sort: false, formatter: (cell) => gridjs.html(buildBadgeList(cell)) },
    ],
    sortColumns: [null, 'display_name', 'email', null, null, null, null, null, null],
    paginationLimit: 10,
    language: config.gridLang ?? {},
    mapData: (data) => data.data.map((row) => [
      row.uuid,
      {
        name: row.display_name,
        avatar_uuid: row.has_avatar ? row.uuid : '',
      },
      row.email,
      row.phone,
      row.mobile,
      row.short_dial,
      row.tenants,
      row.departments,
      row.roles,
    ]),
    search: gridSearch,
    filterSchema,
    extraFilters: customFilters,
    urlSync: true,
    rowDataset: (row) => ({
      uuid: row?.cells?.[uuidIndex]?.data,
    }),
    rowDblClick: {
      getUrl: (rowData) => {
        const uuid = rowData?.cells?.[uuidIndex]?.data;
        return uuid ? new URL(`address-book/view/${uuid}`, appBase).toString() : '';
      },
    },
  };

  const { gridConfig } = initStandardListPage({
    grid: gridOptions,
    filters: {
      mode: 'drawer',
      chipMeta: filterChipMeta,
      watchInputs: ['#address-book-search'],
    },
  });

  if (!gridConfig || !gridConfig.grid) {
    warnOnce('UI_INIT_FAIL', 'Address book grid init failed', { module: 'address-book-index', component: 'grid' });
  }

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

  const normalizeJoined = (value) => normalizeCommaSeparated(value).join(',');

  if (saveFilterButton && saveFilterForm) {
    saveFilterButton.addEventListener('click', () => {
      if (!gridConfig) {
        return;
      }
      const promptText = saveFilterButton.dataset.saveFilterPrompt || '';
      const emptyText = saveFilterButton.dataset.saveFilterEmpty || '';
      const enteredName = window.prompt(promptText, '');
      if (enteredName === null) {
        return;
      }
      const name = String(enteredName).trim();
      if (!name) {
        if (emptyText) {
          window.alert(emptyText);
        }
        return;
      }

      const appliedQuery = new URL(gridConfig.baseUrl()).searchParams;
      const state = {
        search: String(appliedQuery.get('search') || '').trim(),
        tenants: normalizeJoined(appliedQuery.get('tenants') || ''),
        departments: normalizeJoined(appliedQuery.get('departments') || ''),
        roles: normalizeJoined(appliedQuery.get('roles') || ''),
        custom: {},
      };
      appliedQuery.forEach((value, key) => {
        if (!/^(cf_|cfm_|cfd_)/i.test(key)) {
          return;
        }
        const cleanedValue = String(value || '').trim();
        if (cleanedValue === '') {
          return;
        }
        state.custom[key] = cleanedValue;
      });
      const nameInput = saveFilterForm.querySelector('input[name="name"]');
      const searchInput = saveFilterForm.querySelector('input[name="search"]');
      const tenantsInput = saveFilterForm.querySelector('input[name="tenants"]');
      const departmentsInput = saveFilterForm.querySelector('input[name="departments"]');
      const rolesInput = saveFilterForm.querySelector('input[name="roles"]');
      const extrasContainer = saveFilterForm.querySelector('[data-address-book-save-filter-extra]');
      if (!nameInput || !searchInput || !tenantsInput || !departmentsInput || !rolesInput) {
        return;
      }

      nameInput.value = name;
      searchInput.value = state.search;
      tenantsInput.value = state.tenants;
      departmentsInput.value = state.departments;
      rolesInput.value = state.roles;
      if (extrasContainer) {
        extrasContainer.innerHTML = '';
        Object.entries(state.custom || {}).forEach(([key, value]) => {
          const hidden = document.createElement('input');
          hidden.type = 'hidden';
          hidden.name = key;
          hidden.value = String(value ?? '');
          extrasContainer.appendChild(hidden);
        });
      }
      saveFilterForm.requestSubmit();
    });
  }
}
