import { createActor, fromPromise, waitFor } from "xstate";

import {
  PrivateAlbumsResponse,
  PrivateAlbumUnlockResponse,
} from "@/data/dto/private-room";
import { privateRoomMachine } from "@/stores/private-room/private-room-machine";

export const ALBUM_ID = "a1b2c3d4-0000-0000-0000-000000000000";
export const COVER_URL =
  "https://dbapi.banlv-ai.com/storage/v1/object/public/elio-schedules/01.jpg";

export function makeAlbum(index = 0) {
  return {
    albumId: index === 0 ? ALBUM_ID : `album-${index}`,
    title: `Private album ${index + 1}`,
    content: null,
    previewText: "Only for you.",
    imageCount: 8,
    images: [{ url: `${COVER_URL}?album=${index}`, locked: true, index: 0 }],
    locked: true,
    unlocked: false,
    unlockCost: 320,
    publishedAt: "2026-07-13T00:00:00+00:00",
    lockDetail: { locked: true },
  };
}

export function makeAlbumsResponse(
  overrides: Partial<Parameters<typeof PrivateAlbumsResponse.from>[0]> = {},
): PrivateAlbumsResponse {
  return PrivateAlbumsResponse.from({
    items: [makeAlbum()],
    creditBalance: 500,
    ...overrides,
  });
}

export function makeUnlockResponse(
  overrides: Partial<Parameters<typeof PrivateAlbumUnlockResponse.from>[0]> = {},
): PrivateAlbumUnlockResponse {
  return PrivateAlbumUnlockResponse.from({
    albumId: ALBUM_ID,
    locked: false,
    unlocked: true,
    reason: "ok",
    unlockCost: 320,
    requiredCredits: 320,
    creditBalance: 180,
    shortfallCredits: 0,
    images: Array.from({ length: 8 }, (_, index) => ({
      url: `${COVER_URL}?image=${index}`,
      locked: false,
      index,
    })),
    ...overrides,
  });
}

export function createTestPrivateRoomMachine(options: {
  loadResponse?: PrivateAlbumsResponse;
  unlockResponse?: PrivateAlbumUnlockResponse;
  loadError?: Error;
  unlockError?: Error;
  onLoad?: () => void;
} = {}) {
  return privateRoomMachine.provide({
    actors: {
      loadAlbums: fromPromise(async () => {
        options.onLoad?.();
        if (options.loadError) throw options.loadError;
        return options.loadResponse ?? makeAlbumsResponse();
      }),
      unlockAlbum: fromPromise(async () => {
        if (options.unlockError) throw options.unlockError;
        return options.unlockResponse ?? makeUnlockResponse();
      }),
    },
  });
}

export async function loadPrivateRoom(
  options: Parameters<typeof createTestPrivateRoomMachine>[0] = {},
) {
  const actor = createActor(createTestPrivateRoomMachine(options)).start();
  actor.send({ type: "PrivateRoomInit" });
  await waitFor(actor, (snapshot) => snapshot.matches("ready"));
  return actor;
}

export async function unlockFirstAlbum(
  actor: Awaited<ReturnType<typeof loadPrivateRoom>>,
) {
  actor.send({
    type: "PrivateRoomUnlockRequested",
    albumId: ALBUM_ID,
  });
  actor.send({ type: "PrivateRoomUnlockConfirmed" });
  await waitFor(actor, (snapshot) => snapshot.matches("ready"));
}
