import type { Prisma } from "@prisma/client";
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "../../../../lib/server/db";
import { isDatabaseConfigured } from "../../../../lib/server/env";
import {
  dbUnavailable,
  unauthorized,
} from "../../../../lib/server/responses";
import { getSessionUser } from "../../../../lib/server/session";
import { apiRoute } from "../../../../lib/server/apiRoute";
import { putDraftBodySchema } from "../../../../lib/server/validation/createFlowSchemas";
import { readLimitedJson } from "../../../../lib/server/validation/requestBody";
import { jsonFromZodError } from "../../../../lib/server/validation/zodHttp";

export const GET = apiRoute("drafts.me.get", async () => {
  if (!isDatabaseConfigured()) {
    return dbUnavailable();
  }

  const user = await getSessionUser();
  if (!user) {
    return unauthorized();
  }

  const draft = await prisma.ruleDraft.findUnique({
    where: { userId: user.id },
  });

  return NextResponse.json({
    draft: draft
      ? { payload: draft.payload, updatedAt: draft.updatedAt }
      : null,
  });
});

export const PUT = apiRoute("drafts.me.put", async (request: NextRequest) => {
  if (!isDatabaseConfigured()) {
    return dbUnavailable();
  }

  const user = await getSessionUser();
  if (!user) {
    return unauthorized();
  }

  const parsedBody = await readLimitedJson(request);
  if (parsedBody.ok === false) {
    return parsedBody.response;
  }

  const validated = putDraftBodySchema.safeParse(parsedBody.value);
  if (!validated.success) {
    return jsonFromZodError(validated.error);
  }

  const { payload } = validated.data;

  const jsonPayload = payload as Prisma.InputJsonValue;

  const draft = await prisma.ruleDraft.upsert({
    where: { userId: user.id },
    create: {
      userId: user.id,
      payload: jsonPayload,
    },
    update: {
      payload: jsonPayload,
    },
  });

  return NextResponse.json({
    draft: { payload: draft.payload, updatedAt: draft.updatedAt },
  });
});

export const DELETE = apiRoute("drafts.me.delete", async () => {
  if (!isDatabaseConfigured()) {
    return dbUnavailable();
  }

  const user = await getSessionUser();
  if (!user) {
    return unauthorized();
  }

  // Idempotent: missing draft is a no-op so callers can fire-and-forget after
  // publish / exit without worrying about prior state.
  await prisma.ruleDraft.deleteMany({ where: { userId: user.id } });

  return NextResponse.json({ ok: true });
});
