import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
import { NextResponse } from "next/server";

import { serializeWarehouseLocation } from "@/features/warehouse-locations/lib/serialize-warehouse-location";
import { warehouseLocationInputSchema } from "@/features/warehouse-locations/schemas/warehouse-location.schema";
import { createAuditTrailSafe } from "@/lib/audit-trail";
import { resolveMasterCode } from "@/lib/master-code";
import { prisma } from "@/lib/prisma";
import { requireApiAccess } from "@/lib/authorization";

export async function GET(request: Request) {
  const auth = requireApiAccess(request);
  if (!auth.ok) return auth.response;
  const data = await prisma.warehouseLocation.findMany({
    include: { warehouse: { select: { name: true } } },
    orderBy: [{ createdAt: "desc" }]
  });
  return NextResponse.json({ data: data.map(serializeWarehouseLocation) });
}

export async function POST(request: Request) {
  const auth = requireApiAccess(request);
  if (!auth.ok) return auth.response;
  const parsed = warehouseLocationInputSchema.safeParse(await request.json());
  if (!parsed.success) {
    return NextResponse.json(
      { message: "Validasi gagal", errors: parsed.error.flatten().fieldErrors },
      { status: 400 }
    );
  }

  try {
    const resolvedCode = await resolveMasterCode({
      role: auth.user.role,
      prefix: "LOC",
      requestedCode: parsed.data.code,
      countExisting: () =>
        prisma.warehouseLocation.count({ where: { code: { startsWith: "LOC" } } }),
      exists: async (code) =>
        (await prisma.warehouseLocation.count({ where: { code } })) > 0
    });
    if (!resolvedCode.ok) {
      return NextResponse.json(
        { message: "Validasi gagal", errors: { code: [resolvedCode.message] } },
        { status: 400 }
      );
    }
    const location = await prisma.warehouseLocation.create({
      data: {
        warehouseId: BigInt(parsed.data.warehouse_id),
        code: resolvedCode.code,
        name: parsed.data.name,
        locationType: parsed.data.location_type || null,
        status: parsed.data.status
      },
      include: { warehouse: { select: { name: true } } }
    });
    await createAuditTrailSafe({
      userId: auth.user.id,
      action: "WAREHOUSE_LOCATION_CREATED",
      entityType: "WAREHOUSE_LOCATION",
      entityId: location.id,
      method: request.method,
      pathname: new URL(request.url).pathname,
      statusCode: 201,
      summary: `Warehouse location ${location.code} dibuat`
    });
    return NextResponse.json({ data: serializeWarehouseLocation(location) }, { status: 201 });
  } catch (error) {
    if (error instanceof PrismaClientKnownRequestError && error.code === "P2002") {
      return NextResponse.json(
        { message: "Validasi gagal", errors: { code: ["Kode lokasi sudah dipakai di gudang ini"] } },
        { status: 409 }
      );
    }
    if (error instanceof PrismaClientKnownRequestError && error.code === "P2003") {
      return NextResponse.json(
        { message: "Validasi gagal", errors: { warehouse_id: ["Gudang tidak valid"] } },
        { status: 400 }
      );
    }
    throw error;
  }
}
