import * as React from "react";
import { Search, X } from "lucide-react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Spinner } from "@/components/ui/spinner";
import {
  Table,
  TableHeader,
  TableHead,
  TableBody,
  TableRow,
  TableCell,
} from "@/components/ui/table";
import { TablePagination } from "@/components/ui/pagination";
import { cn } from "@/lib/utils";

export interface LeadContact {
  id: string;
  name: string;
  email?: string;
  phone?: string;
}

export interface AddLeadModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** Contacts for the current page — server-side pagination, parent slices. */
  contacts: LeadContact[];
  /** Total contacts matching the current search (drives pagination). */
  total: number;
  isLoading?: boolean;
  isSubmitting?: boolean;
  searchValue?: string;
  onSearchChange?: (value: string) => void;
  /** 0-indexed current page. */
  page?: number;
  pageSize?: number;
  pageSizeOptions?: number[];
  onPageChange?: (page: number) => void;
  onPageSizeChange?: (pageSize: number) => void;
  onAdd?: (selectedIds: string[]) => void;
  className?: string;
}

function toggleInSet<T>(prev: Set<T>, value: T): Set<T> {
  const next = new Set(prev);
  next.has(value) ? next.delete(value) : next.add(value);
  return next;
}

export function AddLeadModal({
  open,
  onOpenChange,
  contacts,
  total,
  isLoading = false,
  isSubmitting = false,
  searchValue = "",
  onSearchChange,
  page = 0,
  pageSize = 10,
  pageSizeOptions,
  onPageChange,
  onPageSizeChange,
  onAdd,
  className,
}: AddLeadModalProps) {
  const [selectedIds, setSelectedIds] = React.useState<Set<string>>(new Set());

  React.useEffect(() => {
    if (open) setSelectedIds(new Set());
  }, [open]);

  const allPageSelected =
    contacts.length > 0 && contacts.every((c) => selectedIds.has(c.id));
  const somePageSelected = contacts.some((c) => selectedIds.has(c.id));

  function toggleAll() {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (allPageSelected) {
        contacts.forEach((c) => next.delete(c.id));
      } else {
        contacts.forEach((c) => next.add(c.id));
      }
      return next;
    });
  }

  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  return (
    <Dialog open={open} onOpenChange={isSubmitting ? undefined : onOpenChange}>
      <DialogContent size="2xl" className={className}>
        <DialogHeader>
          <DialogTitle>Add Lead</DialogTitle>
        </DialogHeader>

        <div className="relative">
          <Search className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
          <Input
            placeholder="Search clients…"
            value={searchValue}
            onChange={(e) => onSearchChange?.(e.target.value)}
            className="pl-8 pr-8"
            disabled={isSubmitting}
          />
          {searchValue && (
            <Button
              type="button"
              variant="ghost"
              size="icon"
              onClick={() => onSearchChange?.("")}
              className="absolute right-2.5 top-1/2 size-6 -translate-y-1/2 text-muted-foreground hover:text-foreground"
              aria-label="Clear search"
            >
              <X className="size-3.5" />
            </Button>
          )}
        </div>

        <div className="relative min-h-[200px] overflow-auto border border-border">
          {isLoading && (
            <div className="absolute inset-0 z-10 flex items-center justify-center bg-background/60">
              <Spinner />
            </div>
          )}
          <Table>
            <TableHeader>
              <TableRow className="hover:bg-transparent">
                <TableHead className="w-10">
                  <span onClick={(e) => e.stopPropagation()}>
                    <Checkbox
                      checked={allPageSelected}
                      indeterminate={somePageSelected && !allPageSelected}
                      onCheckedChange={toggleAll}
                      aria-label="Select all on page"
                      disabled={contacts.length === 0 || isSubmitting}
                    />
                  </span>
                </TableHead>
                <TableHead>Name</TableHead>
                <TableHead>Email</TableHead>
                <TableHead>Phone</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {contacts.length === 0 && !isLoading ? (
                <TableRow className="hover:bg-transparent">
                  <TableCell
                    colSpan={4}
                    className="py-10 text-center text-muted-foreground"
                  >
                    No clients found.
                  </TableCell>
                </TableRow>
              ) : (
                contacts.map((contact) => {
                  const isSelected = selectedIds.has(contact.id);
                  return (
                    <TableRow
                      key={contact.id}
                      data-state={isSelected ? "selected" : undefined}
                      className="cursor-pointer"
                      onClick={() =>
                        !isSubmitting &&
                        setSelectedIds((prev) => toggleInSet(prev, contact.id))
                      }
                    >
                      <TableCell className="h-12">
                        <span onClick={(e) => e.stopPropagation()}>
                          <Checkbox
                            checked={isSelected}
                            onCheckedChange={() =>
                              setSelectedIds((prev) =>
                                toggleInSet(prev, contact.id),
                              )
                            }
                            disabled={isSubmitting}
                          />
                        </span>
                      </TableCell>
                      <TableCell className="h-12 font-medium text-foreground">
                        {contact.name}
                      </TableCell>
                      <TableCell className="h-12 text-muted-foreground">
                        {contact.email ?? "—"}
                      </TableCell>
                      <TableCell className="h-12 text-muted-foreground">
                        {contact.phone ?? "—"}
                      </TableCell>
                    </TableRow>
                  );
                })
              )}
            </TableBody>
          </Table>
        </div>

        {/* TablePagination is 1-indexed; props are 0-indexed — converted here */}
        <div
          className={cn(
            (isLoading || isSubmitting) && "pointer-events-none opacity-50",
          )}
        >
          <TablePagination
            page={page + 1}
            pageCount={totalPages}
            pageSize={pageSize}
            pageSizeOptions={pageSizeOptions}
            selectedCount={selectedIds.size || undefined}
            totalCount={total}
            onPageChange={(p) => onPageChange?.(p - 1)}
            onPageSizeChange={(size) => {
              onPageSizeChange?.(size);
              onPageChange?.(0);
            }}
          />
        </div>

        <DialogFooter>
          <Button
            variant="outline"
            onClick={() => onOpenChange(false)}
            disabled={isSubmitting}
          >
            Cancel
          </Button>
          <Button
            onClick={() => onAdd?.([...selectedIds])}
            disabled={selectedIds.size === 0 || isSubmitting}
          >
            {isSubmitting
              ? "Adding…"
              : `Add${selectedIds.size > 0 ? ` (${selectedIds.size})` : ""}`}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
