import { connectDB } from "@/lib/db";
import { Client } from "@/models/Client";
import { Department } from "@/models/Department";
import { Position } from "@/models/Position";
import { Team } from "@/models/Team";
import { GeneratedDocument } from "@/models/GeneratedDocument";
import { VacationRequest } from "@/models/VacationRequest";
import { remainingVacationDays } from "@/lib/vacationBalance";
import { probationEndDate, PROBATION_ELIGIBLE_TYPES } from "@/lib/employment";
import { PERMISSION_LABELS } from "@/lib/permissions";
import { getSensitiveDataAuditLogAction } from "@/lib/actions/sensitiveData";

// Team-API-Entsprechung von admin/team/[clientId]/page.tsx (StaffFilePage) -
// dieselbe Datenzusammenstellung, damit die Mitarbeiter-App dieselbe
// Personalakte zeigen kann wie die Webseite (25.09.2026, Personalsystem-
// Parität). Gibt null zurück, wenn keine Personalakte existiert (nicht
// gefunden oder role !== "staff") - der Rollen-/Berechtigungs-Check
// (team_management_view) passiert in der aufrufenden Route, nicht hier.
export async function getStaffFileData(clientId: string, canViewSensitiveData: boolean) {
  await connectDB();
  const client = await Client.findById(clientId).lean();
  if (!client || client.role !== "staff") return null;

  const currentYear = new Date().getFullYear();
  const [department, position, teams, documents, sensitiveDataAuditLog, salaryHistoryActors, vacationRequests] = await Promise.all([
    client.departmentId ? Department.findById(client.departmentId).lean() : null,
    client.positionId ? Position.findById(client.positionId).lean() : null,
    Team.find({ _id: { $in: (client.teamIds || []).map(String) } }).lean(),
    GeneratedDocument.find({ clientId }).sort({ createdAt: -1 }).lean(),
    canViewSensitiveData ? getSensitiveDataAuditLogAction(clientId) : Promise.resolve([]),
    Client.find({ _id: { $in: (client.salaryHistory || []).map((h) => String(h.changedByClientId)) } })
      .select("name")
      .lean(),
    VacationRequest.find({ clientId }).sort({ startDate: -1 }).lean(),
  ]);
  const salaryHistoryActorNameById = new Map(salaryHistoryActors.map((c) => [String(c._id), c.name]));
  const vacationBalance = remainingVacationDays(
    client.vacationDaysPerYear ?? null,
    vacationRequests.filter((r) => new Date(r.startDate).getFullYear() === currentYear)
  );

  const permissionSummary =
    !position || position.permissions === null || position.permissions === undefined
      ? "Vollzugriff"
      : position.permissions.length > 0
        ? position.permissions.map((p) => PERMISSION_LABELS[p]).join(", ")
        : "Keine Berechtigungen";

  const latestEmployeeRecord = [...(client.employmentRecords || [])]
    .filter((r) => PROBATION_ELIGIBLE_TYPES.includes(r.type as (typeof PROBATION_ELIGIBLE_TYPES)[number]))
    .sort((a, b) => new Date(b.startDate).getTime() - new Date(a.startDate).getTime())[0];
  let activeProbation: { endDate: string; daysLeft: number } | null = null;
  if (latestEmployeeRecord?.probationMonths && (!latestEmployeeRecord.endDate || new Date(latestEmployeeRecord.endDate) >= new Date())) {
    const endDate = probationEndDate(new Date(latestEmployeeRecord.startDate), latestEmployeeRecord.probationMonths);
    const daysLeft = Math.ceil((endDate.getTime() - Date.now()) / (24 * 60 * 60 * 1000));
    if (daysLeft >= 0) activeProbation = { endDate: endDate.toISOString(), daysLeft };
  }

  return {
    client: {
      id: String(client._id),
      name: client.name,
      firstName: client.firstName,
      email: client.email,
      avatarPath: client.avatarPath || "",
      birthDate: client.birthDate ? client.birthDate.toISOString().slice(0, 10) : "",
    },
    departmentName: department?.name || "",
    positionName: position?.name || "",
    teamNames: teams.map((t) => t.name),
    permissionSummary,
    hasPosition: !!position,
    activeProbation,
    salary: {
      hourlyWage: client.hourlyWage ?? null,
      monthlyHours: client.monthlyHours ?? null,
      suggestedHourlyWage: position?.defaultHourlyWage ?? department?.defaultHourlyWage ?? null,
      history: (client.salaryHistory || []).map((h) => ({
        id: String(h._id),
        oldHourlyWage: h.oldHourlyWage ?? null,
        newHourlyWage: h.newHourlyWage ?? null,
        reason: h.reason || "",
        byName: salaryHistoryActorNameById.get(String(h.changedByClientId)) || "—",
        at: h.createdAt.toISOString(),
      })),
    },
    vacation: {
      allowance: client.vacationDaysPerYear ?? null,
      remaining: vacationBalance.remaining,
      requests: vacationRequests.map((r) => ({
        id: String(r._id),
        startDate: new Date(r.startDate).toISOString(),
        endDate: new Date(r.endDate).toISOString(),
        workDaysCount: r.workDaysCount,
        status: r.status,
        note: r.note || "",
      })),
    },
    sensitiveDataAuditLog: canViewSensitiveData ? sensitiveDataAuditLog : null,
    employmentRecords: (client.employmentRecords || []).map((r) => ({
      id: String(r._id),
      type: r.type,
      startDate: new Date(r.startDate).toISOString(),
      endDate: r.endDate ? new Date(r.endDate).toISOString() : null,
      probationMonths: r.probationMonths ?? null,
      terminationType: r.terminationType ?? null,
      note: r.note || "",
    })),
    onboardingChecklist: (client.onboardingChecklist || []).map((i) => ({ id: String(i._id), text: i.text, done: i.done })),
    documents: documents.map((d) => ({
      id: String(d._id),
      templateName: d.templateName,
      category: d.category,
      createdAt: d.createdAt.toISOString(),
    })),
  };
}
