import { prisma } from "@/lib/prisma";
import { requireUser, requirePermission, withGuard } from "@/lib/guard";
import { parseBody, ok } from "@/lib/http";
import { appraisalCreateSchema, DEFAULT_COMPETENCIES } from "@/lib/validators";
import { isManagerTier } from "@/lib/rbac";
import type { Prisma } from "@prisma/client";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

// GET /api/appraisals — list. Manager-tier sees all; staff see only their own.
export const GET = withGuard(async () => {
  const me = await requireUser();
  const where: Prisma.AppraisalWhereInput = isManagerTier(me.role) ? {} : { userId: me.id };
  const appraisals = await prisma.appraisal.findMany({
    where,
    include: {
      user: { select: { id: true, name: true, position: true } },
      reviewer: { select: { id: true, name: true } },
    },
    orderBy: [{ year: "desc" }, { half: "desc" }, { createdAt: "desc" }],
  });
  return ok(appraisals);
});

// POST /api/appraisals — create an appraisal for a staff member (Manager-tier),
// seeded with the default competencies.
export const POST = withGuard(async (req: Request) => {
  const me = await requirePermission("appraisals:manage");
  const data = await parseBody(req, appraisalCreateSchema);

  const staff = await prisma.user.findUnique({ where: { id: data.userId } });
  if (!staff) return ok({ error: "Staff member not found" }, 404);

  const existing = await prisma.appraisal.findUnique({
    where: { userId_year_half: { userId: data.userId, year: data.year, half: data.half } },
  });
  if (existing) return ok({ error: "An appraisal for this staff & period already exists" }, 409);

  const appraisal = await prisma.appraisal.create({
    data: {
      userId: data.userId,
      reviewerId: me.id,
      year: data.year,
      half: data.half,
      competencies: {
        create: DEFAULT_COMPETENCIES.map((name, i) => ({ name, order: i })),
      },
    },
    include: {
      user: { select: { id: true, name: true, position: true } },
      reviewer: { select: { id: true, name: true } },
    },
  });
  return ok(appraisal, 201);
});
