import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { canManageHumanCapital, ensureEmployeeProfiles } from "@/lib/human-capital";
import { ensureHumanCapitalWorkspaceBootstrap } from "@/lib/human-capital/workspace";

const COMPLETE_STATUSES = new Set(["submitted", "verified"]);

export async function GET(_: Request, { params }: { params: Promise<{ userId: string }> }) {
  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 files." }, { status: 403 });
  }

  await ensureEmployeeProfiles();
  try {
    await ensureHumanCapitalWorkspaceBootstrap();
  } catch (bootstrapError) {
    console.error("[human-capital/files/:userId] workspace bootstrap failed; continuing with existing data.", bootstrapError);
  }

  const { userId } = await params;
  const user = await prisma.user.findUnique({
    where: { id: userId },
    select: { id: true, name: true, email: true, department: true, departmentRole: true },
  });

  if (!user) {
    return NextResponse.json({ error: "User not found." }, { status: 404 });
  }

  const profile = await prisma.employeeProfile.findUnique({
    where: { userId: user.id },
  });

  const requirements = await prisma.hrFileRequirement.findMany({
    where: { department: "capital_humano", isActive: true },
    orderBy: [{ sortOrder: "asc" }, { label: "asc" }],
  });

  const records = await prisma.hrEmployeeFileRecord.findMany({
    where: { userId: user.id, requirementId: { in: requirements.map((req) => req.id) } },
  });

  const recordByRequirement = new Map(records.map((record) => [record.requirementId, record]));

  let requiredMissing = 0;
  let requiredComplete = 0;

  const items = requirements.map((requirement) => {
    const record = recordByRequirement.get(requirement.id);
    const status = record?.status ?? "missing";
    if (requirement.isRequired) {
      if (COMPLETE_STATUSES.has(status)) {
        requiredComplete += 1;
      } else {
        requiredMissing += 1;
      }
    }

    return {
      requirementId: requirement.id,
      requirementKey: requirement.key,
      requirementLabel: requirement.label,
      fieldType: requirement.fieldType,
      isRequired: requirement.isRequired,
      status,
      valueText: record?.valueText ?? null,
      evidenceUrl: record?.evidenceUrl ?? null,
      note: record?.note ?? null,
      verifiedAt: record?.verifiedAt ? record.verifiedAt.toISOString() : null,
    };
  });

  const requiredTotal = Math.max(1, requiredComplete + requiredMissing);
  const completionPct = Math.round((requiredComplete / requiredTotal) * 100);

  return NextResponse.json({
    ok: true,
    file: {
      userId: user.id,
      name: user.name?.trim() || user.email,
      email: user.email,
      department: user.department ?? null,
      departmentRole: user.departmentRole ?? null,
      locationId: profile?.locationId ?? null,
      completionPct,
      complete: requiredMissing === 0,
      items,
    },
  });
}

type FileItemInput = {
  requirementId?: string;
  requirementKey?: string;
  status?: "missing" | "submitted" | "verified" | "rejected";
  valueText?: string | null;
  evidenceUrl?: string | null;
  note?: string | null;
};

export async function PUT(request: Request, { params }: { params: Promise<{ userId: string }> }) {
  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 edit files." }, { status: 403 });
  }

  const body = (await request.json().catch(() => ({}))) as { items?: FileItemInput[] };
  if (!Array.isArray(body.items)) {
    return NextResponse.json({ error: "items array is required." }, { status: 400 });
  }

  const { userId } = await params;
  const requirements = await prisma.hrFileRequirement.findMany({
    where: { department: "capital_humano" },
  });

  const requirementById = new Map(requirements.map((req) => [req.id, req]));
  const requirementByKey = new Map(requirements.map((req) => [req.key, req]));

  const updates = body.items.map((item) => {
    const requirement =
      (item.requirementId ? requirementById.get(item.requirementId) : undefined) ||
      (item.requirementKey ? requirementByKey.get(item.requirementKey) : undefined);

    if (!requirement) {
      throw new Error("Invalid requirement reference.");
    }

    const status = item.status ?? "submitted";

    return prisma.hrEmployeeFileRecord.upsert({
      where: {
        userId_requirementId: {
          userId,
          requirementId: requirement.id,
        },
      },
      update: {
        status,
        valueText: item.valueText ?? null,
        evidenceUrl: item.evidenceUrl ?? null,
        note: item.note ?? null,
        verifiedAt: status === "verified" ? new Date() : null,
        verifiedById: status === "verified" ? session.user.id : null,
        updatedById: session.user.id,
      },
      create: {
        userId,
        requirementId: requirement.id,
        status,
        valueText: item.valueText ?? null,
        evidenceUrl: item.evidenceUrl ?? null,
        note: item.note ?? null,
        verifiedAt: status === "verified" ? new Date() : null,
        verifiedById: status === "verified" ? session.user.id : null,
        updatedById: session.user.id,
      },
    });
  });

  try {
    await prisma.$transaction(updates);
    return NextResponse.json({ ok: true });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Failed to update files.";
    return NextResponse.json({ error: message }, { status: 400 });
  }
}
