import assert from 'node:assert/strict';
import test from 'node:test';

import type { Scene, SceneId } from '../types';

import {
  defaultSceneListOrder,
  moveSceneInListOrder,
  prependSceneListOrder,
  reconcileSceneListOrder,
  removeFromSceneListOrder,
} from './sceneListOrder';

function scene(id: string): Scene {
  return {
    id: id as SceneId,
    title: id,
    description: '',
    previewAssetId: null,
    previewThumbAssetId: null,
    previewAssetType: null,
    previewVideoAutostart: false,
    previewRotationDeg: 0,
    darkenScene: false,
    traps: [],
    tokens: [],
    npcTokens: [],
    grid: { enabled: false, type: 'square', sizeN: 0.06, color: '#ffffff' },
    media: { videos: [], audios: [] },
    settings: { autoplayVideo: false, autoplayAudio: true, loopVideo: true, loopAudio: true },
    connections: [],
    layout: { x: 0, y: 0 },
  };
}

void test('defaultSceneListOrder sorts by id timestamp newest first', () => {
  const scenes = {
    scene_a_100: scene('scene_a_100'),
    scene_b_200: scene('scene_b_200'),
    scene_c_150: scene('scene_c_150'),
  } as Record<SceneId, Scene>;
  assert.deepEqual(defaultSceneListOrder(scenes), ['scene_b_200', 'scene_c_150', 'scene_a_100']);
});

void test('reconcileSceneListOrder drops missing and appends new', () => {
  const scenes = {
    a: scene('a'),
    b: scene('b'),
    c: scene('c'),
  } as Record<SceneId, Scene>;
  assert.deepEqual(reconcileSceneListOrder(scenes, ['b', 'gone', 'a'] as SceneId[]), ['b', 'a', 'c']);
});

void test('moveSceneInListOrder before/after', () => {
  const order = ['a', 'b', 'c', 'd'] as SceneId[];
  assert.deepEqual(moveSceneInListOrder(order, 'd' as SceneId, 'b' as SceneId, 'before'), [
    'a',
    'd',
    'b',
    'c',
  ]);
  assert.deepEqual(moveSceneInListOrder(order, 'a' as SceneId, 'c' as SceneId, 'after'), [
    'b',
    'c',
    'a',
    'd',
  ]);
  assert.deepEqual(moveSceneInListOrder(order, 'b' as SceneId, 'b' as SceneId, 'before'), [
    'a',
    'b',
    'c',
    'd',
  ]);
});

void test('prepend and remove helpers', () => {
  const order = ['a', 'b'] as SceneId[];
  assert.deepEqual(prependSceneListOrder(order, 'c' as SceneId), ['c', 'a', 'b']);
  assert.deepEqual(prependSceneListOrder(order, 'a' as SceneId), ['a', 'b']);
  assert.deepEqual(removeFromSceneListOrder(order, 'a' as SceneId), ['b']);
});
