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

import type { Project } from '../../../shared/types';
import type { AssetId, SceneId } from '../../../shared/types/ids';

import { buildNextSceneCardById } from './sceneCardById';

function minimalProject(overrides: Partial<Project>): Project {
  return {
    id: 'p1' as unknown as Project['id'],
    meta: {
      name: 'n',
      fileBaseName: 'f',
      createdAt: '',
      updatedAt: '',
      createdWithAppVersion: '1',
      appVersion: '1',
      schemaVersion: 1 as unknown as Project['meta']['schemaVersion'],
    },
    scenes: {},
    sceneListOrder: [],
    assets: {},
    campaignAudios: [],
    materials: [],
    npcs: [],
    npcRelations: [],
    currentSceneId: null,
    currentGraphNodeId: null,
    sceneGraphNodes: [],
    sceneGraphEdges: [],
    ...overrides,
  } as unknown as Project;
}

void test('buildNextSceneCardById: does not change refs when irrelevant fields change', () => {
  const sid = 's1' as SceneId;
  const base = minimalProject({
    scenes: {
      [sid]: {
        id: sid,
        title: 'T',
        description: 'A',
        media: { videos: [], audios: [{ assetId: 'a1' as AssetId, autoplay: false, loop: true }] },
        settings: { autoplayVideo: false, autoplayAudio: false, loopVideo: false, loopAudio: false },
        connections: [],
        layout: { x: 0, y: 0 },
        previewAssetId: null,
        previewThumbAssetId: null,
        previewAssetType: null,
        previewVideoAutostart: false,
        previewRotationDeg: 0,
      },
    } as unknown as Project['scenes'],
  });

  const first = buildNextSceneCardById({}, base);
  const card1 = first[sid];
  assert.ok(card1);

  const changedOnlyDescription = minimalProject({
    ...base,
    scenes: {
      ...base.scenes,
      [sid]: { ...base.scenes[sid], description: 'B' },
    },
  });
  const second = buildNextSceneCardById(first, changedOnlyDescription);

  assert.equal(second, first, 'record identity should be reused');
  assert.equal(second[sid], card1, 'card identity should be reused');
});

void test('buildNextSceneCardById: changes card when title changes', () => {
  const sid = 's1' as SceneId;
  const base = minimalProject({
    scenes: {
      [sid]: {
        id: sid,
        title: 'T',
        description: '',
        media: { videos: [], audios: [] },
        settings: { autoplayVideo: false, autoplayAudio: false, loopVideo: false, loopAudio: false },
        connections: [],
        layout: { x: 0, y: 0 },
        previewAssetId: null,
        previewThumbAssetId: null,
        previewAssetType: null,
        previewVideoAutostart: false,
        previewRotationDeg: 0,
      },
    } as unknown as Project['scenes'],
  });
  const first = buildNextSceneCardById({}, base);
  const card1 = first[sid];

  const changedTitle = minimalProject({
    ...base,
    scenes: {
      ...base.scenes,
      [sid]: { ...base.scenes[sid], title: 'T2' },
    },
  });
  const second = buildNextSceneCardById(first, changedTitle);

  assert.notEqual(second[sid], card1);
});
