import assert from 'node:assert/strict';
import { test } from 'node:test';
import { clonePackDestinations, editableChoices, packSlug, shortcodeFor, stickersOf } from '../src/lib/packs.ts';

const image = (shortcode: string, usage: ('Emoticon' | 'Sticker')[]) => ({
  shortcode,
  media_id: `mxc://x/${shortcode}`,
  reaction_key: `mxc://x/${shortcode}`,
  body: null,
  mimetype: null,
  width: null,
  height: null,
  usage
});

const roomPack = (state_key: string, editable: boolean) => ({
  id: `room:!r:x:${state_key}`,
  display_name: state_key,
  avatar: null,
  attribution: null,
  source: { Room: { room_id: '!r:x', state_key } },
  images: [image('a', ['Sticker']), image('b', ['Emoticon']), image('c', [])],
  editable,
  enabled_everywhere: false
});

test('shortcodes come from file names and never clash', () => {
  const taken = new Set(['cat']);
  assert.equal(shortcodeFor('Cat.PNG', taken), 'cat_2');
  assert.equal(shortcodeFor('my cool sticker!.webp', taken), 'my_cool_sticker');
  assert.equal(shortcodeFor('.png', taken), 'image');
  assert.equal(packSlug('Cats & Dogs'), 'cats-dogs');
});

test('stickers include images with no usage of their own', () => {
  assert.deepEqual(stickersOf(roomPack('s', true)).map((i) => i.shortcode), ['a', 'c']);
});

test('your pack is always a destination, then editable room packs only', () => {
  const packs = { global: [], rooms: { '!r:x': [roomPack('mine', true), roomPack('theirs', false)] } };
  const choices = editableChoices(packs, () => 'Room');
  assert.deepEqual(choices.map((c) => c.target), [{ kind: 'user' }, { kind: 'room', room_id: '!r:x', state_key: 'mine' }]);
  const dests = clonePackDestinations(roomPack('Fancy Pack', false), [{ room_id: '!d:x', name: 'Dest' }], () => 'Room');
  assert.deepEqual(dests[1].target, { kind: 'room', room_id: '!d:x', state_key: 'fancy-pack' });
});
