import { beforeEach, describe, expect, it, vi } from "vitest";
import { GET as listAlerts } from "@/app/api/alerts/route";
import { POST as resolveAlert } from "@/app/api/alerts/[id]/resolve/route";

vi.mock("@/lib/prisma", () => ({
  prisma: {
    alertLog: {
      count: vi.fn(),
      findMany: vi.fn(),
      findUnique: vi.fn(),
      update: vi.fn(),
    },
  },
}));

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

const ADMIN_HEADERS = {
  "x-auth-type": "admin",
  "x-user-id": "U_admin_demo",
  "x-user-role": "admin",
};

const SERVICE_HEADERS = {
  "x-auth-type": "service",
  "x-customer-id": "CUST_001",
  "x-permissions": "",
};

const SAMPLE_ALERT = {
  id: BigInt(1),
  alertType: "RPA_FAILED",
  quoteId: "QTE_001",
  cargoHash: "abc123",
  detailJson: { reason: "timeout" },
  status: "open",
  resolverId: null,
  resolvedAt: null,
  createdAt: new Date("2026-06-16T08:00:00Z"),
};

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

describe("GET /api/alerts", () => {
  it("admin + type 筛选 → 200", async () => {
    vi.mocked(prisma.alertLog.count).mockResolvedValue(1);
    vi.mocked(prisma.alertLog.findMany).mockResolvedValue([SAMPLE_ALERT as never]);

    const response = await listAlerts(
      new Request(
        "http://localhost/api/alerts?page=1&size=20&type=RPA_FAILED&status=open",
        { headers: ADMIN_HEADERS },
      ),
    );
    const json = await response.json();

    expect(response.status).toBe(200);
    expect(json.code).toBe(0);
    expect(json.data.list).toHaveLength(1);
    expect(json.data.list[0].alert_type).toBe("RPA_FAILED");
    expect(prisma.alertLog.findMany).toHaveBeenCalledWith(
      expect.objectContaining({
        where: { alertType: "RPA_FAILED", status: "open" },
      }),
    );
  });

  it("缺分页 → 400", async () => {
    const response = await listAlerts(
      new Request("http://localhost/api/alerts", { headers: ADMIN_HEADERS }),
    );
    expect(response.status).toBe(400);
  });

  it("宿主 token → 403", async () => {
    const response = await listAlerts(
      new Request("http://localhost/api/alerts?page=1&size=20", {
        headers: SERVICE_HEADERS,
      }),
    );
    expect(response.status).toBe(403);
  });
});

describe("POST /api/alerts/{id}/resolve", () => {
  it("admin 处理 → 200 + resolved", async () => {
    vi.mocked(prisma.alertLog.findUnique).mockResolvedValue(
      SAMPLE_ALERT as never,
    );
    vi.mocked(prisma.alertLog.update).mockResolvedValue({
      ...SAMPLE_ALERT,
      status: "resolved",
      resolverId: "U_admin_demo",
      resolvedAt: new Date("2026-06-16T09:00:00Z"),
    } as never);

    const response = await resolveAlert(
      new Request("http://localhost/api/alerts/1/resolve", {
        method: "POST",
        headers: { ...ADMIN_HEADERS, "Content-Type": "application/json" },
        body: JSON.stringify({ resolver_id: "U_admin_demo" }),
      }),
      { params: Promise.resolve({ id: "1" }) },
    );
    const json = await response.json();

    expect(response.status).toBe(200);
    expect(json.data.status).toBe("resolved");
    expect(json.data.resolver_id).toBe("U_admin_demo");
  });

  it("不存在 id → 404", async () => {
    vi.mocked(prisma.alertLog.findUnique).mockResolvedValue(null);

    const response = await resolveAlert(
      new Request("http://localhost/api/alerts/999/resolve", {
        method: "POST",
        headers: ADMIN_HEADERS,
      }),
      { params: Promise.resolve({ id: "999" }) },
    );

    expect(response.status).toBe(404);
  });

  it("非 admin → 403", async () => {
    const response = await resolveAlert(
      new Request("http://localhost/api/alerts/1/resolve", {
        method: "POST",
        headers: SERVICE_HEADERS,
      }),
      { params: Promise.resolve({ id: "1" }) },
    );

    expect(response.status).toBe(403);
  });
});
