import { beforeEach, describe, expect, it, vi } from "vitest";
import { SystemRole } from "@capakraken/shared";

import { executeTool } from "./assistant-tools-broadcast-send-test-helpers.js";
import { createToolContext } from "./assistant-tools-notification-test-helpers.js";

describe("assistant broadcast send recipient fan-out errors", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns a stable assistant error when broadcast recipient user is missing", async () => {
    const ctx = createToolContext(
      {
        notificationBroadcast: {
          create: vi.fn().mockResolvedValue({
            id: "broadcast_missing_user",
            title: "Office update",
            targetType: "user",
          }),
        },
        notification: {
          create: vi.fn().mockRejectedValue({
            code: "P2003",
            message: "Foreign key constraint failed",
            meta: { field_name: "Notification_userId_fkey" },
          }),
        },
      },
      SystemRole.MANAGER,
    );

    const result = await executeTool(
      "send_broadcast",
      JSON.stringify({
        title: "Office update",
        targetType: "user",
        targetValue: "user_missing",
      }),
      ctx,
    );

    expect(JSON.parse(result.content)).toEqual({
      error: "Broadcast recipient user not found with the given criteria.",
    });
  });

  it("returns a stable assistant error when broadcast fan-out loses recipient rows inside the router transaction", async () => {
    const recipientMissingTx = {
      notificationBroadcast: {
        create: vi.fn().mockResolvedValue({
          id: "broadcast_missing_recipient",
          title: "Office update",
          targetType: "all",
        }),
        update: vi.fn(),
      },
      notification: {
        create: vi.fn().mockRejectedValue(
          Object.assign(new Error("Foreign key constraint failed"), {
            code: "P2003",
            meta: { field_name: "Notification_userId_fkey" },
          }),
        ),
      },
    };
    const recipientMissingCtx = createToolContext(
      {
        user: {
          findMany: vi.fn().mockResolvedValue([{ id: "user_2" }]),
        },
        $transaction: vi.fn(async (callback: (db: typeof recipientMissingTx) => Promise<unknown>) =>
          callback(recipientMissingTx)),
        notificationBroadcast: {
          create: vi.fn(),
          update: vi.fn(),
        },
        notification: {
          create: vi.fn(),
        },
      },
      SystemRole.MANAGER,
    );

    const recipientMissingResult = await executeTool(
      "send_broadcast",
      JSON.stringify({
        title: "Office update",
        targetType: "all",
      }),
      recipientMissingCtx,
    );

    expect(JSON.parse(recipientMissingResult.content)).toEqual({
      error: "Broadcast recipient user not found with the given criteria.",
    });
  });
});
