/**
 * Tests: UX Utilities (stagger, vibrate)
 * Läuft im Node-Kontext - kein DOM verfügbar, daher nur Pure-Logic-Tests.
 */
import { test } from 'node:test';
import assert from 'node:assert/strict';

// Minimales Window/Navigator-Mock für Node
const { stagger, vibrate, deleteWithUndo } = await (async () => {
  global.window = {
    matchMedia: () => ({ matches: false }),
    oikos: { showToast: () => {} },
  };
  global.t = (k) => k;
  Object.defineProperty(global, 'navigator', {
    value: { vibrate: null },
    writable: true,
    configurable: true,
  });
  return import('./public/utils/ux.js');
})();

test('stagger: setzt opacity:0 auf alle Elemente', () => {
  const els = [{ style: {} }, { style: {} }, { style: {} }];
  stagger(els, { delay: 0, duration: 0 });
  assert.equal(els[0].style.opacity, '0');
  assert.equal(els[1].style.opacity, '0');
  assert.equal(els[2].style.opacity, '0');
});

test('stagger: tut nichts bei prefers-reduced-motion', () => {
  global.window.matchMedia = () => ({ matches: true });
  const els = [{ style: {} }];
  stagger(els);
  assert.equal(els[0].style.opacity, undefined); // unverändert
  global.window.matchMedia = () => ({ matches: false }); // reset
});

test('vibrate: tut nichts wenn API nicht vorhanden', () => {
  Object.defineProperty(global, 'navigator', { value: { vibrate: null }, writable: true, configurable: true });
  assert.doesNotThrow(() => vibrate(10));
});

test('vibrate: ruft navigator.vibrate auf wenn vorhanden', () => {
  let called = null;
  Object.defineProperty(global, 'navigator', { value: { vibrate: (p) => { called = p; } }, writable: true, configurable: true });
  vibrate(15);
  assert.equal(called, 15);
});

test('deleteWithUndo: ruft onDelete auf', async () => {
  let deleteCalled = false;
  global.window.oikos = { showToast: () => {} };
  await deleteWithUndo({
    onDelete: async () => { deleteCalled = true; },
    toastMessage: 'Gelöscht',
  });
  assert.equal(deleteCalled, true);
});

test('deleteWithUndo: übergibt onUndo an showToast', async () => {
  let undoCalled = false;
  let capturedUndo = null;
  global.window.oikos = {
    showToast: (_msg, _type, _duration, undoFn) => { capturedUndo = undoFn; },
  };
  await deleteWithUndo({
    onDelete: async () => {},
    onUndo: async () => { undoCalled = true; },
    toastMessage: 'Gelöscht',
  });
  assert.ok(capturedUndo, 'showToast muss eine Undo-Funktion erhalten haben');
  await capturedUndo();
  assert.equal(undoCalled, true);
});
