import { Prisma } from "@prisma/client";
import { NextResponse } from "next/server";
import { requireAdminApiUser } from "@/lib/auth/admin";
import { prisma } from "@/lib/prisma";
import {
  ContractCreateInputSchema,
  ContractListFiltersSchema,
} from "@/lib/contracts/types";
import { listContractsForUser } from "@/lib/contracts/server";

function isSchemaNotReadyError(error: unknown) {
  return error instanceof Prisma.PrismaClientKnownRequestError && (error.code === "P2021" || error.code === "P2022");
}

function parseJsonBody(body: unknown) {
  return typeof body === "object" && body !== null ? (body as Record<string, unknown>) : {};
}

export async function GET(request: Request) {
  const user = await requireAdminApiUser();

  if (!user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const { searchParams } = new URL(request.url);
    const parsed = ContractListFiltersSchema.safeParse({
      q: searchParams.get("q") ?? undefined,
      status: searchParams.get("status") ?? undefined,
      sort: searchParams.get("sort") ?? undefined,
    });

    if (!parsed.success) {
      return NextResponse.json({ error: "Filtros invalidos." }, { status: 400 });
    }

    const contracts = await listContractsForUser(user.id, parsed.data);
    return NextResponse.json({ ok: true, contracts });
  } catch (error) {
    if (isSchemaNotReadyError(error)) {
      return NextResponse.json(
        { error: "La base de datos aun no tiene las tablas de Gestion Estrategica de Contratos. Ejecuta prisma migrate." },
        { status: 503 },
      );
    }

    return NextResponse.json({ error: "No fue posible obtener contratos." }, { status: 400 });
  }
}

export async function POST(request: Request) {
  const user = await requireAdminApiUser();

  if (!user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = parseJsonBody(await request.json().catch(() => ({})));
    const parsed = ContractCreateInputSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json({ error: "Datos de contrato invalidos." }, { status: 400 });
    }

    const input = parsed.data;
    const created = await prisma.contractRecord.create({
      data: {
        userId: user.id,
        sourceProposalId: input.sourceProposalId ?? null,
        title: input.title,
        counterpartyEntity: input.counterpartyEntity,
        contractNumber: input.contractNumber ?? null,
        contractType: input.contractType,
        startDate: input.startDate ? new Date(input.startDate) : null,
        endDate: input.endDate ? new Date(input.endDate) : null,
        totalAmount: input.totalAmount ?? null,
        currency: (input.currency ?? "MXN").toUpperCase(),
        status: input.status ?? "ACTIVE",
        description: input.description ?? "",
      },
      select: { id: true },
    });

    const contracts = await listContractsForUser(user.id, { q: created.id });
    const contract = contracts.find((item) => item.id === created.id) ?? null;

    return NextResponse.json({ ok: true, contract });
  } catch (error) {
    if (isSchemaNotReadyError(error)) {
      return NextResponse.json(
        { error: "La base de datos aun no tiene las tablas de Gestion Estrategica de Contratos. Ejecuta prisma migrate." },
        { status: 503 },
      );
    }

    return NextResponse.json({ error: "No fue posible crear el contrato." }, { status: 400 });
  }
}
