import { describe, expect, it } from "vitest";
import { createActor, waitFor } from "xstate";

import { createTestChatMachine } from "./chat-machine.test-utils";

describe("chat session flow", () => {
  it("keeps guest logout disabled and supports user to guest transition", async () => {
    const actor = createActor(createTestChatMachine()).start();

    actor.send({ type: "ChatGuestLogin" });
    await waitFor(actor, (snapshot) =>
      snapshot.matches({ guestSession: "ready" }),
    );

    actor.send({ type: "ChatLogout" });
    expect(actor.getSnapshot().matches({ guestSession: "ready" })).toBe(true);

    actor.send({ type: "ChatUserLogin", token: "token" });
    await waitFor(actor, (snapshot) =>
      snapshot.matches({ userSession: "ready" }),
    );

    actor.send({ type: "ChatGuestLogin" });
    await waitFor(actor, (snapshot) =>
      snapshot.matches({ guestSession: "ready" }),
    );

    actor.stop();
  });

  it("allows explicit logout from user session", async () => {
    const actor = createActor(createTestChatMachine()).start();

    actor.send({ type: "ChatUserLogin", token: "token" });
    await waitFor(actor, (snapshot) =>
      snapshot.matches({ userSession: "ready" }),
    );

    actor.send({ type: "ChatLogout" });
    expect(actor.getSnapshot().matches("idle")).toBe(true);

    actor.stop();
  });

  it("keeps a promotion separate from normal history", async () => {
    const actor = createActor(
      createTestChatMachine({
        historyMessages: [
          {
            id: "history-1",
            content: "Existing history",
            isFromAI: true,
            date: "2026-07-13",
          },
        ],
      }),
    ).start();

    actor.send({ type: "ChatUserLogin", token: "token" });
    await waitFor(actor, (snapshot) =>
      snapshot.matches({ userSession: "ready" }),
    );
    actor.send({
      type: "ChatPromotionInjected",
      promotion: {
        promotionType: "voice",
        lockType: "voice_message",
        clientLockId: "promotion-1",
        createdAt: 1,
      },
    });

    const context = actor.getSnapshot().context;
    expect(context.messages).toHaveLength(1);
    expect(context.promotion?.message).toMatchObject({
      id: "promotion:promotion-1",
      locked: true,
      lockReason: "voice_message",
    });

    actor.stop();
  });

  it("switches to guest session when guest login arrives during user session", async () => {
    const actor = createActor(createTestChatMachine()).start();

    actor.send({ type: "ChatUserLogin", token: "token" });
    await waitFor(actor, (snapshot) =>
      snapshot.matches({ userSession: "ready" }),
    );

    actor.send({ type: "ChatGuestLogin" });
    await waitFor(actor, (snapshot) =>
      snapshot.matches({ guestSession: "ready" }),
    );

    actor.stop();
  });

  it("ignores repeated user login while an authenticated user session is active", async () => {
    const actor = createActor(createTestChatMachine()).start();

    actor.send({ type: "ChatUserLogin", token: "token" });
    await waitFor(actor, (snapshot) =>
      snapshot.matches({ userSession: "ready" }),
    );

    actor.send({ type: "ChatSendMessage", content: "keep this message" });
    await waitFor(
      actor,
      (snapshot) => snapshot.context.messages.length === 1,
    );

    actor.send({ type: "ChatUserLogin", token: "another-token" });

    expect(actor.getSnapshot().matches({ userSession: "ready" })).toBe(true);
    expect(actor.getSnapshot().context.messages).toMatchObject([
      { content: "keep this message", isFromAI: false },
    ]);

    actor.stop();
  });
});
