import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useState } from "react";
import { CategoryHeader } from "../../components/CategoryHeader";
import { ItemCard } from "../../components/ItemCard";
import { ItemPicker } from "../../components/ItemPicker";
import { WeightSummaryCard } from "../../components/WeightSummaryCard";
import { useAuth } from "../../hooks/useAuth";
import { useFormatters } from "../../hooks/useFormatters";
import {
	useDeleteSetup,
	usePublicSetup,
	useRemoveSetupItem,
	useSetup,
	useUpdateItemClassification,
	useUpdateSetup,
} from "../../hooks/useSetups";
import { LucideIcon } from "../../lib/iconData";

export const Route = createFileRoute("/setups/$setupId")({
	component: SetupDetailPage,
});

function SetupDetailPage() {
	const { setupId } = Route.useParams();
	const { weight, price } = useFormatters();
	const navigate = useNavigate();
	const numericId = Number(setupId);

	const { data: auth } = useAuth();
	const isAuthenticated = !!auth?.user;

	const privateSetup = useSetup(isAuthenticated ? numericId : null);
	const publicSetup = usePublicSetup(!isAuthenticated ? numericId : null);
	const { data: setup, isLoading } = isAuthenticated
		? privateSetup
		: publicSetup;

	const deleteSetup = useDeleteSetup();
	const _updateSetup = useUpdateSetup(numericId);
	const removeItem = useRemoveSetupItem(numericId);
	const updateClassification = useUpdateItemClassification(numericId);

	const [pickerOpen, setPickerOpen] = useState(false);
	const [confirmDelete, setConfirmDelete] = useState(false);

	if (isLoading) {
		return (
			<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
				<div className="animate-pulse space-y-6">
					<div className="h-8 bg-gray-200 rounded w-48" />
					<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
						{[1, 2, 3].map((i) => (
							<div key={i} className="h-40 bg-gray-200 rounded-xl" />
						))}
					</div>
				</div>
			</div>
		);
	}

	if (!setup) {
		return (
			<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16 text-center">
				<p className="text-gray-500">Setup not found.</p>
			</div>
		);
	}

	// Compute totals from items (multiply by quantity)
	const totalWeight = setup.items.reduce(
		(sum, item) => sum + (item.weightGrams ?? 0) * (item.quantity ?? 1),
		0,
	);
	const totalCost = setup.items.reduce(
		(sum, item) => sum + (item.priceCents ?? 0) * (item.quantity ?? 1),
		0,
	);
	const itemCount = setup.items.length;
	const currentItemIds = setup.items.map((item) => item.id);

	// Group items by category
	const groupedItems = new Map<
		number,
		{
			items: typeof setup.items;
			categoryName: string;
			categoryIcon: string;
		}
	>();

	for (const item of setup.items) {
		const group = groupedItems.get(item.categoryId);
		if (group) {
			group.items.push(item);
		} else {
			groupedItems.set(item.categoryId, {
				items: [item],
				categoryName: item.categoryName,
				categoryIcon: item.categoryIcon,
			});
		}
	}

	function nextClassification(current: string): string {
		const order = ["base", "worn", "consumable"];
		const idx = order.indexOf(current);
		return order[(idx + 1) % order.length];
	}

	function handleDelete() {
		deleteSetup.mutate(numericId, {
			onSuccess: () => navigate({ to: "/setups" }),
		});
	}

	return (
		<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
			{/* Setup-specific sticky bar */}
			<div className="sticky top-14 z-[9] bg-gray-50 border-b border-gray-100 -mx-4 sm:-mx-6 lg:-mx-8 px-4 sm:px-6 lg:px-8">
				<div className="flex items-center justify-between h-12">
					<div className="flex items-center gap-3 min-w-0">
						<Link
							to="/collection"
							search={{ tab: "setups" }}
							className="text-sm text-gray-500 hover:text-gray-700 shrink-0"
						>
							&larr;
						</Link>
						<h2 className="text-base font-semibold text-gray-900 truncate">
							{setup.name}
						</h2>
					</div>
					<div className="flex items-center gap-4 text-sm text-gray-500">
						<span>
							<span className="font-medium text-gray-700">{itemCount}</span>{" "}
							{itemCount === 1 ? "item" : "items"}
						</span>
						<span>
							<span className="font-medium text-gray-700">
								{weight(totalWeight)}
							</span>{" "}
							total
						</span>
						<span>
							<span className="font-medium text-gray-700">
								{price(totalCost)}
							</span>{" "}
							cost
						</span>
					</div>
				</div>
			</div>

			{/* Actions — only visible to authenticated users */}
			{isAuthenticated && (
				<div className="flex items-center gap-3 py-4">
					{/* Add Items — desktop */}
					<button
						type="button"
						onClick={() => setPickerOpen(true)}
						className="hidden md:inline-flex items-center gap-2 px-4 py-2 bg-gray-700 hover:bg-gray-800 text-white text-sm font-medium rounded-lg transition-colors"
					>
						<LucideIcon name="plus" size={16} />
						Add Items
					</button>
					{/* Add Items — mobile */}
					<button
						type="button"
						onClick={() => setPickerOpen(true)}
						className="md:hidden inline-flex items-center justify-center min-w-[44px] min-h-[44px] p-2 bg-gray-700 hover:bg-gray-800 text-white rounded-lg transition-colors"
						aria-label="Add Items"
						title="Add Items"
					>
						<LucideIcon name="plus" size={16} />
					</button>

					{/* Visibility badge — desktop */}
					<span
						className={`hidden md:inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-lg ${
							setup.visibility === "public"
								? "text-green-700 bg-green-50"
								: setup.visibility === "link"
									? "text-blue-600 bg-blue-50"
									: "text-gray-500 bg-gray-50"
						}`}
					>
						<LucideIcon
							name={
								setup.visibility === "public"
									? "globe"
									: setup.visibility === "link"
										? "link"
										: "lock"
							}
							size={16}
						/>
						{setup.visibility === "public"
							? "Public"
							: setup.visibility === "link"
								? "Link"
								: "Private"}
					</span>
					{/* Visibility badge — mobile */}
					<span
						className={`md:hidden inline-flex items-center justify-center min-w-[44px] min-h-[44px] p-2 rounded-lg ${
							setup.visibility === "public"
								? "text-green-700 bg-green-50"
								: setup.visibility === "link"
									? "text-blue-600 bg-blue-50"
									: "text-gray-500 bg-gray-50"
						}`}
						title={
							setup.visibility === "public"
								? "Public"
								: setup.visibility === "link"
									? "Link shared"
									: "Private"
						}
					>
						<LucideIcon
							name={
								setup.visibility === "public"
									? "globe"
									: setup.visibility === "link"
										? "link"
										: "lock"
							}
							size={16}
						/>
					</span>

					<div className="flex-1" />
					{/* Delete Setup — desktop */}
					<button
						type="button"
						onClick={() => setConfirmDelete(true)}
						className="hidden md:inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-red-600 bg-red-50 hover:bg-red-100 rounded-lg transition-colors"
					>
						Delete Setup
					</button>
					{/* Delete Setup — mobile */}
					<button
						type="button"
						onClick={() => setConfirmDelete(true)}
						className="md:hidden inline-flex items-center justify-center min-w-[44px] min-h-[44px] p-2 text-red-600 bg-red-50 hover:bg-red-100 rounded-lg transition-colors"
						aria-label="Delete Setup"
						title="Delete Setup"
					>
						<LucideIcon name="trash-2" size={16} />
					</button>
				</div>
			)}

			{/* Empty state */}
			{itemCount === 0 && (
				<div className="py-16 text-center">
					<div className="max-w-md mx-auto">
						<div className="mb-4">
							<LucideIcon
								name="package"
								size={48}
								className="text-gray-400 mx-auto"
							/>
						</div>
						<h2 className="text-xl font-semibold text-gray-900 mb-2">
							No items in this setup
						</h2>
						<p className="text-sm text-gray-500 mb-6">
							Add items from your collection to build this loadout.
						</p>
						{isAuthenticated && (
							<button
								type="button"
								onClick={() => setPickerOpen(true)}
								className="inline-flex items-center gap-2 px-5 py-2.5 bg-gray-700 hover:bg-gray-800 text-white text-sm font-medium rounded-lg transition-colors"
							>
								Add Items
							</button>
						)}
					</div>
				</div>
			)}

			{/* Weight summary card + items grouped by category */}
			{itemCount > 0 && (
				<div className="pb-6">
					<WeightSummaryCard items={setup.items} />
					{Array.from(groupedItems.entries()).map(
						([
							categoryId,
							{ items: categoryItems, categoryName, categoryIcon },
						]) => {
							const catWeight = categoryItems.reduce(
								(sum, item) =>
									sum + (item.weightGrams ?? 0) * (item.quantity ?? 1),
								0,
							);
							const catCost = categoryItems.reduce(
								(sum, item) =>
									sum + (item.priceCents ?? 0) * (item.quantity ?? 1),
								0,
							);
							return (
								<div key={categoryId} className="mb-8">
									<CategoryHeader
										categoryId={categoryId}
										name={categoryName}
										icon={categoryIcon}
										totalWeight={catWeight}
										totalCost={catCost}
										itemCount={categoryItems.length}
									/>
									<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
										{categoryItems.map((item) => (
											<ItemCard
												key={item.id}
												id={item.id}
												name={item.name}
												weightGrams={item.weightGrams}
												priceCents={item.priceCents}
												quantity={item.quantity}
												categoryName={categoryName}
												categoryIcon={categoryIcon}
												imageFilename={item.imageFilename}
												imageUrl={item.imageUrl}
												productUrl={item.productUrl}
												onRemove={
													isAuthenticated
														? () => removeItem.mutate(item.id)
														: undefined
												}
												classification={item.classification}
												onClassificationCycle={
													isAuthenticated
														? () =>
																updateClassification.mutate({
																	itemId: item.id,
																	classification: nextClassification(
																		item.classification,
																	),
																})
														: undefined
												}
											/>
										))}
									</div>
								</div>
							);
						},
					)}
				</div>
			)}

			{/* Item Picker — only for authenticated users */}
			{isAuthenticated && (
				<ItemPicker
					setupId={numericId}
					currentItemIds={currentItemIds}
					isOpen={pickerOpen}
					onClose={() => setPickerOpen(false)}
				/>
			)}

			{/* Delete Confirmation Dialog — only for authenticated users */}
			{isAuthenticated && confirmDelete && (
				<div className="fixed inset-0 z-50 flex items-center justify-center">
					<div
						className="absolute inset-0 bg-black/30"
						onClick={() => setConfirmDelete(false)}
					/>
					<div className="relative bg-white rounded-xl shadow-lg p-6 max-w-sm mx-4 w-full">
						<h3 className="text-lg font-semibold text-gray-900 mb-2">
							Delete Setup
						</h3>
						<p className="text-sm text-gray-600 mb-6">
							Are you sure you want to delete{" "}
							<span className="font-medium">{setup.name}</span>? This will not
							remove items from your collection.
						</p>
						<div className="flex justify-end gap-3">
							<button
								type="button"
								onClick={() => setConfirmDelete(false)}
								className="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
							>
								Cancel
							</button>
							<button
								type="button"
								onClick={handleDelete}
								disabled={deleteSetup.isPending}
								className="px-4 py-2 text-sm font-medium text-white bg-red-600 hover:bg-red-700 disabled:opacity-50 rounded-lg transition-colors"
							>
								{deleteSetup.isPending ? "Deleting..." : "Delete"}
							</button>
						</div>
					</div>
				</div>
			)}
		</div>
	);
}
