import {
  getSuggestedTypes,
  seedIndustryDefaults,
} from "@/lib/services/appointment-type-seeder";
import { prisma } from "@/lib/db";

// The manual mock at __mocks__/lib/db.js doesn't include appointment_types,
// so we add it here before tests run.
const mockCreateMany = jest.fn();
const mockFindMany = jest.fn();
(prisma as any).appointment_types = {
  createMany: mockCreateMany,
  findMany: mockFindMany,
};

jest.mock("@paralleldrive/cuid2", () => ({
  createId: jest.fn(() => "test-cuid-123"),
}));

describe("getSuggestedTypes", () => {
  it("returns all suggested types when no existing types", () => {
    const result = getSuggestedTypes("dental", []);
    expect(result.length).toBeGreaterThan(0);
    expect(result[0]).toHaveProperty("nameEn");
    expect(result[0]).toHaveProperty("nameAr");
    expect(result[0]).toHaveProperty("duration");
  });

  it("filters out types that already exist by nameEn (case-insensitive)", () => {
    const result = getSuggestedTypes("dental", [
      "Root Canal",
      "TOOTH EXTRACTION",
    ]);
    const names = result.map((t) => t.nameEn.toLowerCase());
    expect(names).not.toContain("root canal");
    expect(names).not.toContain("tooth extraction");
  });

  it("returns other industry suggestions for unknown industry", () => {
    const result = getSuggestedTypes("unknown-industry", []);
    expect(result.length).toBeGreaterThan(0);
  });

  it("returns empty array when all suggested types already exist", () => {
    const allDentalSuggested = getSuggestedTypes("dental", []);
    const allNames = allDentalSuggested.map((t) => t.nameEn);
    const result = getSuggestedTypes("dental", allNames);
    expect(result).toHaveLength(0);
  });
});

describe("seedIndustryDefaults", () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it("creates core appointment types via prisma createMany", async () => {
    mockCreateMany.mockResolvedValue({ count: 3 });

    await seedIndustryDefaults("user-1", "org-1", "dental");

    expect(mockCreateMany).toHaveBeenCalledTimes(1);
    const callArgs = mockCreateMany.mock.calls[0][0];
    expect(callArgs.data).toHaveLength(3); // dental has 3 core types
    expect(callArgs.skipDuplicates).toBe(true);
  });

  it("sets organizationId and createdBy on all created types", async () => {
    mockCreateMany.mockResolvedValue({ count: 3 });

    await seedIndustryDefaults("user-1", "org-1", "dental");

    const callArgs = mockCreateMany.mock.calls[0][0];
    callArgs.data.forEach((type: any) => {
      expect(type.organizationId).toBe("org-1");
      expect(type.createdBy).toBe("user-1");
      expect(type.id).toBeDefined();
    });
  });

  it("falls back to other industry when industry is null", async () => {
    mockCreateMany.mockResolvedValue({ count: 3 });

    await seedIndustryDefaults("user-1", "org-1", null);

    const callArgs = mockCreateMany.mock.calls[0][0];
    expect(callArgs.data.length).toBeGreaterThan(0);
  });
});
