import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { HrComplianceBody, HrComplianceStatus } from "@prisma/client";
import { prisma } from "@/lib/prisma";
import { canManageHumanCapital } from "@/lib/human-capital";

const COMPLIANCE_BODY_KEYS = new Set(Object.values(HrComplianceBody));
const COMPLIANCE_STATUS_KEYS = new Set(Object.values(HrComplianceStatus));

function parseComplianceBody(value?: string | null): HrComplianceBody | null {
  if (!value) {
    return null;
  }
  const trimmed = value.trim();
  if (!trimmed) {
    return null;
  }
  return COMPLIANCE_BODY_KEYS.has(trimmed as HrComplianceBody) ? (trimmed as HrComplianceBody) : null;
}

function parseComplianceStatus(value?: string | null): HrComplianceStatus | undefined {
  if (!value) {
    return undefined;
  }
  const trimmed = value.trim();
  if (!trimmed) {
    return undefined;
  }
  return COMPLIANCE_STATUS_KEYS.has(trimmed as HrComplianceStatus) ? (trimmed as HrComplianceStatus) : undefined;
}

export async function GET() {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!canManageHumanCapital(session.user.role, session.user.department)) {
    return NextResponse.json({ error: "Only owner/HC leaders can view compliance." }, { status: 403 });
  }

  const obligations = await prisma.hrComplianceObligation.findMany({
    where: { department: "capital_humano" },
    orderBy: [{ dueDate: "asc" }, { createdAt: "desc" }],
    take: 300,
  });

  return NextResponse.json({
    ok: true,
    obligations: obligations.map((item) => ({
      id: item.id,
      body: item.body,
      title: item.title,
      status: item.status,
      locationCode: item.locationCode,
      referencePeriod: item.referencePeriod,
      dueDate: item.dueDate ? item.dueDate.toISOString() : null,
      lastPaymentAt: item.lastPaymentAt ? item.lastPaymentAt.toISOString() : null,
      lastPaymentAmount: item.lastPaymentAmount,
      notes: item.notes,
    })),
  });
}

type ObligationInput = {
  id?: string;
  body?: string;
  title?: string;
  status?: string;
  locationCode?: string | null;
  referencePeriod?: string | null;
  dueDate?: string | null;
  lastPaymentAt?: string | null;
  lastPaymentAmount?: number | null;
  notes?: string | null;
};

export async function POST(request: Request) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!canManageHumanCapital(session.user.role, session.user.department)) {
    return NextResponse.json({ error: "Only owner/HC leaders can create obligations." }, { status: 403 });
  }

  const body = (await request.json().catch(() => ({}))) as ObligationInput;
  if (!body.body || !body.title) {
    return NextResponse.json({ error: "body and title are required." }, { status: 400 });
  }

  const complianceBody = parseComplianceBody(body.body);
  if (!complianceBody) {
    return NextResponse.json({ error: "Invalid compliance body." }, { status: 400 });
  }
  const complianceStatus = parseComplianceStatus(body.status);

  const obligation = await prisma.hrComplianceObligation.create({
    data: {
      department: "capital_humano",
      body: complianceBody,
      title: body.title,
      status: complianceStatus ?? "due_soon",
      locationCode: body.locationCode ?? null,
      referencePeriod: body.referencePeriod ?? null,
      dueDate: body.dueDate ? new Date(body.dueDate) : null,
      lastPaymentAt: body.lastPaymentAt ? new Date(body.lastPaymentAt) : null,
      lastPaymentAmount: body.lastPaymentAmount ?? null,
      notes: body.notes ?? null,
      createdById: session.user.id,
      updatedById: session.user.id,
    },
  });

  return NextResponse.json({ ok: true, id: obligation.id });
}

export async function PATCH(request: Request) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!canManageHumanCapital(session.user.role, session.user.department)) {
    return NextResponse.json({ error: "Only owner/HC leaders can update obligations." }, { status: 403 });
  }

  const body = (await request.json().catch(() => ({}))) as ObligationInput;
  if (!body.id) {
    return NextResponse.json({ error: "id is required." }, { status: 400 });
  }

  if (body.body) {
    const parsedBody = parseComplianceBody(body.body);
    if (!parsedBody) {
      return NextResponse.json({ error: "Invalid compliance body." }, { status: 400 });
    }
  }

  const parsedStatus = parseComplianceStatus(body.status);

  await prisma.hrComplianceObligation.update({
    where: { id: body.id },
    data: {
      body: body.body ? parseComplianceBody(body.body) ?? undefined : undefined,
      title: body.title ?? undefined,
      status: parsedStatus ?? undefined,
      locationCode: body.locationCode ?? undefined,
      referencePeriod: body.referencePeriod ?? undefined,
      dueDate: body.dueDate === null ? null : body.dueDate ? new Date(body.dueDate) : undefined,
      lastPaymentAt: body.lastPaymentAt === null ? null : body.lastPaymentAt ? new Date(body.lastPaymentAt) : undefined,
      lastPaymentAmount: body.lastPaymentAmount ?? undefined,
      notes: body.notes ?? undefined,
      updatedById: session.user.id,
    },
  });

  return NextResponse.json({ ok: true });
}
