import { Prisma, WorkshopProgressStatus } from "@prisma/client";
import { NextResponse } from "next/server";
import { requireAdminApiUser } from "@/lib/auth/admin";
import { prisma } from "@/lib/prisma";
import { getTalleresSnapshot } from "@/lib/talleres/server";

type ProgressAction = "WATCHED" | "SKIPPED";

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

function parseString(value: unknown) {
  return typeof value === "string" ? value.trim() : "";
}

function parseAction(value: unknown): ProgressAction | null {
  if (value === "WATCHED" || value === "SKIPPED") {
    return value;
  }

  return null;
}

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

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

  try {
    const body = (await request.json()) as Record<string, unknown>;
    const workshopId = parseString(body.workshopId);
    const action = parseAction(body.action);

    if (!workshopId || !action) {
      return NextResponse.json({ error: "workshopId y action son requeridos." }, { status: 400 });
    }

    const workshop = await prisma.developmentWorkshop.findUnique({
      where: { id: workshopId },
      select: { id: true },
    });

    if (!workshop) {
      return NextResponse.json({ error: "Taller no encontrado." }, { status: 404 });
    }

    const existing = await prisma.developmentWorkshopProgress.findUnique({
      where: {
        workshopId_userId: {
          workshopId,
          userId: user.id,
        },
      },
      select: { status: true, watchedAt: true },
    });

    const now = new Date();

    if (action === "WATCHED") {
      const nextStatus = existing?.status === WorkshopProgressStatus.APPROVED ? WorkshopProgressStatus.APPROVED : WorkshopProgressStatus.WATCHED;

      await prisma.developmentWorkshopProgress.upsert({
        where: {
          workshopId_userId: {
            workshopId,
            userId: user.id,
          },
        },
        update: {
          status: nextStatus,
          watchedAt: existing?.watchedAt ?? now,
        },
        create: {
          workshopId,
          userId: user.id,
          status: WorkshopProgressStatus.WATCHED,
          watchedAt: now,
        },
      });
    }

    if (action === "SKIPPED") {
      const nextStatus = existing?.status === WorkshopProgressStatus.APPROVED ? WorkshopProgressStatus.APPROVED : WorkshopProgressStatus.SKIPPED;

      await prisma.developmentWorkshopProgress.upsert({
        where: {
          workshopId_userId: {
            workshopId,
            userId: user.id,
          },
        },
        update: {
          status: nextStatus,
          skippedAt: now,
        },
        create: {
          workshopId,
          userId: user.id,
          status: WorkshopProgressStatus.SKIPPED,
          skippedAt: now,
        },
      });
    }

    const payload = await getTalleresSnapshot(user.id);
    return NextResponse.json({ ok: true, payload });
  } catch (error) {
    if (isSchemaNotReadyError(error)) {
      return NextResponse.json(
        { error: "La base de datos aun no tiene las tablas de Talleres. Ejecuta prisma migrate para continuar." },
        { status: 503 },
      );
    }

    return NextResponse.json({ error: "No fue posible actualizar el progreso del taller." }, { status: 400 });
  }
}
