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

vi.mock("@/lib/db", () => ({
  db: {
    marketplaceUsageEvent: {
      create: vi.fn(),
    },
  },
}));

vi.mock("@/lib/logger", () => ({
  logger: { info: vi.fn(), error: vi.fn() },
}));

const mockRecordBillingEvent = vi.fn();
vi.mock("@/lib/marketplace-billing", () => ({
  recordBillingEvent: (...args: unknown[]) => mockRecordBillingEvent(...args),
}));

import { db } from "@/lib/db";

describe("Marketplace Billing API", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    process.env.INTERNAL_MARKETPLACE_SECRET = "test-secret";
    mockRecordBillingEvent.mockResolvedValue({ id: "billing-evt-1" });
  });

  describe("POST /api/internal/marketplace/billing", () => {
    it("should return 403 without internal secret", async () => {
      const { POST } = await import("@/app/api/internal/marketplace/billing/route");
      const request = new Request("http://localhost/api/internal/marketplace/billing", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ operatorId: "op1", consumerId: "c1", deviceId: "d1", model: "qwen3:14b" }),
      });
      const response = await POST(request as never);
      expect(response.status).toBe(403);
    });

    it("should return 400 for missing fields", async () => {
      const { POST } = await import("@/app/api/internal/marketplace/billing/route");
      const request = new Request("http://localhost/api/internal/marketplace/billing", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({ operatorId: "op1" }),
      });
      const response = await POST(request as never);
      expect(response.status).toBe(400);
    });

    it("should return 400 for invalid JSON", async () => {
      const { POST } = await import("@/app/api/internal/marketplace/billing/route");
      const request = new Request("http://localhost/api/internal/marketplace/billing", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: "not json",
      });
      const response = await POST(request as never);
      expect(response.status).toBe(400);
    });

    it("should calculate revenue correctly", async () => {
      vi.mocked(db.marketplaceUsageEvent.create).mockResolvedValue({
        id: "e1",
        userId: "c1",
        requestId: "mkt_123",
        deviceId: "d1",
        model: "qwen3:14b",
        promptTokens: 500000,
        completionTokens: 250000,
        priceCents: 8,
        createdAt: new Date(),
      });

      const { POST } = await import("@/app/api/internal/marketplace/billing/route");
      const request = new Request("http://localhost/api/internal/marketplace/billing", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({
          operatorId: "op1",
          consumerId: "c1",
          deviceId: "d1",
          model: "qwen3:14b",
          tokensIn: 500000,
          tokensOut: 250000,
          pricePerMToken: 0.1,
        }),
      });
      const response = await POST(request as never);
      const data = await response.json();

      expect(response.status).toBe(200);
      expect(data.eventId).toBe("e1");
      expect(data.revenue).toBeGreaterThan(0);
      expect(data.operatorShare).toBeLessThan(data.revenue);
      expect(data.platformFee).toBeGreaterThan(0);
    });

    it("should apply 20% platform fee", async () => {
      vi.mocked(db.marketplaceUsageEvent.create).mockResolvedValue({
        id: "e1",
        userId: "c1",
        requestId: "mkt_123",
        deviceId: "d1",
        model: "qwen3:14b",
        promptTokens: 1000000,
        completionTokens: 0,
        priceCents: 10,
        createdAt: new Date(),
      });

      const { POST } = await import("@/app/api/internal/marketplace/billing/route");
      const request = new Request("http://localhost/api/internal/marketplace/billing", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({
          operatorId: "op1",
          consumerId: "c1",
          deviceId: "d1",
          model: "qwen3:14b",
          tokensIn: 1000000,
          tokensOut: 0,
          pricePerMToken: 0.1,
        }),
      });
      const response = await POST(request as never);
      const data = await response.json();

      // 1M tokens * $0.10/1M = $0.10 revenue, 80% = $0.08 operator share
      expect(data.revenue).toBeCloseTo(0.1);
      expect(data.operatorShare).toBeCloseTo(0.08);
      expect(data.platformFee).toBeCloseTo(0.02);
    });

    it("should default to $0.10/1M tokens if no price specified", async () => {
      vi.mocked(db.marketplaceUsageEvent.create).mockResolvedValue({
        id: "e1",
        userId: "c1",
        requestId: "mkt_123",
        deviceId: "d1",
        model: "qwen3:14b",
        promptTokens: 1000000,
        completionTokens: 0,
        priceCents: 10,
        createdAt: new Date(),
      });

      const { POST } = await import("@/app/api/internal/marketplace/billing/route");
      const request = new Request("http://localhost/api/internal/marketplace/billing", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({
          operatorId: "op1",
          consumerId: "c1",
          deviceId: "d1",
          model: "qwen3:14b",
          tokensIn: 1000000,
          tokensOut: 0,
          // no pricePerMToken — should default to 0.10
        }),
      });
      const response = await POST(request as never);
      const data = await response.json();

      expect(data.revenue).toBeCloseTo(0.1);
    });

    it("should handle zero tokens", async () => {
      vi.mocked(db.marketplaceUsageEvent.create).mockResolvedValue({
        id: "e1",
        userId: "c1",
        requestId: "mkt_123",
        deviceId: "d1",
        model: "qwen3:14b",
        promptTokens: 0,
        completionTokens: 0,
        priceCents: 0,
        createdAt: new Date(),
      });

      const { POST } = await import("@/app/api/internal/marketplace/billing/route");
      const request = new Request("http://localhost/api/internal/marketplace/billing", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({
          operatorId: "op1",
          consumerId: "c1",
          deviceId: "d1",
          model: "qwen3:14b",
        }),
      });
      const response = await POST(request as never);
      const data = await response.json();

      expect(data.revenue).toBe(0);
      expect(data.operatorShare).toBe(0);
      expect(data.platformFee).toBe(0);
    });
  });
});
