import { createListPageModule } from '/js/core/app-list-page-module.js';
import { escapeHtml, withCurrentListReturn } from '/js/pages/app-list-utils.js';
import { postForm } from '/js/core/app-http.js';
import { showAsyncFlash } from '/js/components/app-async-flash.js';
import { initListExport } from '/js/core/app-list-export.js';

const LEVEL_LABELS = {
  niedrig: 'Low',
  normal: 'Normal',
  hoch: 'High',
  kritisch: 'Critical',
};

function resolveDialog() {
  const dialog = document.querySelector('[data-app-security-dialog]');
  if (!(dialog instanceof HTMLDialogElement)) {
    return null;
  }
  return {
    dialog,
    domainEl: dialog.querySelector('#sec-dialog-domain'),
    levelSelect: dialog.querySelector('#sec-dialog-level'),
    noteTextarea: dialog.querySelector('#sec-dialog-note'),
    csrfInput: dialog.querySelector('#sec-dialog-csrf'),
    saveButton: dialog.querySelector('[data-sec-dialog-save]'),
    cancelButton: dialog.querySelector('[data-sec-dialog-cancel]'),
    closeButton: dialog.querySelector('[data-sec-dialog-close]'),
  };
}

function openSecurityDialog(badge, securityLevelUrl, labels, onSaved) {
  const els = resolveDialog();
  if (!els) {
    return;
  }

  const domainNo = badge.dataset.domainNo || '';
  const currentLevel = badge.dataset.level || 'normal';
  const currentNote = badge.dataset.note || '';
  const domainName = badge.dataset.domainName || domainNo;

  els.domainEl.textContent = domainName;
  els.levelSelect.value = currentLevel;
  els.noteTextarea.value = currentNote;
  els.saveButton.disabled = false;

  const activeElement = document.activeElement;
  let saved = false;

  const cleanup = () => {
    els.saveButton.removeEventListener('click', onSave);
    els.cancelButton.removeEventListener('click', onCancel);
    if (els.closeButton) {
      els.closeButton.removeEventListener('click', onCancel);
    }
    els.dialog.removeEventListener('close', onClose);
    els.dialog.removeEventListener('cancel', onCancelDialog);
    els.dialog.removeEventListener('click', onBackdrop);
  };

  const closeDialog = () => {
    saved = true;
    cleanup();
    try {
      if (els.dialog.open) {
        els.dialog.close();
      }
    } catch { /* no-op */ }
    document.body.classList.remove('modal-is-open');
    if (activeElement && document.contains(activeElement)) {
      window.requestAnimationFrame(() => {
        activeElement.focus({ preventScroll: true });
      });
    }
  };

  const onSave = async () => {
    const newLevel = els.levelSelect.value;
    const note = els.noteTextarea.value.trim();
    const csrfKey = els.csrfInput?.name || 'csrf_token';
    const csrfToken = els.csrfInput?.value || '';

    const errorLabel = labels?.saveError || 'Save failed';

    if (!csrfToken) {
      showAsyncFlash('error', errorLabel);
      return;
    }

    els.saveButton.disabled = true;
    els.saveButton.setAttribute('aria-busy', 'true');

    const body = new URLSearchParams({
      domain_no: domainNo,
      security_level: newLevel,
      note,
      [csrfKey]: csrfToken,
    });

    try {
      const resp = await postForm(securityLevelUrl, body);
      if (resp?.ok) {
        closeDialog();
        if (typeof onSaved === 'function') {
          onSaved();
        }
        return;
      }
      showAsyncFlash('error', resp?.error || errorLabel);
    } catch (error) {
      showAsyncFlash('error', error?.message || errorLabel);
    } finally {
      els.saveButton.disabled = false;
      els.saveButton.removeAttribute('aria-busy');
    }
  };

  const onCancel = (event) => {
    event.preventDefault();
    closeDialog();
  };

  const onCancelDialog = (event) => {
    event.preventDefault();
    closeDialog();
  };

  const onClose = () => {
    if (!saved) {
      saved = true;
      cleanup();
      document.body.classList.remove('modal-is-open');
    }
  };

  const onBackdrop = (event) => {
    if (event.target === els.dialog) {
      closeDialog();
    }
  };

  els.saveButton.addEventListener('click', onSave);
  els.cancelButton.addEventListener('click', onCancel);
  if (els.closeButton) {
    els.closeButton.addEventListener('click', onCancel);
  }
  els.dialog.addEventListener('cancel', onCancelDialog);
  els.dialog.addEventListener('close', onClose);
  els.dialog.addEventListener('click', onBackdrop);

  document.body.classList.add('modal-is-open');

  try {
    els.dialog.showModal();
  } catch {
    cleanup();
    document.body.classList.remove('modal-is-open');
    return;
  }

  window.requestAnimationFrame(() => {
    els.levelSelect.focus();
  });
}

createListPageModule({
  configId: 'helpdesk-domains',
  moduleId: 'helpdesk-domains',
  missingGridMessage: 'Helpdesk domains grid init failed: Grid.js missing',
  initErrorMessage: 'Helpdesk domains grid init failed',
  setup: ({ config, gridjs, appBase, initListPage }) => {
    const labels = config.labels || {};
    const domainBaseUrl = config.domainBaseUrl || '';
    const securityLevelUrl = (config.securityLevelDataUrl || '').trim();
    const domainUrlIndex = 8;

    const gridContainer = document.querySelector('#helpdesk-domains-grid');
    const gridRef = { grid: null };
    const refreshGrid = () => {
      gridRef.grid?.forceRender();
    };

    gridContainer.addEventListener('click', (event) => {
      const badge = event.target.closest('td .badge[data-domain-no][role="button"]');
      if (!badge) {
        return;
      }
      event.preventDefault();
      event.stopPropagation();
      openSecurityDialog(badge, securityLevelUrl, labels, refreshGrid);
    });

    gridContainer.addEventListener('keydown', (event) => {
      if (event.key !== 'Enter' && event.key !== ' ') {
        return;
      }
      const badge = event.target.closest('.badge[data-domain-no][role="button"]');
      if (!badge) {
        return;
      }
      event.preventDefault();
      event.stopPropagation();
      openSecurityDialog(badge, securityLevelUrl, labels, refreshGrid);
    });

    const { gridConfig } = initListPage({
      grid: {
        gridjs,
        container: '#helpdesk-domains-grid',
        dataUrl: config.dataUrl || 'helpdesk/domains-data',
        appBase,
        columns: [
          {
            name: labels.no || 'No.',
            sort: true,
            formatter: (cell) => {
              const no = escapeHtml(cell?.no || '');
              const detailUrl = String(cell?.url || '').trim();
              if (detailUrl === '') {
                return gridjs.html(no);
              }
              const href = escapeHtml(detailUrl);
              return gridjs.html(`<a href="${href}">${no}</a>`);
            },
          },
          {
            name: labels.customerName || 'Customer Name',
            sort: true,
            formatter: (cell) => {
              const name = escapeHtml(cell?.name || '');
              const detailUrl = String(cell?.url || '').trim();
              if (detailUrl === '') {
                return gridjs.html(name);
              }
              const href = escapeHtml(withCurrentListReturn(detailUrl));
              return gridjs.html(`<a href="${href}">${name}</a>`);
            },
          },
          { name: labels.url || 'URL', sort: true },
          { name: labels.contractType || 'Contract Type', sort: true },
          {
            name: labels.state || 'State',
            sort: true,
            formatter: (cell) => {
              const state = escapeHtml(cell?.state || '');
              const variant = cell?.variant || 'neutral';
              return gridjs.html(`<span class="badge" data-variant="${escapeHtml(variant)}">${state}</span>`);
            },
          },
          { name: labels.administration || 'Administration', sort: true },
          {
            name: labels.securityLevel || 'Security level',
            sort: true,
            formatter: (cell) => {
              const level = cell?.level || 'normal';
              const variant = cell?.variant || 'neutral';
              const domainNo = cell?.domainNo || '';
              const note = cell?.note || '';
              const domainName = cell?.domainName || domainNo;
              const levelLabel = labels?.[level] ?? LEVEL_LABELS[level] ?? level;
              const noteAttr = note ? ` data-note="${escapeHtml(note)}"` : '';
              return gridjs.html(`<span class="badge" data-variant="${escapeHtml(variant)}" data-domain-no="${escapeHtml(domainNo)}" data-level="${escapeHtml(level)}" data-domain-name="${escapeHtml(domainName)}" role="button" tabindex="0"${noteAttr}>${escapeHtml(levelLabel)}</span>`);
            },
          },
          {
            name: labels.note || 'Note',
            sort: true,
            formatter: (cell) => {
              const note = String(cell || '').trim();
              if (note === '') {
                return gridjs.html('<span class="text-muted">—</span>');
              }
              const escaped = escapeHtml(note);
              return gridjs.html(`<span class="app-cell-note" title="${escaped}">${escaped}</span>`);
            },
          },
          { name: 'debitor_url', hidden: true },
          { name: 'domain_detail_url', hidden: true },
        ],
        sortColumns: ['No', 'Customer_Name', 'URL', 'contract_type', 'State', 'Administration', 'security_level', 'security_level_note', null, null],
        paginationLimit: 10,
        language: config.gridLang || {},
        mapData: (data) => (data.data || []).map((row) => {
          const domainDetailUrl = domainBaseUrl && row.No
            ? domainBaseUrl + encodeURIComponent(row.No)
            : '';
          return [
            { no: row.No || '', url: domainDetailUrl },
            { name: row.Customer_Name || '', url: row.debitor_url || '' },
            row.URL || '',
            row.contract_type || '',
            { state: row.State || '', variant: row.state_variant || 'neutral' },
            row.Administration || '',
            { level: row.security_level || 'normal', variant: row.security_level_variant || 'neutral', domainNo: row.No || '', note: row.security_level_note || '', domainName: row.Customer_Name || row.No || '' },
            row.security_level_note || '',
            row.debitor_url || '',
            domainDetailUrl,
          ];
        }),
        search: config.gridSearch || null,
        filterSchema: config.filterSchema || [],
        urlSync: true,
        rowInteraction: { linkColumn: 0 },
        rowDblClick: {
          getUrl: (rowData) => rowData?.cells?.[domainUrlIndex]?.data || '',
          exclude: '.badge[role="button"], .grid-actions, button, a, input, select, textarea',
        },
      },
      filters: {
        mode: 'drawer',
        chipMeta: config.filterChipMeta || {},
        watchInputs: ['#helpdesk-domains-search-input'],
      },
    }) || {};

    gridRef.grid = gridConfig?.grid || null;

    if (gridConfig && config.exportUrl) {
      initListExport({ gridConfig, exportUrl: config.exportUrl });
    }

    return gridConfig;
  },
});
