import { test } from 'node:test';
import assert from 'node:assert/strict';
import { PackImageReader } from './PackImageReader';
import { ImageUsage, PackImage } from './types';

test('fromPackImage returns undefined when url is missing or not a string', () => {
  assert.equal(PackImageReader.fromPackImage('cat', {} as unknown as PackImage), undefined);
  assert.equal(
    PackImageReader.fromPackImage('cat', { url: 123 } as unknown as PackImage),
    undefined,
  );
});

test('fromPackImage builds a reader with shortcode and url', () => {
  const reader = PackImageReader.fromPackImage('cat', { url: 'mxc://x/cat' });
  assert.ok(reader);
  assert.equal(reader?.shortcode, 'cat');
  assert.equal(reader?.url, 'mxc://x/cat');
});

test('body reads only string values', () => {
  assert.equal(PackImageReader.fromPackImage('c', { url: 'u', body: 'Cat' })?.body, 'Cat');
  assert.equal(PackImageReader.fromPackImage('c', { url: 'u' })?.body, undefined);
  assert.equal(
    PackImageReader.fromPackImage('c', { url: 'u', body: 5 } as unknown as PackImage)?.body,
    undefined,
  );
});

test('info is passed through unchanged', () => {
  const info = { w: 10, h: 10 };
  assert.equal(
    PackImageReader.fromPackImage('c', { url: 'u', info } as unknown as PackImage)?.info,
    info,
  );
  assert.equal(PackImageReader.fromPackImage('c', { url: 'u' })?.info, undefined);
});

test('usage filters to known values and returns undefined when none/non-array', () => {
  assert.equal(PackImageReader.fromPackImage('c', { url: 'u' })?.usage, undefined);
  assert.equal(
    PackImageReader.fromPackImage('c', {
      url: 'u',
      usage: 'emoticon' as unknown as ImageUsage[],
    })?.usage,
    undefined,
  );
  assert.equal(
    PackImageReader.fromPackImage('c', {
      url: 'u',
      usage: ['bogus'] as unknown as ImageUsage[],
    })?.usage,
    undefined,
  );
  assert.deepEqual(
    PackImageReader.fromPackImage('c', { url: 'u', usage: [ImageUsage.Sticker] })?.usage,
    [ImageUsage.Sticker],
  );
  assert.deepEqual(
    PackImageReader.fromPackImage('c', {
      url: 'u',
      usage: [ImageUsage.Emoticon, 'x', ImageUsage.Sticker] as unknown as ImageUsage[],
    })?.usage,
    [ImageUsage.Emoticon, ImageUsage.Sticker],
  );
});

test('content reconstructs the PackImage from url and raw image fields', () => {
  const info = { w: 1, h: 1 };
  const reader = PackImageReader.fromPackImage('c', {
    url: 'u',
    body: 'Cat',
    usage: [ImageUsage.Emoticon],
    info,
  } as unknown as PackImage);
  assert.deepEqual(reader?.content, {
    url: 'u',
    body: 'Cat',
    usage: [ImageUsage.Emoticon],
    info,
  });
});

test('content preserves raw usage even when usage getter filters it', () => {
  // content uses the raw image.usage, not the filtered usage getter
  const reader = PackImageReader.fromPackImage('c', {
    url: 'u',
    usage: ['bogus'] as unknown as ImageUsage[],
  });
  assert.deepEqual(reader?.content.usage, ['bogus'] as unknown as ImageUsage[]);
  assert.equal(reader?.usage, undefined);
});
