"use client";

import { useCallback, useEffect, useMemo, useState } from "react";

import {
  type ColumnDef,
  type ColumnFiltersState,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  type SortingState,
  useReactTable,
} from "@tanstack/react-table";
import { CalendarDays, Mail, MoreHorizontal, Phone, Plus, Search, User } from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { Sheet, SheetContent, SheetFooter, SheetHeader, SheetTitle } from "@/components/ui/sheet";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
  type Client,
  type ClientStatus,
  type ClientType,
  clients as initialClients,
  staffMembers,
} from "@/data/clients";
import { getRegisteredClients, type RegisteredClientRecord } from "@/lib/auth";

import { ClientSheet } from "./client-sheet";

const typeVariant: Record<ClientType, "default" | "secondary" | "outline" | "destructive"> = {
  Corporate: "default",
  Individual: "secondary",
  Trust: "outline",
  Partnership: "destructive",
};

const statusVariant: Record<ClientStatus, "default" | "secondary" | "destructive"> = {
  Active: "default",
  Inactive: "secondary",
  Prospect: "destructive",
};

const staffMap = Object.fromEntries(staffMembers.map((s) => [s.id, s.name]));

function ClientDetailSheet({
  client,
  open,
  onOpenChange,
  onEdit,
}: {
  client: Client | null;
  open: boolean;
  onOpenChange: (v: boolean) => void;
  onEdit: (c: Client) => void;
}) {
  if (!client) return null;

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className="w-full overflow-y-auto sm:max-w-xl">
        <SheetHeader>
          <SheetTitle>{client.name}</SheetTitle>
          <div className="flex gap-1.5">
            <Badge variant={typeVariant[client.type]} className="text-xs">
              {client.type}
            </Badge>
            <Badge variant={statusVariant[client.status]} className="text-xs">
              {client.status}
            </Badge>
          </div>
        </SheetHeader>

        <div className="mt-4 flex flex-col gap-5 px-4">
          <div className="space-y-2">
            <p className="font-semibold text-muted-foreground text-xs uppercase tracking-wider">Contact</p>
            <div className="space-y-1.5">
              <div className="flex items-center gap-2 text-sm">
                <Mail className="size-3.5 shrink-0 text-muted-foreground" />
                <a href={`mailto:${client.email}`} className="hover:underline">
                  {client.email}
                </a>
              </div>
              <div className="flex items-center gap-2 text-sm">
                <Phone className="size-3.5 shrink-0 text-muted-foreground" />
                {client.phone}
              </div>
              {client.address && <p className="pl-5 text-muted-foreground text-sm">{client.address}</p>}
            </div>
          </div>

          <Separator />

          <div className="grid grid-cols-2 gap-3">
            {[
              { icon: User, label: "Assigned Staff", value: staffMap[client.assignedStaffId] ?? "—" },
              { icon: User, label: "Backup Staff", value: staffMap[client.backupStaffId] ?? "—" },
              { icon: null, label: "Language", value: client.language === "FR" ? "French" : "English" },
              { icon: null, label: "Portal Status", value: client.portalStatus },
            ].map(({ label, value }) => (
              <div key={label} className="rounded-lg bg-muted/40 p-3">
                <p className="text-muted-foreground text-xs">{label}</p>
                <p className="mt-1 font-medium text-sm">{value}</p>
              </div>
            ))}
          </div>

          {(client.businessNumber || client.sin) && (
            <>
              <Separator />
              <div className="space-y-2">
                {client.businessNumber && (
                  <div className="flex items-center justify-between text-sm">
                    <span className="text-muted-foreground">Business Number</span>
                    <span className="font-medium font-mono">{client.businessNumber}</span>
                  </div>
                )}
                {client.sin && (
                  <div className="flex items-center justify-between text-sm">
                    <span className="text-muted-foreground">SIN</span>
                    <span className="font-medium font-mono">***-***-{client.sin.slice(-3)}</span>
                  </div>
                )}
              </div>
            </>
          )}

          {client.tags.length > 0 && (
            <>
              <Separator />
              <div>
                <p className="mb-2 font-semibold text-muted-foreground text-xs uppercase tracking-wider">Tags</p>
                <div className="flex flex-wrap gap-1.5">
                  {client.tags.map((tag) => (
                    <Badge key={tag} variant="outline" className="text-xs">
                      {tag}
                    </Badge>
                  ))}
                </div>
              </div>
            </>
          )}

          {client.notes && (
            <>
              <Separator />
              <div>
                <p className="mb-1 font-medium text-sm">Notes</p>
                <p className="text-muted-foreground text-sm">{client.notes}</p>
              </div>
            </>
          )}

          <div className="flex items-center gap-1.5 text-muted-foreground text-xs">
            <CalendarDays className="size-3" />
            Client since {new Date(client.createdAt).toLocaleDateString("en-CA", { month: "long", year: "numeric" })}
          </div>
        </div>

        <SheetFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Close
          </Button>
          <Button
            onClick={() => {
              onOpenChange(false);
              onEdit(client);
            }}
          >
            Edit Client
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

function registeredToClient(r: RegisteredClientRecord): Client {
  return {
    id: r.id,
    name: r.name,
    email: r.email,
    phone: r.phone,
    address: "",
    type: "Individual",
    status: "Active",
    language: r.language,
    tags: [r.source === "portal_registration" ? "Self-Registered" : "Intake Converted"],
    assignedStaffId: staffMembers[0]?.id ?? "",
    backupStaffId: "",
    portalStatus: r.source === "portal_registration" ? "Active" : "Pending",
    notes:
      r.source === "intake_conversion"
        ? `Converted from intake: ${r.sourceLabel ?? ""}`
        : "Registered via client portal.",
    createdAt: r.createdAt,
  };
}

export function ClientTable() {
  const [clientData, setClientData] = useState<Client[]>(initialClients);

  useEffect(() => {
    const registered = getRegisteredClients();
    if (registered.length === 0) return;
    setClientData((prev) => {
      const existingIds = new Set(prev.map((c) => c.id));
      const newClients = registered.filter((r) => !existingIds.has(r.id)).map(registeredToClient);
      return newClients.length > 0 ? [...newClients, ...prev] : prev;
    });
  }, []);
  const [sorting, setSorting] = useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
  const [globalFilter, setGlobalFilter] = useState("");
  const [typeFilter, setTypeFilter] = useState("all");
  const [statusFilter, setStatusFilter] = useState("all");

  const [detailClient, setDetailClient] = useState<Client | null>(null);
  const [detailOpen, setDetailOpen] = useState(false);
  const [editingClient, setEditingClient] = useState<Client | null>(null);
  const [editOpen, setEditOpen] = useState(false);

  const openDetail = useCallback((c: Client) => {
    setDetailClient(c);
    setDetailOpen(true);
  }, []);

  const openEdit = useCallback((c: Client) => {
    setEditingClient(c);
    setEditOpen(true);
  }, []);

  const deactivateClient = useCallback((id: string) => {
    setClientData((prev) => prev.map((c) => (c.id === id ? { ...c, status: "Inactive" as ClientStatus } : c)));
  }, []);

  const reactivateClient = useCallback((id: string) => {
    setClientData((prev) => prev.map((c) => (c.id === id ? { ...c, status: "Active" as ClientStatus } : c)));
  }, []);

  const sendPortalInvite = useCallback((id: string) => {
    setClientData((prev) => prev.map((c) => (c.id === id ? { ...c, portalStatus: "Pending" as const } : c)));
  }, []);

  const columns = useMemo<ColumnDef<Client>[]>(
    () => [
      {
        accessorKey: "name",
        header: "Client",
        cell: ({ row }) => (
          <button type="button" className="text-left hover:underline" onClick={() => openDetail(row.original)}>
            <p className="font-medium text-sm">{row.original.name}</p>
            <p className="text-muted-foreground text-xs">{row.original.email}</p>
          </button>
        ),
      },
      {
        accessorKey: "type",
        header: "Type",
        cell: ({ row }) => (
          <Badge variant={typeVariant[row.original.type]} className="text-xs">
            {row.original.type}
          </Badge>
        ),
      },
      {
        accessorKey: "language",
        header: "Lang",
        cell: ({ row }) => (
          <Badge variant="outline" className="text-xs">
            {row.original.language}
          </Badge>
        ),
      },
      {
        accessorKey: "assignedStaffId",
        header: "Assigned Staff",
        cell: ({ row }) => <span className="text-sm">{staffMap[row.original.assignedStaffId] ?? "—"}</span>,
      },
      {
        accessorKey: "tags",
        header: "Tags",
        cell: ({ row }) => (
          <div className="flex flex-wrap gap-1">
            {row.original.tags.slice(0, 2).map((tag) => (
              <Badge key={tag} variant="outline" className="px-1.5 py-0 text-xs">
                {tag}
              </Badge>
            ))}
            {row.original.tags.length > 2 && (
              <Badge variant="outline" className="px-1.5 py-0 text-xs">
                +{row.original.tags.length - 2}
              </Badge>
            )}
          </div>
        ),
      },
      {
        accessorKey: "status",
        header: "Status",
        cell: ({ row }) => (
          <Badge variant={statusVariant[row.original.status]} className="text-xs">
            {row.original.status}
          </Badge>
        ),
      },
      {
        accessorKey: "portalStatus",
        header: "Portal",
        cell: ({ row }) => {
          const v = row.original.portalStatus;
          return (
            <Badge variant={v === "Active" ? "default" : v === "Pending" ? "secondary" : "outline"} className="text-xs">
              {v}
            </Badge>
          );
        },
      },
      {
        id: "actions",
        cell: ({ row }) => {
          const c = row.original;
          return (
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button variant="ghost" size="icon" className="size-8">
                  <MoreHorizontal className="size-4" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end">
                <DropdownMenuLabel>Actions</DropdownMenuLabel>
                <DropdownMenuSeparator />
                <DropdownMenuItem onClick={() => openDetail(c)}>View Details</DropdownMenuItem>
                <DropdownMenuItem onClick={() => openEdit(c)}>Edit Client</DropdownMenuItem>
                {c.portalStatus !== "Active" && (
                  <DropdownMenuItem onClick={() => sendPortalInvite(c.id)}>
                    {c.portalStatus === "Pending" ? "Resend Portal Invite" : "Send Portal Invite"}
                  </DropdownMenuItem>
                )}
                <DropdownMenuSeparator />
                {c.status !== "Inactive" ? (
                  <DropdownMenuItem className="text-destructive" onClick={() => deactivateClient(c.id)}>
                    Deactivate
                  </DropdownMenuItem>
                ) : (
                  <DropdownMenuItem onClick={() => reactivateClient(c.id)}>Reactivate</DropdownMenuItem>
                )}
              </DropdownMenuContent>
            </DropdownMenu>
          );
        },
      },
    ],
    [openDetail, openEdit, deactivateClient, reactivateClient, sendPortalInvite],
  );

  const filtered = useMemo(
    () =>
      clientData.filter((c) => {
        if (typeFilter !== "all" && c.type !== typeFilter) return false;
        if (statusFilter !== "all" && c.status !== statusFilter) return false;
        if (globalFilter) {
          const q = globalFilter.toLowerCase();
          const staff = staffMap[c.assignedStaffId]?.toLowerCase() ?? "";
          const matchesText =
            c.name.toLowerCase().includes(q) ||
            c.email.toLowerCase().includes(q) ||
            c.phone.toLowerCase().includes(q) ||
            staff.includes(q) ||
            c.type.toLowerCase().includes(q) ||
            c.tags.some((t) => t.toLowerCase().includes(q));
          if (!matchesText) return false;
        }
        return true;
      }),
    [clientData, typeFilter, statusFilter, globalFilter],
  );

  const table = useReactTable({
    data: filtered,
    columns,
    state: { sorting, columnFilters },
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: { pagination: { pageSize: 15 } },
  });

  return (
    <div className="flex flex-col gap-4">
      <div className="flex flex-wrap items-center gap-3">
        <div className="relative min-w-[200px] flex-1">
          <Search className="absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            placeholder="Search clients..."
            value={globalFilter}
            onChange={(e) => setGlobalFilter(e.target.value)}
            className="pl-9"
          />
        </div>
        <Select value={typeFilter} onValueChange={setTypeFilter}>
          <SelectTrigger className="w-[140px]">
            <SelectValue placeholder="All types" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All Types</SelectItem>
            <SelectItem value="Corporate">Corporate</SelectItem>
            <SelectItem value="Individual">Individual</SelectItem>
            <SelectItem value="Trust">Trust</SelectItem>
            <SelectItem value="Partnership">Partnership</SelectItem>
          </SelectContent>
        </Select>
        <Select value={statusFilter} onValueChange={setStatusFilter}>
          <SelectTrigger className="w-[130px]">
            <SelectValue placeholder="All statuses" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All Statuses</SelectItem>
            <SelectItem value="Active">Active</SelectItem>
            <SelectItem value="Inactive">Inactive</SelectItem>
            <SelectItem value="Prospect">Prospect</SelectItem>
          </SelectContent>
        </Select>
        <Button
          onClick={() => {
            setEditingClient(null);
            setEditOpen(true);
          }}
        >
          <Plus className="size-4" />
          New Client
        </Button>
      </div>

      <div className="rounded-lg border">
        <Table>
          <TableHeader>
            {table.getHeaderGroups().map((hg) => (
              <TableRow key={hg.id}>
                {hg.headers.map((h) => (
                  <TableHead key={h.id}>{flexRender(h.column.columnDef.header, h.getContext())}</TableHead>
                ))}
              </TableRow>
            ))}
          </TableHeader>
          <TableBody>
            {table.getRowModel().rows.length ? (
              table.getRowModel().rows.map((row) => (
                <TableRow key={row.id} className="cursor-pointer hover:bg-muted/50">
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell colSpan={columns.length} className="py-8 text-center text-muted-foreground">
                  No clients found.
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>

      <div className="flex items-center justify-between text-muted-foreground text-sm">
        <span>{table.getFilteredRowModel().rows.length} clients</span>
        <div className="flex items-center gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => table.previousPage()}
            disabled={!table.getCanPreviousPage()}
          >
            Previous
          </Button>
          <span>
            Page {table.getState().pagination.pageIndex + 1} of {Math.max(1, table.getPageCount())}
          </span>
          <Button variant="outline" size="sm" onClick={() => table.nextPage()} disabled={!table.getCanNextPage()}>
            Next
          </Button>
        </div>
      </div>

      <ClientDetailSheet client={detailClient} open={detailOpen} onOpenChange={setDetailOpen} onEdit={openEdit} />

      <ClientSheet key={editingClient?.id ?? "new"} open={editOpen} onOpenChange={setEditOpen} client={editingClient} />
    </div>
  );
}
