<?php
use MintyPHP\Buffer;
use MintyPHP\Session;

$csrfKey = $csrfKey ?? Session::$csrfSessionKey;
$csrfToken = $csrfToken ?? ($_SESSION[$csrfKey] ?? '');
$customFieldFilterDefinitions = is_array($customFieldFilterDefinitions ?? null) ? $customFieldFilterDefinitions : [];
$activeCustomFieldQuery = is_array($customFieldFilterQuery ?? null) ? $customFieldFilterQuery : [];
?>
<?php
$breadcrumbs = [
  ['label' => t('Home'), 'path' => 'admin'],
  ['label' => t('Address book')],
];
require templatePath('partials/app-breadcrumb.phtml');
?>
<div class="app-list-titlebar">
  <h1><?php e(t('Address book')); ?></h1>
  <div class="app-list-titlebar-actions">
    <button
      class="outline secondary"
      type="button"
      data-address-book-save-filter
      data-save-filter-prompt="<?php e(t('Enter a name for this filter')); ?>"
      data-save-filter-empty="<?php e(t('Filter name is required')); ?>"
    >
      <i class="bi bi-bookmark-plus"></i> <?php e(t('Save filter')); ?>
    </button>
  </div>
</div>
<div
  class="app-list-toolbar"
  id="address-book-toolbar"
  data-tenant-dept-map="<?php e(json_encode($tenantDepartmentMap ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); ?>"
>
  <label class="app-field">
    <span><?php e(t('Search')); ?></span>
    <input type="search" id="address-book-search" placeholder="<?php e(t('Search...')); ?>">
  </label>
  <?php multiSelectFilter('address-book-tenant-filter', 'Tenants', 'Select tenants', $tenantItems ?? [], $activeTenants ?? []); ?>
  <?php multiSelectFilter('address-book-department-filter', 'Departments', 'Select departments', $departments ?? [], $activeDepartments ?? []); ?>
  <?php multiSelectFilter('address-book-role-filter', 'Roles', 'Select roles', $roles ?? [], $activeRoles ?? []); ?>
</div>
<?php if ($customFieldFilterDefinitions): ?>
  <div class="app-list-toolbar" id="address-book-custom-filters">
    <?php foreach ($customFieldFilterDefinitions as $definition): ?>
      <?php
      $definitionUuid = strtolower(trim((string) ($definition['uuid'] ?? '')));
      $definitionType = strtolower(trim((string) ($definition['type'] ?? '')));
      $definitionLabel = trim((string) ($definition['label'] ?? ''));
      $definitionOptions = is_array($definition['options'] ?? null) ? $definition['options'] : [];
      if ($definitionUuid === '' || $definitionLabel === '' || $definitionType === '') {
        continue;
      }
      $label = $definitionLabel;
      $idSuffix = preg_replace('/[^a-z0-9]+/', '-', $definitionUuid);
      $paramScalar = 'cf_' . $definitionUuid;
      $paramMulti = 'cfm_' . $definitionUuid;
      $paramDateFrom = 'cfd_' . $definitionUuid . '_from';
      $paramDateTo = 'cfd_' . $definitionUuid . '_to';
      ?>
      <?php if ($definitionType === 'select'): ?>
        <?php $currentValue = (string) ($activeCustomFieldQuery[$paramScalar] ?? ''); ?>
        <label class="app-field" for="address-book-custom-filter-<?php e($idSuffix); ?>">
          <span><?php e($label); ?></span>
          <select id="address-book-custom-filter-<?php e($idSuffix); ?>"
            data-address-book-custom-filter
            data-address-book-custom-filter-param="<?php e($paramScalar); ?>">
            <option value=""><?php e(t('Please select')); ?></option>
            <?php foreach ($definitionOptions as $option): ?>
              <?php $optionId = (string) ($option['id'] ?? ''); ?>
              <?php if ($optionId === '') {
                continue;
              } ?>
              <option value="<?php e($optionId); ?>" <?php e($currentValue === $optionId ? 'selected' : ''); ?>>
                <?php e((string) ($option['description'] ?? '')); ?>
              </option>
            <?php endforeach; ?>
          </select>
        </label>
      <?php elseif ($definitionType === 'boolean'): ?>
        <?php $currentValue = strtolower(trim((string) ($activeCustomFieldQuery[$paramScalar] ?? ''))); ?>
        <label class="app-field" for="address-book-custom-filter-<?php e($idSuffix); ?>">
          <span><?php e($label); ?></span>
          <select id="address-book-custom-filter-<?php e($idSuffix); ?>"
            data-address-book-custom-filter
            data-address-book-custom-filter-param="<?php e($paramScalar); ?>">
            <option value=""><?php e(t('Please select')); ?></option>
            <option value="1" <?php e(in_array($currentValue, ['1', 'true'], true) ? 'selected' : ''); ?>>
              <?php e(t('Yes')); ?>
            </option>
            <option value="0" <?php e(in_array($currentValue, ['0', 'false'], true) ? 'selected' : ''); ?>>
              <?php e(t('No')); ?>
            </option>
          </select>
        </label>
      <?php elseif ($definitionType === 'multiselect'): ?>
        <?php
        $currentValues = array_values(array_filter(array_map(
          'trim',
          explode(',', (string) ($activeCustomFieldQuery[$paramMulti] ?? ''))
        ), static fn ($item): bool => $item !== ''));
        multiSelectFilter(
          'address-book-custom-filter-' . $idSuffix,
          $label,
          'Select options',
          $definitionOptions,
          $currentValues
        );
        ?>
        <input type="hidden"
          data-address-book-custom-filter
          data-address-book-custom-filter-type="multiselect"
          data-address-book-custom-filter-param="<?php e($paramMulti); ?>"
          data-address-book-custom-filter-input="#address-book-custom-filter-<?php e($idSuffix); ?>"
        >
      <?php elseif ($definitionType === 'date'): ?>
        <?php
        $currentFrom = (string) ($activeCustomFieldQuery[$paramDateFrom] ?? '');
        $currentTo = (string) ($activeCustomFieldQuery[$paramDateTo] ?? '');
        ?>
          <label class="app-field" for="address-book-custom-filter-<?php e($idSuffix); ?>-from">
            <span><?php e($label . ' ' . t('From')); ?></span>
            <input type="date"
              id="address-book-custom-filter-<?php e($idSuffix); ?>-from"
              value="<?php e($currentFrom); ?>"
              data-address-book-custom-filter
              data-address-book-custom-filter-param="<?php e($paramDateFrom); ?>">
          </label>
          <label class="app-field" for="address-book-custom-filter-<?php e($idSuffix); ?>-to">
            <span><?php e($label . ' ' . t('To')); ?></span>
            <input type="date"
              id="address-book-custom-filter-<?php e($idSuffix); ?>-to"
              value="<?php e($currentTo); ?>"
              data-address-book-custom-filter
              data-address-book-custom-filter-param="<?php e($paramDateTo); ?>">
          </label>
      <?php endif; ?>
    <?php endforeach; ?>
  </div>
<?php endif; ?>
<form id="address-book-save-filter-form" method="post" action="address-book/saved-filter-save" hidden>
  <input type="hidden" name="<?php e($csrfKey); ?>" value="<?php e($csrfToken); ?>">
  <input type="hidden" name="name" value="">
  <input type="hidden" name="search" value="">
  <input type="hidden" name="tenants" value="">
  <input type="hidden" name="departments" value="">
  <input type="hidden" name="roles" value="">
  <div data-address-book-save-filter-extra></div>
</form>
<div class="app-list-table">
  <div id="address-book-grid"></div>
</div>

<script src="<?php e(asset('vendor/gridjs/gridjs.umd.js')); ?>"></script>
<script type="module">
  import { initMultiSelect } from "<?php e(asset('js/components/app-multiselect-init.js')); ?>";
  import { initMultiSelectCascade } from "<?php e(asset('js/components/app-multiselect-cascade.js')); ?>";
  import { createServerGrid } from "<?php e(assetVersion('js/core/app-grid-factory.js')); ?>";
  import { getAppBase, escapeHtml, buildBadgeList } from "<?php e(asset('js/pages/app-list-utils.js')); ?>";

  const appBase = getAppBase();
  const toolbar = document.querySelector('#address-book-toolbar');
  const saveFilterButton = document.querySelector('[data-address-book-save-filter]');
  const saveFilterForm = document.querySelector('#address-book-save-filter-form');
  const searchField = document.querySelector('#address-book-search');
  const tenantFilterInput = document.querySelector('#address-book-tenant-filter');
  const departmentFilterInput = document.querySelector('#address-book-department-filter');
  const roleFilterInput = document.querySelector('#address-book-role-filter');
  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 collectFilterState = () => {
    const normalizeJoined = (value) => normalizeCommaSeparated(value).join(',');
    const custom = {};
    customFilterInputs.forEach((input) => {
      const param = String(input?.dataset?.addressBookCustomFilterParam || '').trim();
      if (!param) return;

      if (input.dataset.addressBookCustomFilterType === 'multiselect') {
        const targetSelector = input.dataset.addressBookCustomFilterInput || '';
        const target = targetSelector ? document.querySelector(targetSelector) : null;
        const joined = normalizeJoined(target?.value || '');
        if (joined) {
          custom[param] = joined;
        }
        return;
      }

      const value = String(input?.value || '').trim();
      if (value !== '') {
        custom[param] = value;
      }
    });
    return {
      search: String(searchField?.value || '').trim(),
      tenants: normalizeJoined(tenantFilterInput?.value),
      departments: normalizeJoined(departmentFilterInput?.value),
      roles: normalizeJoined(roleFilterInput?.value),
      custom
    };
  };
  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 baseFilters = [
    {
      input: '#address-book-tenant-filter',
      param: 'tenants',
      default: [],
      normalize: normalizeCommaSeparated
    },
    {
      input: '#address-book-department-filter',
      param: 'departments',
      default: [],
      normalize: normalizeCommaSeparated
    },
    {
      input: '#address-book-role-filter',
      param: 'roles',
      default: [],
      normalize: normalizeCommaSeparated
    }
  ];
  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 {
        input: targetSelector,
        param,
        default: [],
        normalize: normalizeCommaSeparated
      };
    }
    return {
      input,
      param,
      default: ''
    };
  }).filter(Boolean);

  createServerGrid({
    gridjs: window.gridjs,
    container: '#address-book-grid',
    dataUrl: 'address-book/data',
    appBase,
    columns: [
      { name: 'UUID', hidden: true },
      {
        name: "<?php e(t('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: "<?php e(t('Email')); ?>", sort: true },
      { name: "<?php e(t('Phone')); ?>", sort: false },
      { name: "<?php e(t('Mobile')); ?>", sort: false },
      { name: "<?php e(t('Short dial')); ?>", sort: false },
      { name: "<?php e(t('Tenants')); ?>", sort: false, formatter: (cell) => gridjs.html(buildBadgeList(cell)) },
      { name: "<?php e(t('Departments')); ?>", sort: false, formatter: (cell) => gridjs.html(buildBadgeList(cell)) },
      { name: "<?php e(t('Roles')); ?>", sort: false, formatter: (cell) => gridjs.html(buildBadgeList(cell)) }
    ],
    sortColumns: [null, 'display_name', 'email', null, null, null, null, null, null],
    paginationLimit: 10,
    language: <?php MintyPHP\Buffer::get('grid_lang'); ?>,
    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: {
      input: '#address-book-search',
      param: 'search',
      debounce: 250
    },
    filters: [...baseFilters, ...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() : '';
      }
    }
  });

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

  if (saveFilterButton && saveFilterForm) {
    saveFilterButton.addEventListener('click', () => {
      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 state = collectFilterState();
      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();
    });
  }
</script>
