import { createHmac } from "node:crypto";
import { TRPCError } from "@trpc/server";
import { describe, expect, it, vi } from "vitest";
import {
  buildWebhookCreateData,
  buildWebhookTestRequest,
  buildWebhookUpdateData,
  loadWebhookOrThrow,
  sendWebhookTestRequest,
} from "../router/webhook-support.js";

describe("webhook support", () => {
  it("builds create and sparse update payloads", () => {
    expect(buildWebhookCreateData({
      name: "Primary",
      url: "https://example.com/webhook",
      secret: "secret",
      events: ["project.created"],
      isActive: true,
    })).toEqual({
      name: "Primary",
      url: "https://example.com/webhook",
      secret: "secret",
      events: ["project.created"],
      isActive: true,
    });

    expect(buildWebhookUpdateData({
      isActive: false,
      secret: null,
    })).toEqual({
      isActive: false,
      secret: null,
    });
  });

  it("loads a webhook or throws", async () => {
    const db = {
      webhook: {
        findUnique: vi.fn().mockResolvedValue(null),
      },
    } as never;

    await expect(loadWebhookOrThrow(db, "missing")).rejects.toBeInstanceOf(TRPCError);
  });

  it("builds a signed test request when a secret exists", async () => {
    const timestamp = "2026-03-31T12:00:00.000Z";
    const request = await buildWebhookTestRequest({
      id: "wh_1",
      name: "Primary",
      secret: "topsecret",
    }, timestamp);

    const expectedBody = JSON.stringify({
      event: "webhook.test",
      timestamp,
      payload: {
        webhookId: "wh_1",
        webhookName: "Primary",
        message: "This is a test payload from CapaKraken.",
      },
    });

    expect(request.body).toBe(expectedBody);
    expect(request.headers["X-Webhook-Signature"]).toBe(
      createHmac("sha256", "topsecret").update(expectedBody).digest("hex"),
    );
  });

  it("reports fetch failures as unsuccessful test results", async () => {
    const fetchImpl = vi.fn().mockRejectedValue(new Error("network down"));

    await expect(sendWebhookTestRequest({
      id: "wh_1",
      name: "Primary",
      url: "https://example.com/webhook",
      secret: null,
    }, {
      fetchImpl,
      timestamp: "2026-03-31T12:00:00.000Z",
      timeoutMs: 10,
    })).resolves.toEqual({
      success: false,
      statusCode: 0,
      statusText: "network down",
    });
  });
});
