import { Prisma, Webhook } from "@prisma/client";
import { z } from "zod";
import { prisma } from "@formbricks/database";
import { PrismaErrorType } from "@formbricks/database/types/error";
import { Result, err, ok } from "@formbricks/types/error-handlers";
import { InvalidInputError } from "@formbricks/types/errors";
import { validateWebhookUrl } from "@/lib/utils/validate-webhook-url";
import { ZWebhookUpdateSchema } from "@/modules/api/v2/management/webhooks/[webhookId]/types/webhooks";
import { ApiErrorResponseV2 } from "@/modules/api/v2/types/api-error";

export const getWebhook = async (webhookId: string) => {
  try {
    const webhook = await prisma.webhook.findUnique({
      where: {
        id: webhookId,
      },
    });

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

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

export const updateWebhook = async (
  webhookId: string,
  webhookInput: z.infer<typeof ZWebhookUpdateSchema>
): Promise<Result<Webhook, ApiErrorResponseV2>> => {
  if (webhookInput.url) {
    try {
      await validateWebhookUrl(webhookInput.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 updatedWebhook = await prisma.webhook.update({
      where: {
        id: webhookId,
      },
      data: webhookInput,
    });

    return ok(updatedWebhook);
  } catch (error) {
    if (error instanceof Prisma.PrismaClientKnownRequestError) {
      if (
        error.code === PrismaErrorType.RecordDoesNotExist ||
        error.code === PrismaErrorType.RelatedRecordDoesNotExist
      ) {
        return err({
          type: "not_found",
          details: [{ field: "webhook", issue: "not found" }],
        });
      }
    }
    return err({
      type: "internal_server_error",
      details: [
        { field: "webhook", issue: error instanceof Error ? error.message : "Unknown error occurred" },
      ],
    });
  }
};

export const deleteWebhook = async (webhookId: string): Promise<Result<Webhook, ApiErrorResponseV2>> => {
  try {
    const deletedWebhook = await prisma.webhook.delete({
      where: {
        id: webhookId,
      },
    });

    return ok(deletedWebhook);
  } catch (error) {
    if (error instanceof Prisma.PrismaClientKnownRequestError) {
      if (
        error.code === PrismaErrorType.RecordDoesNotExist ||
        error.code === PrismaErrorType.RelatedRecordDoesNotExist
      ) {
        return err({
          type: "not_found",
          details: [{ field: "webhook", issue: "not found" }],
        });
      }
    }
    return err({
      type: "internal_server_error",
      details: [
        { field: "webhook", issue: error instanceof Error ? error.message : "Unknown error occurred" },
      ],
    });
  }
};
