import { test } from 'node:test';
import assert from 'node:assert/strict';
import { upsertPreset, normalizeLabel, StatusPreset } from './statusPresets';

const p = (id: string, label: string, clearAfter = '0'): StatusPreset => ({
  id,
  label,
  clearAfter,
});

test('normalizeLabel trims and lowercases', () => {
  assert.equal(normalizeLabel('  🎮 Gaming  '), '🎮 gaming');
  assert.equal(normalizeLabel('AFK'), 'afk');
});

test('upsertPreset prepends a new preset', () => {
  const list = [p('1', 'a'), p('2', 'b')];
  const out = upsertPreset(list, p('3', 'c'));
  assert.deepEqual(
    out.map((x) => x.id),
    ['3', '1', '2'],
  );
});

test('upsertPreset de-dupes by normalized label, moving the entry to the front', () => {
  const list = [p('1', 'Gaming'), p('2', 'b'), p('3', 'c')];
  // Same label (different case/whitespace) → old entry removed, new one at front.
  const out = upsertPreset(list, p('9', '  gaming '));
  assert.deepEqual(
    out.map((x) => x.id),
    ['9', '2', '3'],
  );
  assert.equal(out.filter((x) => normalizeLabel(x.label) === 'gaming').length, 1);
});

test('upsertPreset enforces the cap, dropping the oldest', () => {
  const list = Array.from({ length: 20 }, (_, i) => p(String(i), `label-${i}`));
  const out = upsertPreset(list, p('new', 'fresh'), 20);
  assert.equal(out.length, 20);
  assert.equal(out[0].id, 'new');
  // The last (oldest) entry, id '19', is dropped.
  assert.equal(
    out.some((x) => x.id === '19'),
    false,
  );
});

test('upsertPreset does not mutate its input', () => {
  const list = [p('1', 'a'), p('2', 'b')];
  const before = list.map((x) => x.id);
  upsertPreset(list, p('3', 'c'));
  assert.deepEqual(
    list.map((x) => x.id),
    before,
  );
});
