import { describe, expect, it, vi } from "vitest";

import { ChatRemoteDataSource } from "../chat_remote_data_source";
import { SendMessageRequestSchema } from "@/data/schemas/chat";


describe("chat send clientMessageId", () => {
  it("keeps legacy requests compatible but validates an explicit UUID", () => {
    expect(
      SendMessageRequestSchema.parse({ characterId: "elio", message: "hello" })
        .clientMessageId,
    ).toBeUndefined();
    expect(() =>
      SendMessageRequestSchema.parse({
        characterId: "elio",
        message: "hello",
        clientMessageId: "not-a-uuid",
      }),
    ).toThrow();
  });

  it("adds one UUID before the HTTP client owns any retry", async () => {
    const sendMessage = vi.fn().mockResolvedValue({
      reply: "hi",
      messageId: "server-message-1",
      image: { type: null, url: null },
      lockDetail: { locked: false, reason: null },
    });
    const source = new ChatRemoteDataSource({ sendMessage } as never);

    await source.sendMessage("elio", "hello");

    const request = sendMessage.mock.calls[0][0];
    expect(request.clientMessageId).toMatch(
      /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,
    );
  });

  it("reuses an explicitly supplied key for a protocol fallback", async () => {
    const sendMessage = vi.fn().mockResolvedValue({
      reply: "hi",
      messageId: "server-message-1",
      image: { type: null, url: null },
      lockDetail: { locked: false, reason: null },
    });
    const source = new ChatRemoteDataSource({ sendMessage } as never);
    const clientMessageId = "11111111-1111-4111-8111-111111111111";

    await source.sendMessage("elio", "hello", { clientMessageId, useWebSocket: false });
    await source.sendMessage("elio", "hello", { clientMessageId, useWebSocket: true });

    expect(sendMessage.mock.calls.map(([request]) => request.clientMessageId)).toEqual([
      clientMessageId,
      clientMessageId,
    ]);
  });
});
