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

const mocks = vi.hoisted(() => ({
  authMock: vi.fn(),
  parseAiChatPayloadMock: vi.fn(),
  createAiChatCompletionMock: vi.fn(),
  getAiErrorMessageMock: vi.fn(),
}))

vi.mock("@/auth", () => ({
  auth: mocks.authMock,
}))

vi.mock("@/shared/lib/ai", () => ({
  parseAiChatPayload: mocks.parseAiChatPayloadMock,
  createAiChatCompletion: mocks.createAiChatCompletionMock,
  getAiErrorMessage: mocks.getAiErrorMessageMock,
}))

import { POST } from "@/app/api/ai/chat/route"

describe("POST /api/ai/chat", () => {
  beforeEach(() => {
    vi.resetAllMocks()
  })

  it("returns 401 when session is missing", async () => {
    mocks.authMock.mockResolvedValue(null)
    const req = new Request("http://localhost/api/ai/chat", {
      method: "POST",
      body: JSON.stringify({ messages: [] }),
      headers: { "Content-Type": "application/json" },
    })

    const response = await POST(req)
    const data = await response.json()

    expect(response.status).toBe(401)
    expect(data).toEqual({ success: false, message: "Unauthorized" })
  })

  it("returns ai response content for valid input", async () => {
    mocks.authMock.mockResolvedValue({ user: { id: "u_1" } })
    mocks.parseAiChatPayloadMock.mockReturnValue({ messages: [{ role: "user", content: "hello" }] })
    mocks.createAiChatCompletionMock.mockResolvedValue({
      content: "mocked-answer",
      usage: { totalTokens: 10, promptTokens: 5, completionTokens: 5 },
    })

    const req = new Request("http://localhost/api/ai/chat", {
      method: "POST",
      body: JSON.stringify({ messages: [{ role: "user", content: "hello" }] }),
      headers: { "Content-Type": "application/json" },
    })

    const response = await POST(req)
    const data = await response.json()

    expect(response.status).toBe(200)
    expect(data.success).toBe(true)
    expect(data.content).toBe("mocked-answer")
    expect(mocks.createAiChatCompletionMock).toHaveBeenCalledTimes(1)
  })

  it("maps invalid payload errors to 400", async () => {
    mocks.authMock.mockResolvedValue({ user: { id: "u_1" } })
    mocks.parseAiChatPayloadMock.mockImplementation(() => {
      throw new Error("bad payload")
    })
    mocks.getAiErrorMessageMock.mockReturnValue("Invalid payload")

    const req = new Request("http://localhost/api/ai/chat", {
      method: "POST",
      body: JSON.stringify({ messages: "bad" }),
      headers: { "Content-Type": "application/json" },
    })

    const response = await POST(req)
    const data = await response.json()

    expect(response.status).toBe(400)
    expect(data).toEqual({ success: false, message: "Invalid payload" })
  })
})
