import { describe, it, expect, beforeEach, vi } from "vitest";
import { NextRequest } from "next/server";

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

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

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

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

describe("POST /api/internal/marketplace/auto-remove", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    delete process.env.INTERNAL_MARKETPLACE_SECRET;
  });

  it("returns 401 without internal secret header", async () => {
    process.env.INTERNAL_MARKETPLACE_SECRET = "test-secret";
    const { POST } = await import(
      "@/app/api/internal/marketplace/auto-remove/route"
    );
    const response = await POST(
      new NextRequest("http://localhost/api/internal/marketplace/auto-remove", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ device_ids: ["dev-1"] }),
      }),
    );
    expect(response.status).toBe(401);
  });

  it("returns 401 when secret is wrong", async () => {
    process.env.INTERNAL_MARKETPLACE_SECRET = "correct-secret";
    const { POST } = await import(
      "@/app/api/internal/marketplace/auto-remove/route"
    );
    const response = await POST(
      new NextRequest("http://localhost/api/internal/marketplace/auto-remove", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "wrong-secret",
        },
        body: JSON.stringify({ device_ids: ["dev-1"] }),
      }),
    );
    expect(response.status).toBe(401);
  });

  it("returns 400 when device_ids is missing", async () => {
    process.env.INTERNAL_MARKETPLACE_SECRET = "test-secret";
    const { POST } = await import(
      "@/app/api/internal/marketplace/auto-remove/route"
    );
    const response = await POST(
      new NextRequest("http://localhost/api/internal/marketplace/auto-remove", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({}),
      }),
    );
    expect(response.status).toBe(400);
    const data = await response.json();
    expect(data.error).toMatch(/device_ids/);
  });

  it("returns 400 when device_ids is empty array", async () => {
    process.env.INTERNAL_MARKETPLACE_SECRET = "test-secret";
    const { POST } = await import(
      "@/app/api/internal/marketplace/auto-remove/route"
    );
    const response = await POST(
      new NextRequest("http://localhost/api/internal/marketplace/auto-remove", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({ device_ids: [] }),
      }),
    );
    expect(response.status).toBe(400);
  });

  it("disables marketplace for the provided device IDs", async () => {
    process.env.INTERNAL_MARKETPLACE_SECRET = "test-secret";
    vi.mocked(db.device.updateMany).mockResolvedValue({ count: 2 });

    const { POST } = await import(
      "@/app/api/internal/marketplace/auto-remove/route"
    );
    const response = await POST(
      new NextRequest("http://localhost/api/internal/marketplace/auto-remove", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({ device_ids: ["dev-1", "dev-2"] }),
      }),
    );

    expect(response.status).toBe(200);
    const data = await response.json();
    expect(data.disabled).toBe(2);
    expect(db.device.updateMany).toHaveBeenCalledWith({
      where: { id: { in: ["dev-1", "dev-2"] }, marketplaceEnabled: true },
      data: { marketplaceEnabled: false },
    });
  });

  it("filters out non-string device_ids", async () => {
    process.env.INTERNAL_MARKETPLACE_SECRET = "test-secret";
    vi.mocked(db.device.updateMany).mockResolvedValue({ count: 1 });

    const { POST } = await import(
      "@/app/api/internal/marketplace/auto-remove/route"
    );
    const response = await POST(
      new NextRequest("http://localhost/api/internal/marketplace/auto-remove", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-internal-secret": "test-secret",
        },
        body: JSON.stringify({ device_ids: ["dev-1", 123, null, "dev-2"] }),
      }),
    );

    expect(response.status).toBe(200);
    expect(db.device.updateMany).toHaveBeenCalledWith({
      where: { id: { in: ["dev-1", "dev-2"] }, marketplaceEnabled: true },
      data: { marketplaceEnabled: false },
    });
  });
});
