"use client";

import * as React from "react";
import {
  type ColumnDef,
  type SortingState,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  useReactTable,
} from "@tanstack/react-table";
import {
  ArchiveIcon,
  ChevronLeftIcon,
  ChevronRightIcon,
  ClipboardListIcon,
  CopyIcon,
  HistoryIcon,
  PencilIcon,
  PinIcon,
  PrinterIcon,
  SearchIcon,
  SlidersHorizontalIcon,
} from "lucide-react";

import { RowActions } from "@/components/medora/row-actions";
import { Button } from "@/components/ui/button";
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { toast } from "@/components/ui/toast";
import { formatKES, products, suppliers } from "@/lib/mock-data";
import { cn } from "@/lib/utils";
import { AdjustStockModal, ArchiveProductModal } from "../overlays/modals";
import { SortHeader } from "./sort-header";

// ---- data: one row per stocked product, with the columns a stock-management screen carries ----

const UNIT: Record<string, string> = { Tablet: "Tablets", Capsule: "Capsules", Syrup: "Bottle", Cream: "Tube", Sachet: "Sachets", Inhaler: "Inhaler", Box: "Box", Pack: "Pack", Device: "Each" };
const SUB: Record<string, string> = {
  Analgesics: "Pain relief",
  Antibiotics: "Anti-infectives",
  Antidiabetics: "Diabetes care",
  Cardiovascular: "Blood pressure",
  Antimalarials: "Malaria",
  Respiratory: "Cough and allergy",
  "Gastro-intestinal": "Digestive health",
  Vitamins: "Supplements",
  Dermatology: "Skin care",
  Consumables: "Medical supplies",
};
const TARGETS = [0, 20, 25, 30];

type StockRow = {
  id: number;
  code: string;
  name: string;
  generic: string;
  unit: string;
  category: string;
  subCategory: string;
  brand: string;
  supplier: string;
  shelf: string;
  stock: number;
  cost: number;
  price: number;
  targetMargin: number;
  margin: number;
  taxClass: string;
  etimsCode: string | null;
};

const stockRows: StockRow[] = products
  .filter((p) => p.type === "Product")
  .map((p, i) => ({
    id: 7400 + p.id,
    code: String(8800 + p.id),
    name: `${p.name} ${p.strength}`,
    generic: p.generic,
    unit: UNIT[p.form] ?? p.form,
    category: p.category,
    subCategory: SUB[p.category] ?? "-",
    brand: p.name.split(" ")[0],
    supplier: suppliers.find((s) => s.id === p.supplierId)?.name ?? "-",
    shelf: p.shelf,
    stock: p.stock,
    cost: p.costPrice,
    price: p.price,
    targetMargin: TARGETS[i % TARGETS.length],
    margin: p.price > 0 ? ((p.price - p.costPrice) / p.price) * 100 : 0,
    // eTIMS tax types: medicines exempt (A), consumables standard-rated 16% (B).
    taxClass: p.category === "Consumables" ? "B · 16%" : "A · Exempt",
    etimsCode: p.id % 3 === 0 ? null : `KE1NTXU${String(p.id).padStart(7, "0")}`,
  }));

// ---- pinned columns ----------------------------------------------------------------------------

/** Item name stays on the left and actions on the right while the middle scrolls. */
const PIN: Record<string, "left" | "right"> = { name: "left", actions: "right" };

/** Opaque backgrounds, so scrolled cells never show through a pinned one; they track the row's hover and selected fills. */
const pinBg = "bg-card group-hover/row:bg-[color-mix(in_oklab,var(--muted)_50%,var(--card))] group-data-[state=selected]/row:bg-muted";

function pinClass(id: string, head = false) {
  const side = PIN[id];
  if (!side) return "";
  return cn(
    "sticky",
    head ? "z-30 bg-card" : cn("z-10", pinBg),
    // Flat at rest. While the user scrolls sideways, a shadow fades in on the pinned column that content is passing under.
    "transition-shadow duration-200",
    side === "left"
      ? "left-0 border-r border-border group-data-[scrolling=true]/scroll:group-data-[scroll-left=true]/scroll:shadow-[10px_0_14px_-8px_rgb(0_17_16/0.28)]"
      : "right-0 border-l border-border group-data-[scrolling=true]/scroll:group-data-[scroll-right=true]/scroll:shadow-[-10px_0_14px_-8px_rgb(0_17_16/0.28)]",
  );
}

/** Row actions reach the table's modals through TanStack's meta, since the column definitions live outside the component. */
type TableMeta = { openModal: (kind: "adjust" | "archive", row: StockRow) => void };

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

const columns: ColumnDef<StockRow>[] = [
  {
    accessorKey: "name",
    header: ({ column }) => <SortHeader label="Item name" column={column} />,
    cell: ({ row }) => (
      <div className="w-56 whitespace-normal">
        <div className="font-medium text-foreground">{row.original.name}</div>
        <div className="truncate text-xs text-muted-foreground">{row.original.generic}</div>
      </div>
    ),
  },
  { accessorKey: "code", header: ({ column }) => <SortHeader label="Code" column={column} />, cell: ({ row }) => <span className="font-mono text-xs">{row.original.code}</span> },
  { accessorKey: "id", header: "ID", cell: ({ row }) => <span className="tabular-nums text-muted-foreground">{row.original.id}</span> },
  { accessorKey: "unit", header: "Unit" },
  { accessorKey: "category", header: ({ column }) => <SortHeader label="Category" column={column} /> },
  { accessorKey: "subCategory", header: "Sub-category" },
  { accessorKey: "brand", header: ({ column }) => <SortHeader label="Brand" column={column} /> },
  { accessorKey: "supplier", header: "Supplier" },
  { accessorKey: "shelf", header: "Shelf", cell: ({ row }) => <span className="font-mono text-xs">{row.original.shelf}</span> },
  {
    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: "cost",
    header: ({ column }) => <SortHeader label="Purchase price" column={column} align="right" />,
    cell: ({ row }) => <div className="text-right tabular-nums">{formatKES(row.original.cost, { decimals: true })}</div>,
  },
  {
    accessorKey: "price",
    header: ({ column }) => <SortHeader label="Selling price" column={column} align="right" />,
    cell: ({ row }) => <div className="text-right tabular-nums">{formatKES(row.original.price, { decimals: true })}</div>,
  },
  {
    accessorKey: "targetMargin",
    header: () => <div className="text-right">Target margin</div>,
    cell: ({ row }) => <div className="text-right tabular-nums text-muted-foreground">{row.original.targetMargin}%</div>,
  },
  {
    accessorKey: "margin",
    header: ({ column }) => <SortHeader label="Margin" column={column} align="right" />,
    cell: ({ row }) => {
      const below = row.original.margin < row.original.targetMargin;
      return (
        <div className={cn("text-right tabular-nums", below && "font-medium text-status-warning-text")} title={below ? "Below target margin" : undefined}>
          {row.original.margin.toFixed(1)}%
        </div>
      );
    },
  },
  { accessorKey: "taxClass", header: "Tax class" },
  {
    accessorKey: "etimsCode",
    header: "eTIMS item code",
    cell: ({ row }) =>
      row.original.etimsCode ? <span className="font-mono text-xs">{row.original.etimsCode}</span> : <span className="text-xs text-muted-foreground">Not registered</span>,
  },
  {
    id: "actions",
    enableSorting: false,
    header: () => <span className="sr-only">Actions</span>,
    cell: ({ row, table }) => {
      const r = row.original;
      const { openModal } = table.options.meta as TableMeta;
      return (
        <RowActions
          label={r.name}
          actions={[
            { label: "View product", icon: ClipboardListIcon, href: `#product-${r.id}` },
            { label: "Stock movements", icon: HistoryIcon, href: `#stock-logs-${r.id}` },
            { label: "Edit product", icon: PencilIcon, onSelect: go(`Edit ${r.name}`) },
            { label: "Adjust stock", icon: SlidersHorizontalIcon, onSelect: () => openModal("adjust", r) },
            { label: "Duplicate", icon: CopyIcon, onSelect: go(`Duplicate ${r.name}`) },
            { label: "Print shelf label", icon: PrinterIcon, onSelect: go(`Print label: ${r.name}`) },
            { label: "Archive", icon: ArchiveIcon, destructive: true, onSelect: () => openModal("archive", r) },
          ]}
        />
      );
    },
  },
];

/**
 * Wide stock-management table (16 data columns). Item name is pinned left and actions pinned right, so the row
 * stays identifiable and actionable however far the user scrolls. While the user scrolls sideways, a shadow shows
 * on whichever pinned column content is passing under; at rest both are flat.
 */
export function StockManagementTable() {
  const [sorting, setSorting] = React.useState<SortingState>([]);
  const [filter, setFilter] = React.useState("");
  const [edges, setEdges] = React.useState({ left: false, right: false });
  const [scrolling, setScrolling] = React.useState(false);
  // The row stays set while the modal animates closed; only `open` flips.
  const [modal, setModal] = React.useState<{ kind: "adjust" | "archive"; row: StockRow; open: boolean } | null>(null);
  const closeModal = (o: boolean) => !o && setModal((m) => (m ? { ...m, open: false } : m));
  const scrollRef = React.useRef<HTMLDivElement>(null);
  const lastLeft = React.useRef(0);
  const idle = React.useRef<ReturnType<typeof setTimeout> | null>(null);

  // eslint-disable-next-line react-hooks/incompatible-library
  const table = useReactTable({
    data: stockRows,
    columns,
    meta: { openModal: (kind, row) => setModal({ kind, row, open: true }) } satisfies TableMeta,
    state: { sorting, globalFilter: filter },
    onSortingChange: setSorting,
    onGlobalFilterChange: setFilter,
    globalFilterFn: (row, _id, value: string) => {
      const q = value.toLowerCase();
      const r = row.original;
      return r.name.toLowerCase().includes(q) || r.code.includes(q) || r.generic.toLowerCase().includes(q);
    },
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: { pagination: { pageSize: 10 } },
  });

  const measure = React.useCallback(() => {
    const el = scrollRef.current;
    if (!el) return;
    const left = el.scrollLeft > 0;
    const right = el.scrollLeft + el.clientWidth < el.scrollWidth - 1;
    setEdges((e) => (e.left === left && e.right === right ? e : { left, right }));
  }, []);

  // Horizontal scrolls only (vertical scrolling of the rows leaves the pinned columns flat). The shadow stays
  // up while scroll events keep arriving and fades 400 ms after the last one.
  const onScroll = () => {
    measure();
    const el = scrollRef.current;
    if (!el || el.scrollLeft === lastLeft.current) return;
    lastLeft.current = el.scrollLeft;
    setScrolling(true);
    if (idle.current) clearTimeout(idle.current);
    idle.current = setTimeout(() => setScrolling(false), 400);
  };

  React.useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    const ro = new ResizeObserver(measure);
    ro.observe(el);
    measure();
    return () => {
      ro.disconnect();
      if (idle.current) clearTimeout(idle.current);
    };
  }, [measure]);

  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">
        <InputGroup className="w-64">
          <InputGroupAddon>
            <SearchIcon />
          </InputGroupAddon>
          <InputGroupInput aria-label="Search by item name, code or generic" placeholder="Search name, code or generic" value={filter} onChange={(e) => setFilter(e.target.value)} />
        </InputGroup>
        <span className="ml-auto flex items-center gap-1.5 text-xs text-muted-foreground">
          <PinIcon className="size-3.5" />
          Item name and actions stay in view while you scroll sideways
        </span>
      </div>

      <div
        ref={scrollRef}
        onScroll={onScroll}
        data-scrolling={scrolling}
        data-scroll-left={edges.left}
        data-scroll-right={edges.right}
        className="group/scroll max-h-[28rem] overflow-auto [&_[data-slot=table-container]]:overflow-visible"
      >
        <Table className="whitespace-nowrap">
          <TableHeader className="sticky top-0 z-20 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={cn("h-9", pinClass(h.column.id, true))}>
                    {h.isPlaceholder ? null : 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="group/row">
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id} className={cn("py-2", pinClass(cell.column.id))}>
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow className="hover:bg-transparent">
                <TableCell colSpan={columns.length} className="py-10 text-center text-muted-foreground">
                  No items match &ldquo;{filter}&rdquo;
                </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">
          {from}-{to} of {filtered} items
        </span>
        <div className="flex items-center gap-1">
          <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>
        </div>
      </div>

      {modal ? (
        <>
          <AdjustStockModal product={modal.row} open={modal.open && modal.kind === "adjust"} onOpenChange={closeModal} />
          <ArchiveProductModal product={modal.row} open={modal.open && modal.kind === "archive"} onOpenChange={closeModal} />
        </>
      ) : null}
    </div>
  );
}
