"use client";

import * as React from "react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import {
  Users,
  Search,
  MoreHorizontal,
  Eye,
  Merge,
  Trash2,
  Link2,
  Loader2,
  ChevronLeft,
  ChevronRight,
  CalendarPlus,
} from "lucide-react";
import { formatDistanceToNow, differenceInDays, format } from "date-fns";

import { Header } from "@/components/layout/header";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

type PersonRow = {
  id: string;
  firstName: string;
  lastName: string;
  email: string | null;
  cellPhone: string | null;
  createdAt: string;
  updatedAt: string;
  _count: { cards: number };
  cards?: { createdAt: string }[];
};

type PeopleResponse = {
  people: PersonRow[];
  total: number;
  page: number;
  limit: number;
};

function formatDate(dateStr: string): string {
  const d = new Date(dateStr);
  if (differenceInDays(new Date(), d) < 30) {
    return formatDistanceToNow(d, { addSuffix: true });
  }
  return format(d, "MMM d, yyyy");
}

export default function PeoplePage() {
  const router = useRouter();

  const [data, setData] = React.useState<PeopleResponse | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [search, setSearch] = React.useState("");
  const [debouncedSearch, setDebouncedSearch] = React.useState("");
  const [page, setPage] = React.useState(1);
  const [linking, setLinking] = React.useState(false);
  const [deletingId, setDeletingId] = React.useState<string | null>(null);
  const limit = 20;

  React.useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedSearch(search);
      setPage(1);
    }, 300);
    return () => clearTimeout(timer);
  }, [search]);

  const fetchPeople = React.useCallback(async () => {
    setLoading(true);
    try {
      const params = new URLSearchParams({
        page: String(page),
        limit: String(limit),
      });
      if (debouncedSearch) params.set("search", debouncedSearch);

      const res = await fetch(`/api/people?${params.toString()}`);
      if (!res.ok) throw new Error();
      const json = await res.json();
      setData(json);
    } catch {
      toast.error("Failed to load people");
    } finally {
      setLoading(false);
    }
  }, [page, debouncedSearch]);

  React.useEffect(() => {
    fetchPeople();
  }, [fetchPeople]);

  const totalPages = data ? Math.max(1, Math.ceil(data.total / limit)) : 1;

  const newThisMonth = React.useMemo(() => {
    if (!data) return 0;
    const now = new Date();
    const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
    return data.people.filter(
      (p) => new Date(p.createdAt) >= startOfMonth
    ).length;
  }, [data]);

  const handleLinkCards = async () => {
    setLinking(true);
    try {
      const res = await fetch("/api/people/link", { method: "POST" });
      if (!res.ok) throw new Error();
      const result = await res.json();
      toast.success(
        `Linked ${result.linked} card${result.linked !== 1 ? "s" : ""}, created ${result.created} new ${result.created !== 1 ? "people" : "person"}`
      );
      fetchPeople();
    } catch {
      toast.error("Failed to link cards");
    } finally {
      setLinking(false);
    }
  };

  const handleDelete = async (personId: string) => {
    setDeletingId(personId);
    try {
      const res = await fetch(`/api/people/${personId}`, { method: "DELETE" });
      if (!res.ok) throw new Error();
      toast.success("Person deleted");
      fetchPeople();
    } catch {
      toast.error("Failed to delete person");
    } finally {
      setDeletingId(null);
    }
  };

  if (loading && !data) {
    return (
      <div className="space-y-6">
        <Skeleton className="h-10 w-64 rounded-xl" />
        <Skeleton className="h-4 w-80 rounded-lg" />
        <Skeleton className="h-10 w-full rounded-xl" />
        <div className="grid grid-cols-2 gap-3">
          <Skeleton className="h-20 rounded-2xl" />
          <Skeleton className="h-20 rounded-2xl" />
        </div>
        <div className="space-y-2">
          {Array.from({ length: 6 }).map((_, i) => (
            <Skeleton key={i} className="h-12 w-full rounded-xl" />
          ))}
        </div>
      </div>
    );
  }

  const people = data?.people ?? [];
  const isEmpty = !loading && people.length === 0 && !debouncedSearch;
  const noResults = !loading && people.length === 0 && !!debouncedSearch;

  return (
    <div className="space-y-6">
      <Header
        title="People"
        description="Contact directory from scanned response cards"
        icon={Users}
      >
        <Button
          variant="outline"
          size="sm"
          className="rounded-xl"
          onClick={handleLinkCards}
          disabled={linking}
        >
          {linking ? (
            <>
              <Loader2 className="mr-1 size-4 animate-spin" /> Linking...
            </>
          ) : (
            <>
              <Link2 className="mr-1 size-4" /> Link Unlinked Cards
            </>
          )}
        </Button>
      </Header>

      {isEmpty ? (
        <div className="glass-card flex flex-col items-center justify-center rounded-2xl p-12 text-center">
          <Users className="mb-4 size-12 text-muted-foreground/40" />
          <h2 className="text-lg font-semibold">No people yet</h2>
          <p className="mt-1 max-w-sm text-sm text-muted-foreground">
            People are automatically created when response cards are processed.
          </p>
        </div>
      ) : (
        <>
          <div className="relative">
            <Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              placeholder="Search by name or email..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="pl-9"
            />
          </div>

          <div className="grid grid-cols-2 gap-3">
            <div className="gradient-stat flex flex-col gap-1 rounded-2xl p-4">
              <div className="flex size-9 items-center justify-center rounded-xl bg-primary/10 text-primary">
                <Users className="size-5" />
              </div>
              <p className="mt-1 text-2xl font-bold tracking-tight">
                {data?.total.toLocaleString() ?? "—"}
              </p>
              <p className="text-xs text-muted-foreground">Total People</p>
            </div>
            <div className="gradient-stat flex flex-col gap-1 rounded-2xl p-4">
              <div className="flex size-9 items-center justify-center rounded-xl bg-emerald-500/10 text-emerald-600 dark:text-emerald-400">
                <CalendarPlus className="size-5" />
              </div>
              <p className="mt-1 text-2xl font-bold tracking-tight">
                {newThisMonth}
              </p>
              <p className="text-xs text-muted-foreground">New This Month</p>
            </div>
          </div>

          {noResults ? (
            <div className="glass-card flex flex-col items-center justify-center rounded-2xl p-12 text-center">
              <Search className="mb-4 size-10 text-muted-foreground/40" />
              <h2 className="text-lg font-semibold">No results</h2>
              <p className="mt-1 text-sm text-muted-foreground">
                No people match &ldquo;{debouncedSearch}&rdquo;
              </p>
            </div>
          ) : (
            <div className="glass-card overflow-hidden rounded-2xl">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Name</TableHead>
                    <TableHead className="hidden sm:table-cell">
                      Email
                    </TableHead>
                    <TableHead className="hidden md:table-cell">
                      Phone
                    </TableHead>
                    <TableHead className="text-center">Cards</TableHead>
                    <TableHead className="hidden lg:table-cell">
                      Last Seen
                    </TableHead>
                    <TableHead className="w-10" />
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {loading
                    ? Array.from({ length: 5 }).map((_, i) => (
                        <TableRow key={i}>
                          <TableCell>
                            <Skeleton className="h-5 w-32 rounded" />
                          </TableCell>
                          <TableCell className="hidden sm:table-cell">
                            <Skeleton className="h-4 w-40 rounded" />
                          </TableCell>
                          <TableCell className="hidden md:table-cell">
                            <Skeleton className="h-4 w-28 rounded" />
                          </TableCell>
                          <TableCell className="text-center">
                            <Skeleton className="mx-auto h-5 w-8 rounded-full" />
                          </TableCell>
                          <TableCell className="hidden lg:table-cell">
                            <Skeleton className="h-4 w-24 rounded" />
                          </TableCell>
                          <TableCell>
                            <Skeleton className="h-6 w-6 rounded" />
                          </TableCell>
                        </TableRow>
                      ))
                    : people.map((person) => {
                        const lastSeen =
                          person.cards?.[0]?.createdAt ?? person.updatedAt;
                        return (
                          <TableRow key={person.id}>
                            <TableCell>
                              <button
                                className="font-medium text-foreground hover:text-primary hover:underline"
                                onClick={() =>
                                  router.push(`/people/${person.id}`)
                                }
                              >
                                {person.firstName} {person.lastName}
                              </button>
                            </TableCell>
                            <TableCell className="hidden text-muted-foreground sm:table-cell">
                              {person.email || "—"}
                            </TableCell>
                            <TableCell className="hidden text-muted-foreground md:table-cell">
                              {person.cellPhone || "—"}
                            </TableCell>
                            <TableCell className="text-center">
                              <Badge variant="secondary">
                                {person._count.cards}
                              </Badge>
                            </TableCell>
                            <TableCell className="hidden text-muted-foreground lg:table-cell">
                              {formatDate(lastSeen)}
                            </TableCell>
                            <TableCell>
                              <DropdownMenu>
                                <DropdownMenuTrigger
                                  render={
                                    <Button
                                      variant="ghost"
                                      size="icon-xs"
                                    />
                                  }
                                >
                                  <MoreHorizontal className="size-4" />
                                </DropdownMenuTrigger>
                                <DropdownMenuContent align="end">
                                  <DropdownMenuItem
                                    onClick={() =>
                                      router.push(`/people/${person.id}`)
                                    }
                                  >
                                    <Eye className="mr-2 size-4" /> View
                                  </DropdownMenuItem>
                                  <DropdownMenuItem
                                    onClick={() =>
                                      router.push(
                                        `/people/${person.id}?action=merge`
                                      )
                                    }
                                  >
                                    <Merge className="mr-2 size-4" /> Merge
                                  </DropdownMenuItem>
                                  <DropdownMenuSeparator />
                                  <DropdownMenuItem
                                    variant="destructive"
                                    disabled={deletingId === person.id}
                                    onClick={() => handleDelete(person.id)}
                                  >
                                    <Trash2 className="mr-2 size-4" /> Delete
                                  </DropdownMenuItem>
                                </DropdownMenuContent>
                              </DropdownMenu>
                            </TableCell>
                          </TableRow>
                        );
                      })}
                </TableBody>
              </Table>
            </div>
          )}

          {totalPages > 1 && (
            <div className="flex items-center justify-between">
              <p className="text-sm text-muted-foreground">
                Page {page} of {totalPages}
              </p>
              <div className="flex gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  className="rounded-xl"
                  disabled={page <= 1}
                  onClick={() => setPage((p) => p - 1)}
                >
                  <ChevronLeft className="mr-1 size-4" /> Previous
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  className="rounded-xl"
                  disabled={page >= totalPages}
                  onClick={() => setPage((p) => p + 1)}
                >
                  Next <ChevronRight className="ml-1 size-4" />
                </Button>
              </div>
            </div>
          )}
        </>
      )}
    </div>
  );
}
