import { test } from 'node:test';
import assert from 'node:assert/strict';
import { createStore } from 'jotai';
import { allRoomsAtom } from './roomList';

// allRoomsAtom wraps an unexported baseRoomsAtom string[] reducer:
//   INITIALIZE -> replace wholesale
//   PUT        -> filter-out-then-push (move-to-end dedupe)
//   DELETE     -> filter-out
// We drive the reducer through a jotai store. The React binding hook
// (useBindAllRoomsAtom) wires this to MatrixClient events and is not covered.

const R1 = '!r1:server';
const R2 = '!r2:server';
const R3 = '!r3:server';

test('starts empty', () => {
  const store = createStore();
  assert.deepEqual(store.get(allRoomsAtom), []);
});

test('INITIALIZE replaces the whole list', () => {
  const store = createStore();
  store.set(allRoomsAtom, { type: 'PUT', roomId: R1 });
  store.set(allRoomsAtom, { type: 'INITIALIZE', rooms: [R2, R3] });
  assert.deepEqual(store.get(allRoomsAtom), [R2, R3]);
});

test('PUT appends a new room', () => {
  const store = createStore();
  store.set(allRoomsAtom, { type: 'PUT', roomId: R1 });
  store.set(allRoomsAtom, { type: 'PUT', roomId: R2 });
  assert.deepEqual(store.get(allRoomsAtom), [R1, R2]);
});

test('PUT of an existing room moves it to the end (dedupe)', () => {
  const store = createStore();
  store.set(allRoomsAtom, { type: 'INITIALIZE', rooms: [R1, R2, R3] });
  store.set(allRoomsAtom, { type: 'PUT', roomId: R1 });
  assert.deepEqual(store.get(allRoomsAtom), [R2, R3, R1]);
});

test('DELETE removes a room', () => {
  const store = createStore();
  store.set(allRoomsAtom, { type: 'INITIALIZE', rooms: [R1, R2, R3] });
  store.set(allRoomsAtom, { type: 'DELETE', roomId: R2 });
  assert.deepEqual(store.get(allRoomsAtom), [R1, R3]);
});

test('DELETE of an absent room is a no-op', () => {
  const store = createStore();
  store.set(allRoomsAtom, { type: 'INITIALIZE', rooms: [R1] });
  store.set(allRoomsAtom, { type: 'DELETE', roomId: R2 });
  assert.deepEqual(store.get(allRoomsAtom), [R1]);
});
