import { setup, type ActionFunction, type EventObject } from "xstate";

import { getPendingAlbum } from "../helper/albums";
import type { PrivateRoomEvent } from "../private-room-events";
import type { PrivateRoomState } from "../private-room-state";
import {
  loadPrivateAlbumsActor,
  unlockPrivateAlbumActor,
} from "./actors/albums";

export const basePrivateRoomMachineSetup = setup({
  types: {
    context: {} as PrivateRoomState,
    events: {} as PrivateRoomEvent,
  },
  actors: {
    loadAlbums: loadPrivateAlbumsActor,
    unlockAlbum: unlockPrivateAlbumActor,
  },
  guards: {
    hasPendingAlbum: ({ context }) => getPendingAlbum(context) !== null,
  },
});

type PrivateRoomActorAction<TEvent extends EventObject> = ActionFunction<
  PrivateRoomState,
  TEvent,
  PrivateRoomEvent,
  undefined,
  never,
  never,
  never,
  never,
  never
>;

export function createPrivateRoomActorActionSetup<
  TEvent extends EventObject,
>() {
  const actorActionSetup = setup({
    types: {
      context: {} as PrivateRoomState,
      events: {} as TEvent,
    },
  });
  return {
    assign(
      assignment: Parameters<typeof actorActionSetup.assign>[0],
    ): PrivateRoomActorAction<TEvent> {
      return actorActionSetup.assign(
        assignment,
      ) as unknown as PrivateRoomActorAction<TEvent>;
    },
  };
}
