import { NextRequest, NextResponse } from "next/server";
import { Prisma } from "@/generated/prisma/client";
import { prisma } from "@/lib/db";
import {
  requireApiAuthWithOrg,
  requireApiAuthWithPermission,
  handleApiError,
} from "@/lib/api-auth";

export async function GET(request: NextRequest) {
  try {
    const session = await requireApiAuthWithOrg();
    const { searchParams } = new URL(request.url);

    if (searchParams.get("default") === "true") {
      const template = await prisma.formTemplate.findFirst({
        where: {
          organizationId: session.user.orgId,
          isDefault: true,
          isActive: true,
        },
        include: { fields: { orderBy: { sortOrder: "asc" } } },
      });
      return NextResponse.json({ template });
    }

    const templates = await prisma.formTemplate.findMany({
      where: { organizationId: session.user.orgId },
      orderBy: { createdAt: "desc" },
      include: {
        organization: { select: { slug: true } },
        _count: { select: { fields: true, cards: true } },
      },
    });

    return NextResponse.json({ templates });
  } catch (error) {
    return handleApiError(error);
  }
}

function slugify(name: string): string {
  return name
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-|-$/g, "");
}

export async function POST(request: NextRequest) {
  try {
    const session = await requireApiAuthWithPermission("settings.edit");
    const body = await request.json();

    const { name, description, duplicateFrom } = body as {
      name?: string;
      description?: string;
      duplicateFrom?: string;
    };

    if (!name?.trim()) {
      return NextResponse.json(
        { error: "Name is required" },
        { status: 400 }
      );
    }

    const baseSlug = slugify(name);
    let slug = baseSlug;
    let suffix = 1;
    while (
      await prisma.formTemplate.findUnique({
        where: {
          organizationId_slug: {
            organizationId: session.user.orgId!,
            slug,
          },
        },
      })
    ) {
      slug = `${baseSlug}-${suffix++}`;
    }

    let fieldsToCreate: Prisma.FormFieldCreateWithoutFormTemplateInput[] = [];

    if (duplicateFrom) {
      const source = await prisma.formTemplate.findFirst({
        where: { id: duplicateFrom, organizationId: session.user.orgId },
        include: { fields: { orderBy: { sortOrder: "asc" } } },
      });
      if (!source) {
        return NextResponse.json(
          { error: "Source template not found" },
          { status: 404 }
        );
      }
      fieldsToCreate = source.fields.map((f) => ({
        key: f.key,
        label: f.label,
        type: f.type,
        section: f.section,
        required: f.required,
        removable: f.removable,
        isCore: f.isCore,
        sortOrder: f.sortOrder,
        options: (f.options ?? Prisma.JsonNull) as Prisma.InputJsonValue,
        placeholder: f.placeholder,
        helpText: f.helpText,
        validation: (f.validation ?? Prisma.JsonNull) as Prisma.InputJsonValue,
        visibleOnCard: f.visibleOnCard,
        visibleOnSurvey: f.visibleOnSurvey,
      }));
    }

    const template = await prisma.formTemplate.create({
      data: {
        organizationId: session.user.orgId!,
        name: name.trim(),
        slug,
        description: description?.trim() || null,
        isDefault: false,
        isActive: true,
        ...(fieldsToCreate.length > 0 && {
          fields: { create: fieldsToCreate },
        }),
      },
      include: {
        fields: { orderBy: { sortOrder: "asc" } },
        _count: { select: { cards: true } },
      },
    });

    return NextResponse.json(template, { status: 201 });
  } catch (error) {
    return handleApiError(error);
  }
}
