import { useState, useMemo, useCallback } from "react";
import { createFileRoute, Link } from "@tanstack/react-router";
import { Search, Plus, Pencil, Trash2, Package, Star } from "lucide-react";
import { GridTable } from "#/components/GridTable";
import type { GridTableColumn } from "#/components/GridTable";
import { Button, buttonVariants } from "#/components/ui";
import { useListStockBatches, useRemoveStockBatch, trpc } from "shared-react";

interface StockRow {
	id: number;
	product: { id: number; name: string; brand: string };
	arrived: string;
	batch_no: string;
	mfg: string;
	expiry: string;
	rack: { id: number; name: string } | null;
	distributor: { id: number; agency: string } | null;
	quantity: number;
	is_default: boolean;
}

function daysUntil(expiry: string): number {
	const today = new Date();
	today.setHours(0, 0, 0, 0);
	const exp = new Date(expiry + "T00:00:00");
	return Math.ceil((exp.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
}

function fmtDate(d: string): string {
	const date = new Date(d + "T00:00:00");
	return date.toLocaleDateString("en-US", { day: "numeric", month: "short", year: "numeric" });
}

function daysBadge(days: number) {
	if (days < 0) return <span className="inline-block px-2 py-0.5 rounded-full text-[11px] font-semibold bg-red-50 text-red-600 line-through">Expired</span>;
	if (days <= 30) return <span className="inline-block px-2 py-0.5 rounded-full text-[11px] font-semibold bg-red-50 text-red-600">{days} days</span>;
	if (days <= 90) return <span className="inline-block px-2 py-0.5 rounded-full text-[11px] font-semibold bg-amber-50 text-amber-600">{days} days</span>;
	return <span className="inline-block px-2 py-0.5 rounded-full text-[11px] font-semibold bg-emerald-50 text-emerald-600">{days} days</span>;
}

function makeColumns(
	onDelete: (row: StockRow) => void,
): GridTableColumn<StockRow>[] {
	return [
		{
			id: "product",
			header: "Product",
			cell: ({ row }) => (
				<div>
					<div className="font-semibold text-[13px]">{row.product.name}</div>
					<div className="text-xs text-slate-500 mt-px">{row.product.brand}</div>
				</div>
			),
		},
		{
			id: "arrived",
			header: "Arrived Date",
			cell: ({ row }) => <span className="text-[13px] whitespace-nowrap">{fmtDate(row.arrived)}</span>,
		},
		{
			id: "batch_no",
			header: "Batch No",
			cell: ({ row }) => (
				<span className="text-xs font-mono whitespace-nowrap">{row.batch_no}</span>
			),
		},
		{
			id: "quantity",
			header: "Qty",
			size: 60,
			cell: ({ row }) => (
				<span className="font-semibold text-[13px]">{row.quantity}</span>
			),
		},
		{
			id: "is_default",
			header: "Default",
			size: 60,
			cell: ({ row }) => (
				<span title={row.is_default ? "Default batch" : ""}>
					{row.is_default ? (
						<Star className="w-4 h-4 text-amber-500 fill-amber-500" />
					) : (
						<Star className="w-4 h-4 text-slate-300" />
					)}
				</span>
			),
		},
		{
			id: "mfg",
			header: "Manufacture Date",
			cell: ({ row }) => <span className="text-[13px] whitespace-nowrap">{fmtDate(row.mfg)}</span>,
		},
		{
			id: "expiry",
			header: "Expiry Date",
			cell: ({ row }) => {
				const days = daysUntil(row.expiry);
				return (
					<span className={`text-[13px] whitespace-nowrap ${days < 0 ? "text-red-600 font-medium" : days <= 30 ? "text-amber-600 font-medium" : ""}`}>
						{fmtDate(row.expiry)}
					</span>
				);
			},
		},
		{
			id: "days",
			header: "Days Remaining",
			cell: ({ row }) => daysBadge(daysUntil(row.expiry)),
		},
		{
			id: "rack",
			header: "Rack",
			cell: ({ row }) => <span className="text-[13px]">{row.rack?.name || "—"}</span>,
		},
		{
			id: "distributor",
			header: "Distributor",
			cell: ({ row }) => <span className="text-[13px] text-slate-600">{row.distributor?.agency || "—"}</span>,
		},
		{
			id: "actions",
			header: "Actions",
			size: 90,
			cell: ({ row }) => (
				<div className="flex items-center justify-center gap-1">
					<Link
						to="/stock/$id"
						params={{ id: row.id.toString() }}
						className="text-[10px] font-medium text-blue-600 hover:underline whitespace-nowrap"
					>
						View
					</Link>
					<Link to="/stock/add" search={{ id: row.id }}>
						<Button variant="ghost-blue" size="icon" aria-label={`Edit ${row.batch_no}`} type="button">
							<Pencil className="w-[15px] h-[15px]" />
						</Button>
					</Link>
					<Button variant="ghost-red" size="icon" aria-label={`Delete ${row.batch_no}`} onClick={() => onDelete(row)}>
						<Trash2 className="w-[15px] h-[15px]" />
					</Button>
				</div>
			),
		},
	];
}

export const Route = createFileRoute("/stock/")({
	component: StockIndexPage,
	staticData: {
		title: "Stock Batches",
		subtitle: "Track inventory batches by expiry and rack location",
	},
});

function StockIndexPage() {
	const [searchQuery, setSearchQuery] = useState("");
	const { data: batches, isLoading, error } = useListStockBatches();
	const removeMutation = useRemoveStockBatch();
	const utils = trpc.useUtils();

	const handleDelete = useCallback(
		(row: StockRow) => {
			if (!confirm(`Delete batch ${row.batch_no}?`)) return;
			removeMutation.mutate(
				{ id: row.id },
				{ onSuccess: () => utils.stock.list.invalidate() },
			);
		},
		[removeMutation, utils],
	);

	const columns = useMemo(() => makeColumns(handleDelete), [handleDelete]);

	const filtered = useMemo(() => {
		const q = searchQuery.toLowerCase().trim();
		if (!q) return batches ?? [];
		return (batches ?? []).filter((b) => {
			const text = `${b.product.name} ${b.product.brand} ${b.batch_no} ${b.rack?.name || ""} ${b.distributor?.agency || ""}`;
			return text.toLowerCase().includes(q);
		});
	}, [searchQuery, batches]);

	if (isLoading) return <div className="text-sm text-slate-600 py-8">Loading stock batches...</div>;
	if (error) return <div className="text-sm text-red-600 py-8">Failed to load stock batches.</div>;

	return (
		<div>
			<div className="flex items-center gap-3 mb-5 flex-wrap">
				<div className="flex items-center gap-2 flex-1 min-w-[200px] max-w-[480px] px-3.5 py-2 bg-white rounded-md border border-slate-200 transition-all duration-200 focus-within:border-blue-600 focus-within:shadow-[0_0_0_3px_rgba(37,99,235,0.1)]">
					<Search className="w-4 h-4 text-slate-600 shrink-0" />
					<input
						type="text"
						value={searchQuery}
						onChange={(e) => setSearchQuery(e.target.value)}
						placeholder="Search by product, brand, batch, or rack..."
						className="bg-transparent border-none outline-none text-sm text-slate-900 w-full placeholder:text-slate-400"
					/>
				</div>
				<Link to="/stock/add" className={buttonVariants({ variant: "primary" })}>
					<Plus className="w-[15px] h-[15px]" />
					Add Stock
				</Link>
			</div>

			<GridTable
				columns={columns}
				data={filtered}
				emptyState={
					<div className="flex flex-col items-center py-16 px-6 text-slate-600">
						<Package className="w-12 h-12 mb-4 opacity-40" />
						<h3 className="text-base font-semibold text-slate-900 mb-1.5">No stock batches found</h3>
						<p className="text-sm">
							{searchQuery ? "No batches match your search." : "Add your first stock batch to get started."}
						</p>
					</div>
				}
			/>
		</div>
	);
}
