import {
  Baby,
  Contact,
  Mail,
  Phone,
  Search,
  ShieldCheck,
  SlidersHorizontal,
  UserRound,
} from "lucide-react";

import { requireKitaSession } from "@/lib/auth-utils";
import { prisma } from "@/lib/prisma";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";

export const metadata = { title: "Adressbuch · Kita-Planer" };

type DirectoryFamilyDto = {
  id: string;
  name: string;
  children: {
    id: string;
    firstName: string;
    lastName: string;
  }[];
  parents: {
    id: string;
    firstName: string;
    lastName: string;
    hasDirectoryOptIn: boolean;
    email?: string;
    phone?: string;
    duties: {
      id: string;
      name: string;
    }[];
  }[];
};

export default async function AdressbuchPage() {
  const session = await requireKitaSession();

  const familyRows = await prisma.family.findMany({
    where: {
      kitaId: session.user.kitaId,
      users: {
        some: {
          directoryOptInAt: { not: null },
        },
      },
    },
    select: {
      id: true,
      name: true,
      children: {
        select: {
          id: true,
          firstName: true,
          lastName: true,
        },
        orderBy: [{ lastName: "asc" }, { firstName: "asc" }],
      },
      users: {
        select: {
          id: true,
          firstName: true,
          lastName: true,
          directoryOptInAt: true,
          dutyAssignments: {
            select: {
              id: true,
              duty: {
                select: {
                  name: true,
                },
              },
            },
          },
        },
        orderBy: [{ lastName: "asc" }, { firstName: "asc" }],
      },
    },
    orderBy: { name: "asc" },
  });

  const visibleContactRows = await prisma.user.findMany({
    where: {
      kitaId: session.user.kitaId,
      directoryOptInAt: { not: null },
      familyId: { in: familyRows.map((family) => family.id) },
    },
    select: {
      id: true,
      email: true,
      phone: true,
    },
  });
  const visibleContactsByUserId = new Map(
    visibleContactRows.map((user) => [user.id, user]),
  );

  const families: DirectoryFamilyDto[] = familyRows.map((family) => ({
    id: family.id,
    name: family.name,
    children: family.children,
    parents: family.users.map((user) => {
      const hasDirectoryOptIn = !!user.directoryOptInAt;
      const contact = visibleContactsByUserId.get(user.id);
      return {
        id: user.id,
        firstName: user.firstName,
        lastName: user.lastName,
        hasDirectoryOptIn,
        email: contact?.email,
        phone: contact?.phone ?? undefined,
        duties: user.dutyAssignments.map((assignment) => ({
          id: assignment.id,
          name: assignment.duty.name,
        })),
      };
    }),
  }));

  const visibleParentCount = families.reduce(
    (count, family) =>
      count + family.parents.filter((parent) => parent.hasDirectoryOptIn).length,
    0,
  );
  const childCount = families.reduce(
    (count, family) => count + family.children.length,
    0,
  );
  const groupedFamilies = groupFamiliesByInitial(families);

  return (
    <div className="mx-auto max-w-[1280px] px-11 py-9 pb-16 max-[760px]:px-5">
      <header className="mb-7 flex items-end justify-between gap-8 max-[900px]:flex-col max-[900px]:items-start">
        <div>
          <p className="text-[11px] font-semibold uppercase text-[var(--accent-deep)] [letter-spacing:0.18em]">
            KONTAKTE · ADRESSBUCH
          </p>
          <h1 className="mt-2 text-[36px] font-normal leading-tight tracking-[-0.025em] text-[var(--ink)]">
            Freigegebene{" "}
            <em className="font-normal italic text-[var(--accent-deep)]">
              Kontakte
            </em>
          </h1>
          <p className="mt-2 max-w-2xl text-[15px] leading-6 text-[var(--ink-soft)]">
            Haushalte und Kontaktdaten, die explizit für das interne
            Kita-Adressbuch freigegeben wurden.
          </p>
        </div>
        <div className="flex shrink-0 flex-wrap gap-2">
          <span className="inline-flex h-9 items-center gap-2 rounded-full border border-[var(--hairline)] bg-[var(--surface)] px-4 text-[13px] font-semibold text-[var(--ink-soft)] tabular-nums">
            <ShieldCheck className="h-4 w-4 text-[var(--accent-deep)] [stroke-width:1.7]" />
            {visibleParentCount} sichtbar
          </span>
          <Button variant="ghost" size="sm">
            <SlidersHorizontal className="h-4 w-4 [stroke-width:1.7]" />
            Sichtbarkeit
          </Button>
        </div>
      </header>

      {families.length === 0 ? (
        <Card className="border-dashed">
          <CardContent className="flex max-h-[280px] min-h-[260px] flex-col items-center justify-center px-6 py-12 text-center">
            <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-[var(--accent-soft)] text-[var(--accent-deep)]">
              <Contact className="h-6 w-6 [stroke-width:1.7]" />
            </div>
            <h3 className="text-lg font-medium tracking-[-0.02em] text-[var(--ink)]">
              Keine freigegebenen Kontakte
            </h3>
            <p className="mt-2 max-w-sm text-sm leading-6 text-[var(--ink-soft)]">
              Sobald mindestens ein Elternteil eines Haushalts zustimmt,
              erscheint die Familie hier.
            </p>
          </CardContent>
        </Card>
      ) : (
        <div className="space-y-5">
          <div className="flex flex-wrap items-center justify-between gap-3">
            <div className="flex flex-wrap gap-2">
              <DirectoryMetric label="Haushalte" value={families.length} />
              <DirectoryMetric label="Kontakte" value={visibleParentCount} />
              <DirectoryMetric label="Kinder" value={childCount} />
            </div>
            <div className="relative min-w-72 max-[760px]:w-full max-[760px]:min-w-0">
              <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--ink-muted)] [stroke-width:1.7]" />
              <Input
                placeholder="Familien, Namen oder E-Mail suchen"
                className="pl-9"
              />
            </div>
          </div>

          <div className="flex flex-wrap gap-1.5">
            {["Alle Gruppen", "Mit Telefon", "Mit Ämtern", "Nur Opt-in"].map(
              (filter, index) => (
                <span
                  key={filter}
                  className={[
                    "inline-flex h-9 items-center rounded-full border px-3 text-[13px] font-medium",
                    index === 0
                      ? "border-[var(--accent-mid)] bg-[var(--accent-soft)] text-[var(--accent-deep)]"
                      : "border-[var(--hairline)] bg-[var(--surface)] text-[var(--ink-soft)]",
                  ].join(" ")}
                >
                  {filter}
                </span>
              ),
            )}
          </div>

          <Card className="overflow-hidden p-0">
            {groupedFamilies.map((group) => (
              <section key={group.initial}>
                <div className="flex items-center justify-between border-b border-[var(--hairline-soft)] bg-[var(--surface-2)] px-5 py-3">
                  <h2 className="text-[11px] font-semibold uppercase text-[var(--ink-muted)] [letter-spacing:0.14em]">
                    {group.initial}
                  </h2>
                  <span className="text-[11px] font-semibold text-[var(--ink-muted)] tabular-nums">
                    {group.families.length}
                  </span>
                </div>
                <div className="divide-y divide-[var(--hairline-soft)]">
                  {group.families.map((family) => (
                    <FamilyDirectoryRow key={family.id} family={family} />
                  ))}
                </div>
              </section>
            ))}
          </Card>
        </div>
      )}
    </div>
  );
}

function FamilyDirectoryRow({ family }: { family: DirectoryFamilyDto }) {
  const visibleParents = family.parents.filter(
    (parent) => parent.hasDirectoryOptIn,
  );
  const duties = family.parents.flatMap((parent) => parent.duties);

  return (
    <div className="grid grid-cols-[minmax(220px,0.8fr)_minmax(0,1.4fr)_minmax(220px,1fr)] gap-5 px-5 py-4 transition-colors hover:bg-[var(--surface-2)] max-[1050px]:grid-cols-1">
      <div className="flex min-w-0 gap-3">
        <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-[var(--accent-soft)] text-sm font-semibold uppercase text-[var(--accent-deep)]">
          {family.name.slice(0, 1)}
        </div>
        <div className="min-w-0">
          <h3 className="truncate text-[15px] font-semibold text-[var(--ink)]">
            {family.name}
          </h3>
          <p className="mt-1 flex flex-wrap items-center gap-1.5 text-[13px] text-[var(--ink-soft)]">
            <Baby className="h-3.5 w-3.5 [stroke-width:1.7]" />
            {family.children.length === 0
              ? "Keine Kinder hinterlegt"
              : family.children
                  .map((child) => `${child.firstName} ${child.lastName}`)
                  .join(", ")}
          </p>
        </div>
      </div>

      <div className="grid gap-3">
        {family.parents.map((user) => (
          <div key={user.id} className="min-w-0">
            <div className="flex flex-wrap items-center gap-2">
              <UserRound className="h-3.5 w-3.5 text-[var(--ink-muted)] [stroke-width:1.7]" />
              <p className="text-sm font-medium text-[var(--ink)]">
                {user.firstName} {user.lastName}
              </p>
              {user.hasDirectoryOptIn ? (
                <Badge variant="success">Opt-in</Badge>
              ) : (
                <span className="text-xs italic text-[var(--ink-faint)]">
                  nicht freigegeben
                </span>
              )}
            </div>

            {user.hasDirectoryOptIn && (
              <div className="mt-1 flex flex-wrap gap-x-4 gap-y-1 pl-5 text-[13px] text-[var(--ink-soft)]">
                {user.email && (
                  <a
                    href={`mailto:${user.email}`}
                    className="inline-flex min-w-0 items-center gap-1.5 hover:text-[var(--accent-deep)]"
                  >
                    <Mail className="h-3.5 w-3.5 shrink-0 [stroke-width:1.7]" />
                    <span className="break-words [overflow-wrap:anywhere]">
                      {user.email}
                    </span>
                  </a>
                )}
                {user.phone ? (
                  <a
                    href={`tel:${user.phone}`}
                    className="inline-flex items-center gap-1.5 hover:text-[var(--accent-deep)]"
                  >
                    <Phone className="h-3.5 w-3.5 shrink-0 [stroke-width:1.7]" />
                    {user.phone}
                  </a>
                ) : (
                  <span className="italic text-[var(--ink-faint)]">
                    Keine Telefonnummer
                  </span>
                )}
              </div>
            )}
          </div>
        ))}
      </div>

      <div className="flex flex-col items-end justify-between gap-3 max-[1050px]:items-start">
        <div className="flex flex-wrap justify-end gap-1.5 max-[1050px]:justify-start">
          <Badge variant="secondary">
            {visibleParents.length} von {family.parents.length} sichtbar
          </Badge>
          {duties.map((duty) => (
            <Badge
              key={duty.id}
              variant="outline"
              className="border-[var(--accent-mid)] bg-[var(--accent-soft)] text-[var(--accent-deep)]"
            >
              {duty.name}
            </Badge>
          ))}
        </div>
        <Button variant="ghost" size="sm">
          Kontakt öffnen
        </Button>
      </div>
    </div>
  );
}

function DirectoryMetric({ label, value }: { label: string; value: number }) {
  return (
    <span className="inline-flex h-9 items-center gap-2 rounded-full border border-[var(--hairline)] bg-[var(--surface)] px-3 text-[13px] font-semibold text-[var(--ink-soft)]">
      <span className="text-[var(--ink)] tabular-nums">{value}</span>
      {label}
    </span>
  );
}

function groupFamiliesByInitial(families: DirectoryFamilyDto[]) {
  const groups = new Map<string, DirectoryFamilyDto[]>();

  families.forEach((family) => {
    const initial = family.name.trim().slice(0, 1).toLocaleUpperCase("de-DE");
    const key = initial || "#";
    groups.set(key, [...(groups.get(key) ?? []), family]);
  });

  return Array.from(groups.entries()).map(([initial, groupFamilies]) => ({
    initial,
    families: groupFamilies,
  }));
}
