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

const { requireAdminApiUserMock, parseDiagnosisAnswersMock, evaluateDiagnosisMock, prismaMock } = vi.hoisted(() => ({
  requireAdminApiUserMock: vi.fn(),
  parseDiagnosisAnswersMock: vi.fn(),
  evaluateDiagnosisMock: vi.fn(),
  prismaMock: {
    legalDiagnosis: {
      findFirst: vi.fn(),
      update: vi.fn(),
    },
    contractRecord: {
      findFirst: vi.fn(),
    },
    legalCase: {
      create: vi.fn(),
    },
  },
}));

vi.mock("@/lib/auth/admin", () => ({
  requireAdminApiUser: requireAdminApiUserMock,
}));

vi.mock("@/lib/legal/diagnosis", () => ({
  parseDiagnosisAnswers: parseDiagnosisAnswersMock,
  evaluateDiagnosis: evaluateDiagnosisMock,
}));

vi.mock("@/lib/prisma", () => ({
  prisma: prismaMock,
}));

import { POST } from "@/app/api/legal/diagnosis/answer/route";

describe("M9 diagnosis contract continuity regression", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("keeps persisted contractId when finalizing diagnosis into legal case", async () => {
    const now = new Date("2026-04-15T11:00:00.000Z");

    requireAdminApiUserMock.mockResolvedValue({ id: "user-1" });
    prismaMock.legalDiagnosis.findFirst.mockResolvedValue({
      id: "diag-1",
      totalSteps: 4,
      legalCaseId: null,
      answersJson: {
        contractId: "contract-1",
        counterparty: "Proveedor SA",
        description: "Incumplimiento de entregable",
      },
    });
    parseDiagnosisAnswersMock.mockReturnValue({ amountAtRisk: 5000 });
    evaluateDiagnosisMock.mockReturnValue({
      suggestedSeverity: "HIGH",
      suggestedCaseType: "CONTRACT_BREACH",
    });
    prismaMock.contractRecord.findFirst.mockResolvedValue({ id: "contract-1" });
    prismaMock.legalCase.create.mockResolvedValue({ id: "case-1" });
    prismaMock.legalDiagnosis.update.mockResolvedValue({
      id: "diag-1",
      legalCaseId: "case-1",
      stepIndex: 4,
      totalSteps: 4,
      answersJson: {
        contractId: "contract-1",
      },
      recommendedRouteJson: {
        suggestedSeverity: "HIGH",
        suggestedCaseType: "CONTRACT_BREACH",
      },
      updatedAt: now,
    });

    const request = new Request("http://localhost/api/legal/diagnosis/answer", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        diagnosisId: "diag-1",
        stepIndex: 3,
        answers: {},
        finalize: true,
      }),
    });

    const response = await POST(request);
    const payload = (await response.json()) as {
      ok?: boolean;
      diagnosis?: {
        legalCaseId: string | null;
      };
    };

    expect(response.status).toBe(200);
    expect(payload.ok).toBe(true);
    expect(payload.diagnosis?.legalCaseId).toBe("case-1");
    expect(prismaMock.contractRecord.findFirst).toHaveBeenCalledWith({
      where: {
        id: "contract-1",
        userId: "user-1",
      },
      select: {
        id: true,
      },
    });
    expect(prismaMock.legalCase.create).toHaveBeenCalledWith(
      expect.objectContaining({
        data: expect.objectContaining({
          contractId: "contract-1",
        }),
      }),
    );
  });
});
