import { notFound } from "next/navigation";
import { EmployeeDetail } from "@/components/employees/EmployeeDetail";
import { todayIso } from "@/lib/format";
import { breadcrumbLabel, loadOrgMaps } from "@/lib/org";
import { loadPlacements, type ReportingLine } from "@/lib/placement";
import { loadOpenPositions } from "@/lib/positions";
import { createClient } from "@/lib/supabase/server";

type PageProps = { params: Promise<{ id: string }> };

export default async function EmployeeDetailPage({ params }: PageProps) {
  const { id } = await params;
  const supabase = await createClient();
  const today = todayIso();

  // Vorgesetzte und direkte Berichte stehen nirgends als Spalte — sie kommen
  // aus om_reporting_lines(). Beide Abfragen filtern *in* der Funktion, es
  // wandern also neun Zeilen über die Leitung und nicht achthundert.
  const [
    { data: employee },
    { data: ownLine },
    { data: reportLines },
    { data: history },
    { data: dependents },
    { data: notes },
    orgMaps,
    placements,
    openPositions,
  ] = await Promise.all([
    supabase.from("employees").select("*").eq("id", id).single(),
    supabase.rpc("om_reporting_lines", { p_as_of: today }).eq("employee_id", id).maybeSingle(),
    supabase.rpc("om_reporting_lines", { p_as_of: today }).eq("acting_manager_id", id),
    supabase
      .from("employee_history")
      .select("*")
      .eq("employee_id", id)
      .order("event_date", { ascending: false })
      .order("created_at", { ascending: false }),
    supabase.from("employee_dependents").select("*").eq("employee_id", id).order("created_at"),
    supabase.from("employee_notes").select("*").eq("employee_id", id).order("created_at", { ascending: false }),
    loadOrgMaps(supabase),
    loadPlacements(supabase, { asOf: today, employeeIds: [id] }),
    loadOpenPositions(supabase),
  ]);

  if (!employee) notFound();

  const line = ownLine as ReportingLine | null;
  const reports = (reportLines ?? []) as ReportingLine[];

  // Namen für die beteiligten Personen in einem Zug: die Vertretung, die
  // formal zuständige Leitung und die direkten Berichte.
  const relatedIds = Array.from(
    new Set(
      [line?.acting_manager_id, line?.formal_manager_id, ...reports.map((r) => r.employee_id)].filter(
        (x): x is string => Boolean(x)
      )
    )
  );
  const { data: relatedRows } = relatedIds.length
    ? await supabase.from("employees").select("id, first_name, last_name, job_title, status").in("id", relatedIds)
    : { data: [] };
  const byId = new Map((relatedRows ?? []).map((e) => [e.id, e]));

  const placement = placements.get(id) ?? null;

  return (
    <EmployeeDetail
      employee={employee}
      placement={
        placement && {
          positionNumber: placement.positionNumber,
          jobTitle: placement.jobTitle,
          isChief: placement.isChief,
          current: placement.current,
        }
      }
      breadcrumb={breadcrumbLabel(orgMaps, placement?.orgUnitId)}
      manager={(line?.acting_manager_id ? byId.get(line.acting_manager_id) : null) ?? null}
      // Nur wenn eine Vertretung im Spiel ist — sonst stünde dieselbe Person
      // zweimal da.
      formalManager={
        line?.formal_manager_id && line.formal_manager_id !== line.acting_manager_id
          ? (byId.get(line.formal_manager_id) ?? null)
          : null
      }
      directReports={reports.flatMap((r) => {
        const e = byId.get(r.employee_id);
        return e ? [e] : [];
      })}
      history={history ?? []}
      dependents={dependents ?? []}
      notes={notes ?? []}
      locations={orgMaps.locationList}
      openPositions={openPositions}
    />
  );
}
