"use client";

import * as React from "react";
import {
  type ColumnDef,
  type ColumnFiltersState,
  type SortingState,
  type VisibilityState,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  useReactTable,
} from "@tanstack/react-table";
import {
  ArchiveIcon,
  ChevronLeftIcon,
  ChevronRightIcon,
  ChevronsLeftIcon,
  ChevronsRightIcon,
  ClipboardListIcon,
  Columns3Icon,
  PackageSearchIcon,
  PencilIcon,
  PrinterIcon,
  ReceiptIcon,
  RotateCcwIcon,
  SlidersHorizontalIcon,
  Trash2Icon,
  TruckIcon,
  XCircleIcon,
} from "lucide-react";

import { Example } from "@/components/design-system/example";
import { Section } from "@/components/design-system/section";
import { RowActions } from "@/components/medora/row-actions";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { toast } from "@/components/ui/toast";
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty";
import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  type InventoryRow,
  batches,
  customers,
  expiring,
  formatDate,
  formatKES,
  inventoryRows,
  recentSales,
  staff,
  topProducts,
} from "@/lib/mock-data";
import { cn } from "@/lib/utils";
import { StatusBadge, saleTone, stockTone, toneText } from "../status";
import { SortHeader } from "./sort-header";
import { StockManagementTable } from "./wide-table";

const preview = (what: string) => () => toast.add({ title: what, description: "Design-system preview: no record changes." });

type Row = InventoryRow & { batchNo: string };

const rows: Row[] = inventoryRows.map((r) => {
  const b = batches
    .filter((x) => x.productId === r.id && x.stock > 0)
    .sort((a, c) => (a.expiryDate < c.expiryDate ? -1 : 1))[0];
  return { ...r, batchNo: b?.batchNo ?? "-" };
});

const COLUMN_LABEL: Record<string, string> = {
  name: "Product",
  category: "Category",
  batchNo: "Batch",
  nextExpiry: "Expiry",
  stock: "Stock",
  costPrice: "Cost",
  price: "Price",
  status: "Status",
};

const columns: ColumnDef<Row>[] = [
  {
    id: "select",
    enableSorting: false,
    enableHiding: false,
    header: ({ table }) => (
      <Checkbox
        aria-label="Select all rows on this page"
        checked={table.getIsAllPageRowsSelected()}
        indeterminate={table.getIsSomePageRowsSelected()}
        onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}
      />
    ),
    cell: ({ row }) => (
      <Checkbox aria-label={`Select ${row.original.name}`} checked={row.getIsSelected()} onCheckedChange={(v) => row.toggleSelected(!!v)} />
    ),
  },
  {
    accessorKey: "name",
    header: ({ column }) => <SortHeader label="Product" column={column} />,
    cell: ({ row }) => (
      <div>
        <div className="font-medium">{row.original.name}</div>
        <div className="text-xs text-muted-foreground">
          {row.original.generic} {row.original.strength}
        </div>
      </div>
    ),
  },
  { accessorKey: "category", header: "Category" },
  { accessorKey: "batchNo", header: "Batch", cell: ({ row }) => <span className="font-mono text-xs">{row.original.batchNo}</span> },
  {
    accessorKey: "nextExpiry",
    header: ({ column }) => <SortHeader label="Expiry" column={column} />,
    cell: ({ row }) => (row.original.nextExpiry ? formatDate(row.original.nextExpiry) : "-"),
  },
  {
    accessorKey: "stock",
    header: ({ column }) => <SortHeader label="Stock" column={column} align="right" />,
    cell: ({ row }) => <div className="text-right tabular-nums">{row.original.stock.toLocaleString("en-US")}</div>,
  },
  {
    accessorKey: "costPrice",
    header: () => <div className="text-right">Cost</div>,
    cell: ({ row }) => <div className="text-right tabular-nums">{formatKES(row.original.costPrice, { decimals: true })}</div>,
  },
  {
    accessorKey: "price",
    header: ({ column }) => <SortHeader label="Price" column={column} align="right" />,
    cell: ({ row }) => <div className="text-right tabular-nums">{formatKES(row.original.price, { decimals: true })}</div>,
  },
  {
    accessorKey: "status",
    header: "Status",
    cell: ({ row }) => <StatusBadge tone={stockTone(row.original.status)}>{row.original.status}</StatusBadge>,
  },
  {
    id: "actions",
    enableHiding: false,
    header: () => <span className="sr-only">Actions</span>,
    cell: ({ row }) => (
      <RowActions
        label={row.original.name}
        actions={[
          { label: "View batches", icon: ClipboardListIcon, href: `#batches-${row.original.id}` },
          { label: "Adjust stock", icon: SlidersHorizontalIcon, onSelect: preview(`Adjust stock: ${row.original.name}`) },
          { label: "Edit product", icon: PencilIcon, onSelect: preview(`Edit ${row.original.name}`) },
          { label: "Archive", icon: ArchiveIcon, destructive: true, onSelect: preview(`Archive ${row.original.name}`) },
        ]}
      />
    ),
  },
];

type ViewState = "data" | "loading" | "empty";

function InventoryDataTable() {
  const [sorting, setSorting] = React.useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);
  const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});
  const [rowSelection, setRowSelection] = React.useState({});
  const [density, setDensity] = React.useState<"comfortable" | "compact">("comfortable");
  const [view, setView] = React.useState<ViewState>("data");

  const data = React.useMemo(() => (view === "empty" ? [] : rows), [view]);

  // eslint-disable-next-line react-hooks/incompatible-library
  const table = useReactTable({
    data,
    columns,
    state: { sorting, columnFilters, columnVisibility, rowSelection },
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    onColumnVisibilityChange: setColumnVisibility,
    onRowSelectionChange: setRowSelection,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: { pagination: { pageSize: 8 } },
  });

  const cellPad = density === "compact" ? "py-1" : "py-2.5";
  const visibleCols = table.getVisibleLeafColumns().length;
  const filtered = table.getFilteredRowModel().rows.length;
  const { pageIndex, pageSize } = table.getState().pagination;
  const from = filtered === 0 ? 0 : pageIndex * pageSize + 1;
  const to = Math.min((pageIndex + 1) * pageSize, filtered);

  return (
    <div>
      <div className="flex flex-wrap items-center gap-2 border-b border-border p-3">
        <Input
          aria-label="Filter products by name"
          placeholder="Filter products..."
          className="w-56"
          value={(table.getColumn("name")?.getFilterValue() as string) ?? ""}
          onChange={(e) => table.getColumn("name")?.setFilterValue(e.target.value)}
        />
        <div className="ml-auto flex flex-wrap items-center gap-2">
          <div className="flex items-center gap-1" role="group" aria-label="Table state">
            {(["data", "loading", "empty"] as const).map((v) => (
              <Button key={v} size="sm" variant={view === v ? "secondary" : "ghost"} aria-pressed={view === v} onClick={() => setView(v)}>
                {v === "data" ? "Data" : v === "loading" ? "Loading" : "Empty"}
              </Button>
            ))}
          </div>
          <div className="flex items-center gap-1" role="group" aria-label="Row density">
            {(["comfortable", "compact"] as const).map((d) => (
              <Button key={d} size="sm" variant={density === d ? "secondary" : "ghost"} aria-pressed={density === d} onClick={() => setDensity(d)}>
                {d === "comfortable" ? "Comfortable" : "Compact"}
              </Button>
            ))}
          </div>
          <DropdownMenu>
            <DropdownMenuTrigger render={<Button variant="outline" size="sm" />}>
              <Columns3Icon data-icon="inline-start" />
              Columns
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-44">
              {table
                .getAllColumns()
                .filter((c) => c.getCanHide())
                .map((c) => (
                  <DropdownMenuCheckboxItem key={c.id} checked={c.getIsVisible()} onCheckedChange={(v) => c.toggleVisibility(!!v)}>
                    {COLUMN_LABEL[c.id] ?? c.id}
                  </DropdownMenuCheckboxItem>
                ))}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </div>

      <div className="max-h-96 overflow-auto [&_[data-slot=table-container]]:overflow-visible">
        <Table>
          <TableHeader className="sticky top-0 z-10 bg-card shadow-[inset_0_-1px_0_var(--border)] [&_tr]:border-b-0">
            {table.getHeaderGroups().map((hg) => (
              <TableRow key={hg.id} className="hover:bg-transparent">
                {hg.headers.map((h) => (
                  <TableHead key={h.id} className="h-9">
                    {h.isPlaceholder ? null : flexRender(h.column.columnDef.header, h.getContext())}
                  </TableHead>
                ))}
              </TableRow>
            ))}
          </TableHeader>
          <TableBody>
            {view === "loading" ? (
              Array.from({ length: 6 }, (_, i) => (
                <TableRow key={i} className="hover:bg-transparent">
                  {Array.from({ length: visibleCols }, (_, j) => (
                    <TableCell key={j} className={cellPad}>
                      <Skeleton className={cn("h-4", j === 0 ? "w-4" : j === 1 ? "w-36" : "w-16")} />
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : table.getRowModel().rows.length ? (
              table.getRowModel().rows.map((row) => (
                <TableRow key={row.id} data-state={row.getIsSelected() ? "selected" : undefined}>
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id} className={cellPad}>
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow className="hover:bg-transparent">
                <TableCell colSpan={visibleCols} className="p-0">
                  <Empty className="border-0 py-10">
                    <EmptyHeader>
                      <EmptyMedia variant="icon">
                        <PackageSearchIcon />
                      </EmptyMedia>
                      <EmptyTitle>{view === "empty" ? "No products yet" : "No products match this filter"}</EmptyTitle>
                      <EmptyDescription>
                        {view === "empty" ? "Add your first product or import a list to start tracking stock." : "Try a different name, or clear the filter."}
                      </EmptyDescription>
                    </EmptyHeader>
                  </Empty>
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>

      <div className="flex flex-wrap items-center justify-between gap-3 border-t border-border p-3 text-xs text-muted-foreground">
        <span className="tabular-nums">
          {table.getFilteredSelectedRowModel().rows.length} of {filtered} selected
        </span>
        <div className="flex items-center gap-4">
          <span className="tabular-nums">
            {from}-{to} of {filtered}
          </span>
          <div className="flex items-center gap-1">
            <Button variant="outline" size="icon-sm" aria-label="First page" disabled={!table.getCanPreviousPage()} onClick={() => table.setPageIndex(0)}>
              <ChevronsLeftIcon />
            </Button>
            <Button variant="outline" size="icon-sm" aria-label="Previous page" disabled={!table.getCanPreviousPage()} onClick={() => table.previousPage()}>
              <ChevronLeftIcon />
            </Button>
            <span className="px-2 tabular-nums">
              Page {pageIndex + 1} of {Math.max(table.getPageCount(), 1)}
            </span>
            <Button variant="outline" size="icon-sm" aria-label="Next page" disabled={!table.getCanNextPage()} onClick={() => table.nextPage()}>
              <ChevronRightIcon />
            </Button>
            <Button variant="outline" size="icon-sm" aria-label="Last page" disabled={!table.getCanNextPage()} onClick={() => table.setPageIndex(table.getPageCount() - 1)}>
              <ChevronsRightIcon />
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
}

const basicRows = topProducts.slice(0, 5);
const salesRows = recentSales.slice(0, 10);
const expiringRows = expiring.slice(0, 10);

function daysLeftClass(d: number) {
  return d <= 30 ? toneText.error : d <= 60 ? toneText.warning : "text-foreground";
}

export function TablesSection() {
  return (
    <Section id="tables" title="Tables" description="Dense, ruled rows with tabular figures. Money and quantities are right-aligned; status is carried by a badge, not row colour.">
      <Example
        title="Basic table"
        description="Caption and footer"
        bare
        code={`<Table>
  <TableCaption>Top sellers, last 30 days</TableCaption>
  <TableHeader>...</TableHeader>
  <TableBody>...</TableBody>
  <TableFooter>...</TableFooter>
</Table>`}
      >
        <Table>
          <TableCaption>Top sellers, last 30 days.</TableCaption>
          <TableHeader>
            <TableRow>
              <TableHead>Product</TableHead>
              <TableHead className="text-right">Units</TableHead>
              <TableHead className="text-right">Revenue</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {basicRows.map((r) => (
              <TableRow key={r.productId}>
                <TableCell className="font-medium">{r.name}</TableCell>
                <TableCell className="text-right">{r.units.toLocaleString("en-US")}</TableCell>
                <TableCell className="text-right">{formatKES(r.revenue)}</TableCell>
              </TableRow>
            ))}
          </TableBody>
          <TableFooter>
            <TableRow>
              <TableCell>Total</TableCell>
              <TableCell className="text-right">{basicRows.reduce((s, r) => s + r.units, 0).toLocaleString("en-US")}</TableCell>
              <TableCell className="text-right">{formatKES(basicRows.reduce((s, r) => s + r.revenue, 0))}</TableCell>
            </TableRow>
          </TableFooter>
        </Table>
      </Example>

      <Example
        title="Data table: product inventory"
        description="TanStack Table: sort, filter, columns, selection, pagination, density, states"
        bare
        code={`const table = useReactTable({
  data, columns,
  state: { sorting, columnFilters, columnVisibility, rowSelection },
  getCoreRowModel: getCoreRowModel(),
  getSortedRowModel: getSortedRowModel(),
  getFilteredRowModel: getFilteredRowModel(),
  getPaginationRowModel: getPaginationRowModel(),
})`}
      >
        <InventoryDataTable />
      </Example>

      <Example
        title="Wide table: stock management"
        description="16 columns with item name pinned left and actions pinned right; scroll sideways"
        bare
        code={`// Pinned cells: sticky + an opaque background that follows row hover and selection. They are flat at
// rest; while the user scrolls sideways a shadow fades in on the side content is passing under,
// and fades out 400 ms after scrolling stops.
<div ref={scrollRef} onScroll={onScroll} data-scrolling={scrolling}
     data-scroll-left={edges.left} data-scroll-right={edges.right} className="group/scroll overflow-auto">
  <TableCell className="sticky left-0 z-10 bg-card border-r transition-shadow
     group-data-[scrolling=true]/scroll:group-data-[scroll-left=true]/scroll:shadow-[10px_0_14px_-8px_rgb(0_17_16/0.28)]">…</TableCell>
  …
  <TableCell className="sticky right-0 z-10 bg-card border-l …"><RowActions … /></TableCell>
</div>`}
      >
        <StockManagementTable />
      </Example>

      <Example title="Sales and transactions" description="Right-aligned tabular KES amounts" bare>
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Receipt</TableHead>
              <TableHead>Date</TableHead>
              <TableHead>Customer</TableHead>
              <TableHead>Cashier</TableHead>
              <TableHead>Method</TableHead>
              <TableHead className="text-right">Items</TableHead>
              <TableHead className="text-right">Total</TableHead>
              <TableHead>Status</TableHead>
              <TableHead className="w-10">
                <span className="sr-only">Actions</span>
              </TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {salesRows.map((s) => (
              <TableRow key={s.id}>
                <TableCell className="font-mono text-xs">{s.receipt}</TableCell>
                <TableCell>
                  {formatDate(s.createdAt, { short: true })} {s.time}
                </TableCell>
                <TableCell>{s.customerId ? customers.find((c) => c.id === s.customerId)?.name : <span className="text-muted-foreground">Walk-in</span>}</TableCell>
                <TableCell>{staff.find((u) => u.id === s.cashierId)?.name}</TableCell>
                <TableCell>{s.method}</TableCell>
                <TableCell className="text-right">{s.items}</TableCell>
                <TableCell className="text-right font-medium">{formatKES(s.total, { decimals: true })}</TableCell>
                <TableCell>
                  <StatusBadge tone={saleTone(s.status)}>{s.status}</StatusBadge>
                </TableCell>
                <TableCell className="py-1 text-right">
                  <RowActions
                    label={`Receipt ${s.receipt}`}
                    actions={[
                      { label: "View receipt", icon: ReceiptIcon, href: `#receipt-${s.receipt}` },
                      { label: "Reprint receipt", icon: PrinterIcon, onSelect: preview(`Reprint ${s.receipt}`) },
                      { label: "Return or refund", icon: RotateCcwIcon, onSelect: preview(`Return on ${s.receipt}`) },
                      { label: "Void sale", icon: XCircleIcon, destructive: true, onSelect: preview(`Void ${s.receipt}`) },
                    ]}
                  />
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
          <TableFooter>
            <TableRow>
              <TableCell colSpan={6}>Total, completed sales</TableCell>
              <TableCell className="text-right">
                {formatKES(salesRows.filter((s) => s.status === "Completed").reduce((a, s) => a + s.total, 0), { decimals: true })}
              </TableCell>
              <TableCell colSpan={2} />
            </TableRow>
          </TableFooter>
        </Table>
      </Example>

      <Example title="Expiring batches" description="Days left coloured with status text colours" bare>
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Product</TableHead>
              <TableHead>Batch</TableHead>
              <TableHead>Expiry</TableHead>
              <TableHead className="text-right">Units</TableHead>
              <TableHead className="text-right">Value at cost</TableHead>
              <TableHead className="text-right">Days left</TableHead>
              <TableHead className="w-10">
                <span className="sr-only">Actions</span>
              </TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {expiringRows.map((b) => (
              <TableRow key={b.id}>
                <TableCell className="font-medium">{b.productName}</TableCell>
                <TableCell className="font-mono text-xs">{b.batchNo}</TableCell>
                <TableCell>{formatDate(b.expiryDate)}</TableCell>
                <TableCell className="text-right">{b.stock.toLocaleString("en-US")}</TableCell>
                <TableCell className="text-right">{formatKES(b.stock * b.costPrice, { decimals: true })}</TableCell>
                <TableCell className={cn("text-right font-medium", daysLeftClass(b.daysLeft))}>
                  {b.daysLeft < 0 ? `Expired ${-b.daysLeft}d ago` : `${b.daysLeft} days`}
                </TableCell>
                <TableCell className="py-1 text-right">
                  <RowActions
                    label={`${b.productName}, batch ${b.batchNo}`}
                    actions={[
                      { label: "View batch", icon: ClipboardListIcon, href: `#batch-${b.id}` },
                      { label: "Return to supplier", icon: TruckIcon, onSelect: preview(`Return batch ${b.batchNo}`) },
                      { label: "Write off", icon: Trash2Icon, destructive: true, onSelect: preview(`Write off batch ${b.batchNo}`) },
                    ]}
                  />
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </Example>
    </Section>
  );
}
