"use client";

import { useEffect, useRef, useState } from "react";
import Link from "next/link";
import { usePathname, useSearchParams } from "next/navigation";
import type { Permission } from "@/lib/permissions";
import { GlobalSearchBox } from "@/components/admin/GlobalSearchBox";
import { adminLogoutAction } from "@/lib/actions/auth";

// Meldet inaktive Mitarbeiter-Sessions automatisch ab — Wunsch aus dem
// Team-App-Feedback ("professionelles App-Feeling", kein ewig offenes
// Admin-Fenster). 30 Minuten ohne Maus/Tastatur/Touch/Scroll-Aktivität.
const IDLE_LOGOUT_MS = 30 * 60 * 1000;

function useIdleLogout() {
  useEffect(() => {
    let timer: ReturnType<typeof setTimeout>;
    function reset() {
      clearTimeout(timer);
      timer = setTimeout(() => {
        adminLogoutAction();
      }, IDLE_LOGOUT_MS);
    }
    const events: (keyof WindowEventMap)[] = ["mousemove", "keydown", "click", "scroll", "touchstart"];
    events.forEach((e) => window.addEventListener(e, reset, { passive: true }));
    reset();
    return () => {
      clearTimeout(timer);
      events.forEach((e) => window.removeEventListener(e, reset));
    };
  }, []);
}

// alwaysVisible auf dem einzelnen Link (nicht nur der Kategorie) - für den
// Fall, dass eine Kategorie überwiegend berechtigungsgebundene Links
// enthält, aber ein einzelner Link (z. B. Zeiterfassung im Personalsystem,
// 24.09.2026) trotzdem für alle sichtbar sein soll, ohne gleich die ganze
// Kategorie ungefiltert zu lassen.
type NavLink = { href: string; label: string; permission?: Permission | Permission[]; alwaysVisible?: boolean };
type NavCategory = { label: string; links: NavLink[]; alwaysVisible?: boolean };

// Innerhalb jeder Kategorie sortiert von der am breitesten vergebenen
// Berechtigung zur am stärksten eingeschränkten/sensibelsten — Kategorien
// selbst laufen schon vorher grob "breit" (Aufträge) zu "eng" (Verwaltung).
const CATEGORIES: NavCategory[] = [
  {
    label: "Aufträge",
    links: [
      { href: "/de/admin/orders", label: "Aufträge", permission: "orders_view" },
      { href: "/de/admin/contracts", label: "Verträge", permission: "orders_view" },
      { href: "/de/admin/calendar", label: "Kalender", permission: ["orders_view", "calendars_view"] },
      // Umbenannt von "Urlaub" (Nav-Aufräumen, 25.09.2026) - seit dem neuen
      // Urlaubsanträge-System unter "Personalsystem" gab es zwei gleich
      // benannte, aber komplett unterschiedliche Nav-Punkte: hier nur eine
      // gefilterte Kalenderansicht (informeller Team-Überblick "wer ist wann
      // weg"), dort das formelle Kontingent-/Genehmigungssystem.
      { href: "/de/admin/calendar?vacation=1", label: "Urlaubskalender", permission: "calendars_view" },
      { href: "/de/admin/clients", label: "Kunden", permission: "clients_view" },
      { href: "/de/admin/feedback", label: "Feedback", permission: "orders_view" },
      { href: "/de/admin/wishlist", label: "Wunschliste", permission: "orders_view" },
      { href: "/de/admin/rejection-reasons", label: "Ablehnungsgründe", permission: "rejection_reasons_view" },
    ],
  },
  {
    label: "Inhalte",
    links: [
      { href: "/de/admin/portfolio", label: "Portfolio", permission: "portfolio_view" },
      { href: "/de/admin/services", label: "Angebote", permission: "services_view" },
      { href: "/de/admin/bundles", label: "Pakete", permission: "bundles_view" },
      { href: "/de/admin/conventions", label: "Conventions", permission: "conventions_view" },
      { href: "/de/admin/blog", label: "Blog", permission: "blog_view" },
      { href: "/de/admin/faq", label: "FAQ", permission: "faq_view" },
      { href: "/de/admin/testimonials", label: "Bewertungen", permission: "testimonials_view" },
    ],
  },
  {
    label: "Finanzen",
    links: [
      { href: "/de/admin/discounts", label: "Rabattcodes", permission: "discounts_view" },
      { href: "/de/admin/vouchers", label: "Gutscheine", permission: "vouchers_view" },
      { href: "/de/admin/price-templates", label: "Preisvorlagen", permission: "price_templates_view" },
      { href: "/de/admin/expenses", label: "Einnahmen & Ausgaben", permission: "expenses_view" },
      { href: "/de/admin/mileage", label: "Fahrtkosten", permission: "expenses_view" },
      { href: "/de/admin/statistics", label: "Statistiken", permission: "statistics" },
      { href: "/de/admin/tax", label: "Steuer", permission: "statistics" },
    ],
  },
  {
    // Bewusst ungefiltert (alwaysVisible) — ToDos sind für jede:n immer
    // nutzbar (mindestens die eigenen), und im Intranet ist Ansehen für
    // jede:n immer möglich, siehe admin/intranet/page.tsx. Beide sind daher
    // nicht an eine bestimmte Berechtigung gebunden.
    label: "Intranet",
    alwaysVisible: true,
    links: [
      { href: "/de/admin/intranet", label: "Abläufe" },
      { href: "/de/admin/todos", label: "ToDos" },
      { href: "/de/admin/absences", label: "Abwesenheiten" },
      { href: "/de/admin/qr-code", label: "QR-Code-Generator" },
      { href: "/de/admin/mitarbeiter-app", label: "Mitarbeiter-App" },
    ],
  },
  {
    // Personalsystem (24.09.2026) - alles Mitarbeiter-bezogene an einem Ort
    // statt über Intranet/Verwaltung verstreut, auf Wunsch des Nutzers.
    // Ausdrücklich NICHT die Foto-Kundenverträge (Contract-Modell,
    // contractPdf.tsx) - die bleiben bei "Aufträge" → "Verträge", ein
    // komplett getrenntes System. Zeiterfassung war früher alwaysVisible
    // (persönliches Ein-/Ausstempeln lief hier für alle) - seit dem neuen
    // Mitarbeiter-Tab (25.09.2026) ist die Selbstbedienung nach
    // /account/mitarbeiter umgezogen, diese Seite zeigt nur noch die
    // teamweite HR-Übersicht, daher jetzt hr-gated wie die anderen.
    // Sortierung (Nav-Aufräumen, 25.09.2026): ein reines Ansehen-Recht gilt
    // als "breiter" als eine gebündelte Handlungs-Berechtigung wie "hr"/"qm"
    // (die faktisch auch Bearbeiten/Entscheiden erlaubt) - daher Dokumente
    // (akzeptiert das breite documents_view als Alternative zu hr/qm) vor
    // Team & Rechte (reines Ansehen-Recht) vor den echten hr/qm-Handlungs-
    // berechtigungen.
    label: "Personalsystem",
    links: [
      { href: "/de/admin/documents", label: "Dokumente", permission: ["documents_view", "hr", "qm"] },
      { href: "/de/admin/team", label: "Team & Rechte", permission: "team_management_view" },
      { href: "/de/admin/zeiterfassung", label: "Zeiterfassung (Team)", permission: "hr" },
      { href: "/de/admin/urlaubsantraege", label: "Urlaubsanträge", permission: "hr" },
      { href: "/de/admin/qm", label: "QM & Personal", permission: ["qm", "hr"] },
    ],
  },
  {
    label: "Verwaltung",
    links: [
      { href: "/de/admin/guide", label: "Handbuch", permission: "guide" },
      { href: "/de/admin/contract-templates", label: "Vertragsvorlagen", permission: "contract_templates" },
      { href: "/de/admin/seo", label: "SEO", permission: "seo" },
      { href: "/de/admin/settings", label: "Einstellungen", permission: "settings" },
      { href: "/de/admin/logs", label: "Systemprotokoll", permission: "logs" },
    ],
  },
];

// Berücksichtigt bei Links mit Query-String (z. B. "?vacation=1") auch die
// aktuellen Suchparameter, nicht nur den Pfad — sonst markieren sich zwei
// Links, die denselben Pfad aber unterschiedliche Parameter haben (Kalender
// vs. Urlaub), gleichzeitig als aktiv (der Pfad allein passt bei beiden).
function isActive(pathname: string | null, search: string, href: string) {
  const [hrefPath, hrefQuery] = href.split("?");
  if (pathname !== hrefPath && !pathname?.startsWith(`${hrefPath}/`)) return false;
  // Bei einem Link ohne eigenen Query-String (z. B. "Kalender") nur aktiv,
  // wenn gerade keine Suchparameter gesetzt sind — sonst wären "Kalender"
  // und "Urlaub" (gleicher Pfad, "?vacation=1") gleichzeitig hervorgehoben.
  if (!hrefQuery) return search === "";
  return search === hrefQuery;
}

export function AdminNavLinks({ permissions }: { permissions: Record<Permission, boolean> }) {
  useIdleLogout();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const search = searchParams.toString();
  // Klick-/Tap-gesteuert statt reinem CSS-:hover — auf Touch-Geräten bleibt
  // ein :hover/:focus-within-Dropdown nach dem Antippen eines Links oft
  // hängen (kein "Mouse-Leave"-Ereignis gibt es dort nicht), sodass es die
  // neu geladene Seite dahinter verdeckt und wie ein Fehler wirkt. Schließt
  // sich jetzt explizit bei Linkklick, Seitenwechsel und Klick daneben.
  const [openCategory, setOpenCategory] = useState<string | null>(null);
  const navRef = useRef<HTMLElement>(null);

  // Auf Geräten mit echtem Maus-Hover (nicht Touch) zusätzlich per Hover
  // öffnen, wie ursprünglich gewohnt — die Klick-Steuerung bleibt parallel
  // bestehen (u. a. für Tastatur-Bedienung), nur eben nicht mehr die einzige
  // Öffnungsart. `hover: hover` schließt Touch-Geräte zuverlässig aus, damit
  // der oben behobene Mobile-Bug nicht wieder auftritt.
  const [hoverCapable, setHoverCapable] = useState(false);
  useEffect(() => {
    setHoverCapable(window.matchMedia("(hover: hover) and (pointer: fine)").matches);
  }, []);

  useEffect(() => {
    setOpenCategory(null);
  }, [pathname, search]);

  useEffect(() => {
    if (!openCategory) return;
    function onOutsideClick(e: MouseEvent) {
      if (navRef.current && !navRef.current.contains(e.target as Node)) setOpenCategory(null);
    }
    document.addEventListener("mousedown", onOutsideClick);
    return () => document.removeEventListener("mousedown", onOutsideClick);
  }, [openCategory]);

  const visibleCategories = CATEGORIES.map((cat) => ({
    label: cat.label,
    links: cat.alwaysVisible
      ? cat.links
      : cat.links.filter((link) =>
          link.alwaysVisible
            ? true
            : Array.isArray(link.permission)
              ? link.permission.some((p) => permissions[p])
              : link.permission
                ? permissions[link.permission]
                : false
        ),
  })).filter((cat) => cat.links.length > 0);

  return (
    <div className="pt-4 mb-8">
      <nav ref={navRef} className="flex items-center gap-1 flex-wrap text-xs uppercase tracking-[0.13em]">
      {visibleCategories.map((cat) => {
        const categoryActive = cat.links.some((link) => isActive(pathname, search, link.href));
        const open = openCategory === cat.label;
        return (
          <div
            key={cat.label}
            className="relative"
            onMouseEnter={hoverCapable ? () => setOpenCategory(cat.label) : undefined}
            onMouseLeave={hoverCapable ? () => setOpenCategory((prev) => (prev === cat.label ? null : prev)) : undefined}
          >
            <button
              type="button"
              onClick={() =>
                setOpenCategory((prev) => {
                  // Auf Hover-fähigen Geräten übernimmt schon der Mauszeiger
                  // das Schließen (onMouseLeave) — ein Klick auf eine bereits
                  // per Hover geöffnete Kategorie soll sie nur offen halten,
                  // nicht zuklappen (sonst bliebe sie zu, bis die Maus die
                  // Kategorie verlässt und erneut betritt, weil kein neues
                  // mouseenter mehr feuert).
                  if (hoverCapable) return cat.label;
                  return prev === cat.label ? null : cat.label;
                })
              }
              className={`rounded-full px-3.5 py-1.5 transition-colors inline-flex items-center gap-1.5 ${
                categoryActive ? "bg-white/10 text-[var(--rk-ink)]" : "text-[var(--rk-ink-muted)] hover:text-[var(--rk-ink)]"
              }`}
            >
              {cat.label}
              <svg width="8" height="8" viewBox="0 0 8 8" fill="none" className="opacity-60 shrink-0">
                <path d="M1.5 2.5L4 5l2.5-2.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </button>
            {open && (
              <div className="absolute left-0 top-full pt-1.5 z-40">
                <div className="min-w-[12rem] bg-[var(--rk-surface)] border border-white/10 rounded-xl p-1.5 flex flex-col gap-0.5 shadow-xl shadow-black/40">
                  {cat.links.map((link) => {
                    const active = isActive(pathname, search, link.href);
                    return (
                      <Link
                        key={link.href}
                        href={link.href}
                        onClick={() => setOpenCategory(null)}
                        className={`rounded-lg px-3 py-1.5 normal-case tracking-normal text-[0.8rem] transition-colors ${
                          active ? "bg-white/10 text-[var(--rk-ink)]" : "text-[var(--rk-ink-muted)] hover:text-[var(--rk-ink)] hover:bg-white/5"
                        }`}
                      >
                        {link.label}
                      </Link>
                    );
                  })}
                </div>
              </div>
            )}
          </div>
        );
      })}
      <GlobalSearchBox />
      </nav>
    </div>
  );
}
