"use client";

import { ChevronDown, ChevronRight, Search } from "lucide-react";
import Link from "next/link";
import { useMemo, useState } from "react";
import { Avatar } from "@/components/ui/Avatar";
import type { OrgEmployee } from "./types";

export function EmployeeTree({ employees }: { employees: OrgEmployee[] }) {
  const [expanded, setExpanded] = useState<Set<string>>(new Set());
  const [query, setQuery] = useState("");

  const { childrenByManager, totalReportsById, root } = useMemo(() => {
    const byManager = new Map<string, OrgEmployee[]>();
    for (const e of employees) {
      const key = e.manager_id ?? "__root__";
      if (!byManager.has(key)) byManager.set(key, []);
      byManager.get(key)!.push(e);
    }
    for (const list of byManager.values()) list.sort((a, b) => a.last_name.localeCompare(b.last_name));

    const totals = new Map<string, number>();
    function countTotal(id: string): number {
      if (totals.has(id)) return totals.get(id)!;
      const direct = byManager.get(id) ?? [];
      let total = direct.length;
      for (const child of direct) total += countTotal(child.id);
      totals.set(id, total);
      return total;
    }
    for (const e of employees) countTotal(e.id);

    return { childrenByManager: byManager, totalReportsById: totals, root: byManager.get("__root__") ?? [] };
  }, [employees]);

  const matchIds = useMemo(() => {
    if (query.trim().length < 2) return null;
    const q = query.trim().toLowerCase();
    const matches = new Set<string>();
    for (const e of employees) {
      if (
        `${e.first_name} ${e.last_name}`.toLowerCase().includes(q) ||
        e.job_title.toLowerCase().includes(q) ||
        String(e.personnel_number).includes(q)
      ) {
        matches.add(e.id);
      }
    }
    return matches;
  }, [query, employees]);

  const ancestorExpandIds = useMemo(() => {
    if (!matchIds) return null;
    const byId = new Map(employees.map((e) => [e.id, e]));
    const toExpand = new Set<string>();
    for (const id of matchIds) {
      let current = byId.get(id);
      while (current?.manager_id) {
        toExpand.add(current.manager_id);
        current = byId.get(current.manager_id);
      }
    }
    return toExpand;
  }, [matchIds, employees]);

  function toggle(id: string) {
    setExpanded((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }

  function isExpanded(id: string): boolean {
    return expanded.has(id) || (ancestorExpandIds?.has(id) ?? false);
  }

  function renderNode(e: OrgEmployee, depth: number) {
    const children = childrenByManager.get(e.id) ?? [];
    const hasChildren = children.length > 0;
    const expandedNow = isExpanded(e.id);
    const isMatch = matchIds?.has(e.id) ?? false;
    const totalReports = totalReportsById.get(e.id) ?? 0;

    return (
      <div key={e.id}>
        <div
          className={`flex items-center gap-2 rounded px-2 py-1.5 hover:bg-surface ${isMatch ? "bg-brand-100" : ""}`}
          style={{ paddingLeft: depth * 24 + 8 }}
        >
          {hasChildren ? (
            <button type="button" onClick={() => toggle(e.id)} className="shrink-0 text-ink-muted">
              {expandedNow ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
            </button>
          ) : (
            <span className="w-4 shrink-0" />
          )}
          <Avatar firstName={e.first_name} lastName={e.last_name} size="sm" />
          <Link href={`/employees/${e.id}`} className="flex-1 hover:underline">
            <span className="text-sm font-semibold text-ink">
              {e.first_name} {e.last_name}
            </span>
            <span className="ml-2 text-xs text-ink-muted">{e.job_title}</span>
          </Link>
          {hasChildren && (
            <span className="shrink-0 text-xs text-ink-muted">
              {children.length} direkt · {totalReports} gesamt
            </span>
          )}
        </div>
        {hasChildren && expandedNow && <div>{children.map((c) => renderNode(c, depth + 1))}</div>}
      </div>
    );
  }

  return (
    <div className="rounded border border-border bg-white p-4">
      <div className="mb-4 flex flex-wrap items-center gap-3">
        <div className="flex min-w-[240px] flex-1 items-center gap-2 rounded border border-border px-3 py-2">
          <Search className="h-4 w-4 shrink-0 text-ink-muted" />
          <input
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder="Name, Pers.-Nr., Titel…"
            className="w-full text-sm text-ink outline-none placeholder:text-ink-muted"
          />
        </div>
        <button
          type="button"
          onClick={() => setExpanded(new Set(root.map((r) => r.id)))}
          className="rounded border border-border px-3 py-1.5 text-sm font-semibold text-ink-body hover:bg-surface"
        >
          Bereiche anzeigen
        </button>
        <button
          type="button"
          onClick={() => setExpanded(new Set())}
          className="rounded border border-border px-3 py-1.5 text-sm font-semibold text-ink-body hover:bg-surface"
        >
          Alles einklappen
        </button>
      </div>
      <div>{root.map((r) => renderNode(r, 0))}</div>
    </div>
  );
}
