import { beforeEach, describe, expect, it, vi } from "vitest";
import { POST } from "./route";

const mocks = vi.hoisted(() => {
  return {
    createClient: vi.fn(),
    getCompanyContext: vi.fn(),
    canCompany: vi.fn(),
  };
});

vi.mock("@/lib/supabase-server", () => ({
  createClient: mocks.createClient,
}));

vi.mock("@/lib/company-context", () => ({
  getCompanyContext: mocks.getCompanyContext,
  canCompany: mocks.canCompany,
}));

describe("POST /api/commissions/adjustments", () => {
  const rpc = vi.fn();
  const getUser = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();

    mocks.createClient.mockResolvedValue({
      auth: {
        getUser,
      },
      rpc,
    });

    getUser.mockResolvedValue({
      data: {
        user: {
          id: "user-1",
        },
      },
    });

    mocks.getCompanyContext.mockResolvedValue({
      companyId: "company-1",
    });

    mocks.canCompany.mockReturnValue(true);
    rpc.mockResolvedValue({ data: { adjustment_id: "adj-1" }, error: null });
  });

  it("bloqueia ajuste com valor zero sem chamar RPC", async () => {
    const response = await POST(
      new Request("http://localhost/api/commissions/adjustments", {
        method: "POST",
        body: JSON.stringify({
          event_id: "event-1",
          amount: "0,00",
          reason: "Correção",
        }),
      })
    );

    expect(response.status).toBe(400);
    await expect(response.json()).resolves.toEqual({
      error: "Informe um valor de ajuste diferente de zero.",
    });
    expect(rpc).not.toHaveBeenCalled();
  });

  it("bloqueia ajuste sem motivo", async () => {
    const response = await POST(
      new Request("http://localhost/api/commissions/adjustments", {
        method: "POST",
        body: JSON.stringify({
          event_id: "event-1",
          amount: "15,50",
          reason: "   ",
        }),
      })
    );

    expect(response.status).toBe(400);
    await expect(response.json()).resolves.toEqual({
      error: "Informe o motivo do ajuste.",
    });
    expect(rpc).not.toHaveBeenCalled();
  });

  it("normaliza valor e chama a RPC com os dados corretos", async () => {
    const response = await POST(
      new Request("http://localhost/api/commissions/adjustments", {
        method: "POST",
        body: JSON.stringify({
          event_id: "event-1",
          amount: "15,50",
          reason: "Ajuste manual",
        }),
      })
    );

    expect(response.status).toBe(200);
    expect(rpc).toHaveBeenCalledWith("adjust_commission_event", {
      p_event_id: "event-1",
      p_amount: 15.5,
      p_reason: "Ajuste manual",
      p_company_id: "company-1",
    });
    await expect(response.json()).resolves.toMatchObject({
      ok: true,
      message: "Ajuste de comissão registrado com sucesso.",
    });
  });
});
