import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import test from 'node:test';

import { PlayersStore } from './playersStore';
import { asPlayerId } from '../../shared/types/ids';

async function withTempStore(run: (store: PlayersStore, root: string) => Promise<void>) {
  const root = await fs.mkdtemp(path.join(os.tmpdir(), 'dnd-players-'));
  const store = new PlayersStore(root);
  try {
    await run(store, root);
  } finally {
    await fs.rm(root, { recursive: true, force: true });
  }
}

void test('PlayersStore upsert list delete and teams', async () => {
  await withTempStore(async (store, root) => {
    const png = path.join(root, 'sample.png');
    // minimal 1x1 png
    const buf = Buffer.from(
      'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==',
      'base64',
    );
    await fs.writeFile(png, buf);

    const progress: number[] = [];
    const player = await store.upsert(
      { name: 'Ada', filePath: png, ringColor: '#112233', imageOffset: { x: 0.1, y: -0.1 } },
      (p) => progress.push(p.percent),
    );
    assert.equal(player.name, 'Ada');
    assert.equal(player.ringColor, '#112233');
    assert.ok(progress.length > 0);
    assert.equal(store.listPlayers().length, 1);

    const team = await store.upsertTeam({ name: 'Party', color: '#abcdef' });
    assert.equal(team.name, 'Party');
    const assigned = await store.assignPlayerTeam(player.id, team.id);
    assert.equal(assigned?.teamId, team.id);

    await store.deleteTeam(team.id);
    assert.equal(store.listTeams().length, 0);
    assert.equal(store.getById(player.id)?.teamId, null);

    await store.delete(player.id);
    assert.equal(store.listPlayers().length, 0);
  });
});

void test('PlayersStore persists across reload', async () => {
  await withTempStore(async (store, root) => {
    const png = path.join(root, 'sample.png');
    await fs.writeFile(
      png,
      Buffer.from(
        'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==',
        'base64',
      ),
    );
    const created = await store.upsert({ name: 'Bob', filePath: png });
    const store2 = new PlayersStore(root);
    await store2.ensureLoaded();
    assert.equal(store2.listPlayers().length, 1);
    assert.equal(store2.getById(asPlayerId(created.id))?.name, 'Bob');
  });
});
