import { redirect } from "next/navigation";
import { connectDB } from "@/lib/db";
import { Client } from "@/models/Client";
import { TimeEntry } from "@/models/TimeEntry";
import { VacationRequest } from "@/models/VacationRequest";
import { getSessionClientId } from "@/lib/auth";
import { AccountPageHeader } from "@/components/account/AccountPageHeader";
import { ClockInOutPanel } from "@/components/admin/ClockInOutPanel";
import { VacationSelfServicePanel } from "@/components/admin/VacationSelfServicePanel";
import { MySalaryPanel } from "@/components/account/MySalaryPanel";
import { SensitiveDataPanel } from "@/components/SensitiveDataPanel";
import { computeComplianceWarnings } from "@/lib/workingTimeCompliance";
import { remainingVacationDays } from "@/lib/vacationBalance";
import { AdminEmptyState } from "@/components/admin/AdminEmptyState";

export const dynamic = "force-dynamic";

function formatDuration(ms: number): string {
  const minutes = Math.floor(ms / 60_000);
  return `${Math.floor(minutes / 60)} Std. ${minutes % 60} Min.`;
}

function startOfDay(d: Date): Date {
  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
}
// Montag als Wochenstart (DE-Konvention), unabhängig vom aktuellen Wochentag.
function startOfWeek(d: Date): Date {
  const day = d.getDay();
  const diff = (day + 6) % 7;
  return startOfDay(new Date(d.getTime() - diff * 86_400_000));
}

// Für abgeschlossene UND noch offene Einträge - ein offener Eintrag zählt bis
// "jetzt", nicht bis zu einem (nicht vorhandenen) clockOut.
function sumDuration(entries: { clockIn: Date; clockOut: Date | null }[], since: Date): number {
  const now = Date.now();
  return entries.reduce((sum, e) => {
    const start = Math.max(new Date(e.clockIn).getTime(), since.getTime());
    const end = e.clockOut ? new Date(e.clockOut).getTime() : now;
    return sum + Math.max(0, end - start);
  }, 0);
}

// Neuer Mitarbeiter-Tab im Konto-Bereich (25.09.2026, auf Tills wiederholte
// explizite Bestätigung: /account, NICHT /admin). Bündelt alle bisher über
// /admin/zeiterfassung + /account/profile verstreuten Selbstbedienungs-
// Funktionen an einem Ort: Ein-/Ausstempeln, Urlaub, Gehaltsübersicht,
// sensible Selbstangaben. /admin/zeiterfassung bleibt separat als reine
// HR-Teamübersicht bestehen (wer ist eingestempelt, teamweite ArbZG-Hinweise).
export default async function AccountMitarbeiterPage({ params }: { params: Promise<{ locale: string }> }) {
  const { locale } = await params;
  const clientId = await getSessionClientId();
  if (!clientId) redirect(`/${locale}/login`);

  await connectDB();
  const client = await Client.findById(clientId)
    .select("role hourlyWage monthlyHours salaryHistory vacationDaysPerYear")
    .lean();
  if (!client || client.role !== "staff") redirect(`/${locale}/account`);

  const now = new Date();
  const todayStart = startOfDay(now);
  const weekStart = startOfWeek(now);
  const complianceWindowStart = new Date(now.getTime() - 30 * 86_400_000);

  const [openEntry, weekEntries, recentEntries, ownComplianceEntries, vacationRequests, salaryHistoryActors] = await Promise.all([
    TimeEntry.findOne({ clientId, clockOut: null }).lean(),
    TimeEntry.find({ clientId, clockIn: { $gte: weekStart } }).sort({ clockIn: -1 }).lean(),
    TimeEntry.find({ clientId }).sort({ clockIn: -1 }).limit(10).lean(),
    TimeEntry.find({ clientId, clockIn: { $gte: complianceWindowStart } }).lean(),
    VacationRequest.find({ clientId }).sort({ startDate: -1 }).lean(),
    Client.find({ _id: { $in: (client.salaryHistory || []).map((h) => String(h.changedByClientId)) } })
      .select("name")
      .lean(),
  ]);
  const salaryHistoryActorNameById = new Map(salaryHistoryActors.map((c) => [String(c._id), c.name]));

  const todayMs = sumDuration(weekEntries, todayStart);
  const weekMs = sumDuration(weekEntries, weekStart);
  const ownWarnings = computeComplianceWarnings(ownComplianceEntries);
  const vacationBalance = remainingVacationDays(
    client.vacationDaysPerYear ?? null,
    vacationRequests.filter((r) => new Date(r.startDate).getFullYear() === now.getFullYear())
  );

  return (
    <div>
      <div className="max-w-2xl flex flex-col gap-8">
        <AccountPageHeader
          eyebrow="Mitarbeiter"
          title="Mein Arbeitsbereich"
          subtitle="Zeiterfassung, Urlaub, Gehalt und deine sensiblen Selbstangaben an einem Ort."
        />

        <div>
          <h2 className="text-sm font-medium text-[var(--rk-ink)] mb-3">Zeiterfassung</h2>
          <ClockInOutPanel clockInSince={openEntry ? new Date(openEntry.clockIn).toISOString() : null} />

          {ownWarnings.length > 0 && (
            <div className="mt-4 flex flex-col gap-2">
              {ownWarnings.map((w, i) => (
                <div key={i} className="border border-amber-400/30 bg-amber-400/5 rounded-xl px-4 py-3 text-xs text-amber-400">
                  <span className="font-medium">
                    {new Date(w.date).toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })}:
                  </span>{" "}
                  {w.message}
                </div>
              ))}
            </div>
          )}

          <div className="grid grid-cols-2 gap-3 mt-4">
            <div className="bg-[var(--rk-surface)] border border-white/10 rounded-xl p-4">
              <p className="text-xs uppercase tracking-[0.1em] text-[var(--rk-ink-muted)] mb-1">Heute</p>
              <p className="text-lg text-[var(--rk-ink)]">{formatDuration(todayMs)}</p>
            </div>
            <div className="bg-[var(--rk-surface)] border border-white/10 rounded-xl p-4">
              <p className="text-xs uppercase tracking-[0.1em] text-[var(--rk-ink-muted)] mb-1">Diese Woche</p>
              <p className="text-lg text-[var(--rk-ink)]">{formatDuration(weekMs)}</p>
            </div>
          </div>

          <div className="mt-4">
            {recentEntries.length === 0 ? (
              <AdminEmptyState message="Noch keine Einträge." />
            ) : (
              <div className="flex flex-col gap-2">
                {recentEntries.map((e) => {
                  const clockIn = new Date(e.clockIn);
                  const clockOut = e.clockOut ? new Date(e.clockOut) : null;
                  return (
                    <div
                      key={String(e._id)}
                      className="flex items-center justify-between bg-[var(--rk-surface)] border border-white/10 rounded-xl px-4 py-3 text-sm"
                    >
                      <span>{clockIn.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })}</span>
                      <span className="text-[var(--rk-ink-muted)]">
                        {clockIn.toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" })} –{" "}
                        {clockOut ? clockOut.toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" }) : "läuft"}
                      </span>
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        </div>

        <div>
          <h2 className="text-sm font-medium text-[var(--rk-ink)] mb-3">Urlaub</h2>
          <VacationSelfServicePanel
            allowance={client.vacationDaysPerYear ?? null}
            approvedDays={vacationBalance.approvedDays}
            pendingDays={vacationBalance.pendingDays}
            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 || "",
            }))}
          />
        </div>

        <div>
          <h2 className="text-sm font-medium text-[var(--rk-ink)] mb-3">Gehalt</h2>
          <MySalaryPanel
            hourlyWage={client.hourlyWage ?? null}
            monthlyHours={client.monthlyHours ?? null}
            salaryHistory={(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(),
            }))}
          />
        </div>

        <div>
          <h2 className="text-sm font-medium text-[var(--rk-ink)] mb-3">Sensible Selbstangaben</h2>
          <SensitiveDataPanel clientId={String(client._id)} />
        </div>
      </div>
    </div>
  );
}
