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

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

describe("assistant metro city mutation tools - success", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("creates, updates, and deletes metro cities for admin users", async () => {
    const create = vi.fn().mockResolvedValue({
      id: "city_muc",
      name: "Munich",
      countryId: "country_de",
    });
    const findUnique = vi.fn()
      .mockResolvedValueOnce({ id: "city_muc", name: "Munich", countryId: "country_de" })
      .mockResolvedValueOnce({ id: "city_muc", name: "Munich", _count: { resources: 0 } });
    const update = vi.fn().mockResolvedValue({
      id: "city_muc",
      name: "Muenchen",
      countryId: "country_de",
    });
    const remove = vi.fn().mockResolvedValue({ id: "city_muc" });
    const ctx = createToolContext({
      country: {
        findUnique: vi.fn().mockResolvedValue({ id: "country_de", name: "Germany" }),
      },
      metroCity: {
        create,
        findUnique,
        update,
        delete: remove,
      },
    });

    const createResult = await executeTool(
      "create_metro_city",
      JSON.stringify({ countryId: "country_de", name: "Munich" }),
      ctx,
    );
    const updateResult = await executeTool(
      "update_metro_city",
      JSON.stringify({ id: "city_muc", data: { name: "Muenchen" } }),
      ctx,
    );
    const deleteResult = await executeTool(
      "delete_metro_city",
      JSON.stringify({ id: "city_muc" }),
      ctx,
    );

    expect(create).toHaveBeenCalledWith({
      data: { name: "Munich", countryId: "country_de" },
    });
    expect(update).toHaveBeenCalledWith({
      where: { id: "city_muc" },
      data: { name: "Muenchen" },
    });
    expect(remove).toHaveBeenCalledWith({ where: { id: "city_muc" } });
    expect(createResult.action).toEqual({
      type: "invalidate",
      scope: ["country", "resource", "holidayCalendar", "vacation"],
    });
    expect(updateResult.action).toEqual({
      type: "invalidate",
      scope: ["country", "resource", "holidayCalendar", "vacation"],
    });
    expect(deleteResult.action).toEqual({
      type: "invalidate",
      scope: ["country", "resource", "holidayCalendar", "vacation"],
    });
    expect(createResult.data).toMatchObject({
      success: true,
      message: "Created metro city: Munich",
      metroCity: { id: "city_muc", name: "Munich" },
    });
    expect(updateResult.data).toMatchObject({
      success: true,
      message: "Updated metro city: Muenchen",
      metroCity: { id: "city_muc", name: "Muenchen" },
    });
    expect(deleteResult.data).toMatchObject({
      success: true,
      message: "Deleted metro city: Munich",
    });
  });

  it("deletes metro cities only when no resources are assigned", async () => {
    const ctx = createToolContext({
      metroCity: {
        findUnique: vi.fn().mockResolvedValue({
          id: "city_ham",
          name: "Hamburg",
          _count: { resources: 0 },
        }),
        delete: vi.fn().mockResolvedValue(undefined),
      },
    });

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

    expect(result.action).toEqual({
      type: "invalidate",
      scope: ["country", "resource", "holidayCalendar", "vacation"],
    });
    expect(result.data).toMatchObject({
      success: true,
      message: "Deleted metro city: Hamburg",
    });
  });
});
