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

vi.mock("@capakraken/application", async (importOriginal) => {
  const actual = await importOriginal<typeof import("@capakraken/application")>();
  return {
    ...actual,
    getDashboardBudgetForecast: vi.fn().mockResolvedValue([]),
    getDashboardPeakTimes: vi.fn().mockResolvedValue([]),
    listAssignmentBookings: vi.fn().mockResolvedValue([]),
  };
});

import { executeTool } from "../router/assistant-tools.js";
import { createToolContext, withUserLookup } from "./assistant-tools-notification-test-helpers.js";

describe("assistant reminder mutation tools - success", () => {
  it("parses reminder datetimes and forwards optional reminder fields", async () => {
    const db = withUserLookup({
      notification: {
        create: vi.fn().mockResolvedValue({
          id: "rem_1",
          title: "Check holiday setup",
          category: "REMINDER",
        }),
      },
    });
    const ctx = createToolContext(db, SystemRole.USER);

    const result = await executeTool(
      "create_reminder",
      JSON.stringify({
        title: "Check holiday setup",
        body: "Compare Bavaria and Hamburg",
        remindAt: "2026-05-02T10:15:00.000Z",
        recurrence: "monthly",
        entityId: "calendar_1",
        entityType: "HOLIDAY_CALENDAR",
        link: "/holidays",
      }),
      ctx,
    );

    expect(db.notification.create).toHaveBeenCalledWith({
      data: {
        userId: "user_1",
        type: "REMINDER",
        category: "REMINDER",
        title: "Check holiday setup",
        body: "Compare Bavaria and Hamburg",
        remindAt: new Date("2026-05-02T10:15:00.000Z"),
        nextRemindAt: new Date("2026-05-02T10:15:00.000Z"),
        recurrence: "monthly",
        entityId: "calendar_1",
        entityType: "HOLIDAY_CALENDAR",
        link: "/holidays",
        channel: "in_app",
      },
    });
    expect(result.action).toEqual({ type: "invalidate", scope: ["notification"] });
    expect(result.data).toEqual(
      expect.objectContaining({
        success: true,
        reminderId: "rem_1",
        message: 'Reminder "Check holiday setup" created.',
      }),
    );
  });

  it("updates reminders through the real router path and invalidates notification queries", async () => {
    const remindAt = new Date("2026-05-01T07:00:00.000Z");
    const db = withUserLookup({
      notification: {
        findFirst: vi.fn().mockResolvedValue({
          id: "rem_1",
          userId: "user_1",
          category: "REMINDER",
        }),
        update: vi.fn().mockResolvedValue({
          id: "rem_1",
          title: "Updated reminder",
          remindAt,
          nextRemindAt: remindAt,
          recurrence: null,
        }),
      },
    });
    const ctx = createToolContext(db, SystemRole.USER);

    const result = await executeTool(
      "update_reminder",
      JSON.stringify({
        id: "rem_1",
        title: "Updated reminder",
        remindAt: "2026-05-01T07:00:00.000Z",
        recurrence: null,
      }),
      ctx,
    );

    expect(db.notification.findFirst).toHaveBeenCalledWith({
      where: { id: "rem_1", userId: "user_1", category: "REMINDER" },
    });
    expect(db.notification.update).toHaveBeenCalledWith({
      where: { id: "rem_1" },
      data: {
        title: "Updated reminder",
        remindAt,
        nextRemindAt: remindAt,
        recurrence: null,
      },
    });
    expect(result.action).toEqual({ type: "invalidate", scope: ["notification"] });
    expect(result.data).toEqual(
      expect.objectContaining({
        success: true,
        reminderId: "rem_1",
        message: "Updated reminder rem_1.",
        reminder: expect.objectContaining({
          id: "rem_1",
          title: "Updated reminder",
          recurrence: null,
        }),
      }),
    );
  });

  it("deletes reminders through the router and returns notification invalidation metadata", async () => {
    const db = withUserLookup({
      notification: {
        findFirst: vi.fn().mockResolvedValue({
          id: "rem_1",
          userId: "user_1",
          category: "REMINDER",
        }),
        delete: vi.fn().mockResolvedValue({ id: "rem_1" }),
      },
    });
    const ctx = createToolContext(db, SystemRole.USER);

    const result = await executeTool(
      "delete_reminder",
      JSON.stringify({ id: "rem_1" }),
      ctx,
    );

    expect(db.notification.delete).toHaveBeenCalledWith({ where: { id: "rem_1" } });
    expect(result.action).toEqual({ type: "invalidate", scope: ["notification"] });
    expect(result.data).toEqual({
      success: true,
      id: "rem_1",
      message: "Deleted reminder rem_1.",
    });
  });
});
