import { Prisma, Webhook } from "@prisma/client";
import { prisma } from "@formbricks/database";
import { Result, err, ok } from "@formbricks/types/error-handlers";
import { InvalidInputError } from "@formbricks/types/errors";
import { generateWebhookSecret } from "@/lib/crypto";
import { validateWebhookUrl } from "@/lib/utils/validate-webhook-url";
import { getWebhooksQuery } from "@/modules/api/v2/management/webhooks/lib/utils";
import { TGetWebhooksFilter, TWebhookInput } from "@/modules/api/v2/management/webhooks/types/webhooks";
import { ApiErrorResponseV2 } from "@/modules/api/v2/types/api-error";
import { ApiResponseWithMeta } from "@/modules/api/v2/types/api-success";

export const getWebhooks = async (
  environmentIds: string[],
  params: TGetWebhooksFilter
): Promise<Result<ApiResponseWithMeta<Webhook[]>, ApiErrorResponseV2>> => {
  try {
    const query = getWebhooksQuery(environmentIds, params);

    const [webhooks, count] = await prisma.$transaction([
      prisma.webhook.findMany({
        ...query,
      }),
      prisma.webhook.count({
        where: query.where,
      }),
    ]);

    if (!webhooks) {
      return err({
        type: "not_found",
        details: [{ field: "webhooks", issue: "not_found" }],
      });
    }

    return ok({
      data: webhooks,
      meta: {
        total: count,
        limit: params?.limit,
        offset: params?.skip,
      },
    });
  } catch (error) {
    return err({
      type: "internal_server_error",
      details: [
        { field: "webhooks", issue: error instanceof Error ? error.message : "Unknown error occurred" },
      ],
    });
  }
};

export const createWebhook = async (webhook: TWebhookInput): Promise<Result<Webhook, ApiErrorResponseV2>> => {
  const { environmentId, name, url, source, triggers, surveyIds } = webhook;

  try {
    await validateWebhookUrl(url);
  } catch (error) {
    if (error instanceof InvalidInputError) {
      return err({
        type: "bad_request",
        details: [{ field: "url", issue: error.message }],
      });
    }
    return err({
      type: "internal_server_error",
      details: [{ field: "url", issue: "Webhook URL validation failed unexpectedly" }],
    });
  }

  try {
    const secret = generateWebhookSecret();

    const prismaData: Prisma.WebhookCreateInput = {
      environment: {
        connect: {
          id: environmentId,
        },
      },
      name,
      url,
      source,
      triggers,
      surveyIds,
      secret,
    };

    const createdWebhook = await prisma.webhook.create({
      data: prismaData,
    });

    return ok(createdWebhook);
  } catch (error) {
    return err({
      type: "internal_server_error",
      details: [
        { field: "webhook", issue: error instanceof Error ? error.message : "Unknown error occurred" },
      ],
    });
  }
};
