import {
	createRootRoute,
	Outlet,
	useMatchRoute,
	useNavigate,
} from "@tanstack/react-router";
import { useState } from "react";
import "../app.css";
import { CandidateForm } from "../components/CandidateForm";
import { ConfirmDialog } from "../components/ConfirmDialog";
import { ExternalLinkDialog } from "../components/ExternalLinkDialog";
import { ItemForm } from "../components/ItemForm";
import { OnboardingWizard } from "../components/OnboardingWizard";
import { SlideOutPanel } from "../components/SlideOutPanel";
import { TotalsBar } from "../components/TotalsBar";
import { useAuth } from "../hooks/useAuth";
import { useDeleteCandidate } from "../hooks/useCandidates";
import { useOnboardingComplete } from "../hooks/useSettings";
import { useResolveThread, useThread } from "../hooks/useThreads";
import { useUIStore } from "../stores/uiStore";

export const Route = createRootRoute({
	component: RootLayout,
});

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

	// Item panel state
	const panelMode = useUIStore((s) => s.panelMode);
	const editingItemId = useUIStore((s) => s.editingItemId);
	const openAddPanel = useUIStore((s) => s.openAddPanel);
	const closePanel = useUIStore((s) => s.closePanel);

	// Candidate panel state
	const candidatePanelMode = useUIStore((s) => s.candidatePanelMode);
	const editingCandidateId = useUIStore((s) => s.editingCandidateId);
	const closeCandidatePanel = useUIStore((s) => s.closeCandidatePanel);

	// Candidate delete state
	const confirmDeleteCandidateId = useUIStore(
		(s) => s.confirmDeleteCandidateId,
	);
	const closeConfirmDeleteCandidate = useUIStore(
		(s) => s.closeConfirmDeleteCandidate,
	);

	// Resolution dialog state
	const resolveThreadId = useUIStore((s) => s.resolveThreadId);
	const resolveCandidateId = useUIStore((s) => s.resolveCandidateId);
	const closeResolveDialog = useUIStore((s) => s.closeResolveDialog);

	// Onboarding
	const { data: onboardingComplete, isLoading: onboardingLoading } =
		useOnboardingComplete();
	const [wizardDismissed, setWizardDismissed] = useState(false);

	// Don't show onboarding wizard until user has created an account
	const showWizard =
		!onboardingLoading && onboardingComplete !== "true" && !wizardDismissed && isAuthenticated;

	const isItemPanelOpen = panelMode !== "closed";
	const isCandidatePanelOpen = candidatePanelMode !== "closed";

	// Route matching for contextual behavior
	const matchRoute = useMatchRoute();

	const threadMatch = matchRoute({
		to: "/threads/$threadId",
		fuzzy: true,
	}) as { threadId?: string } | false;
	const currentThreadId = threadMatch ? Number(threadMatch.threadId) : null;

	const isDashboard = !!matchRoute({ to: "/" });
	const isCollection = !!matchRoute({ to: "/collection", fuzzy: true });
	const isSetupDetail = !!matchRoute({ to: "/setups/$setupId", fuzzy: true });

	// Determine TotalsBar props based on current route
	const _totalsBarProps = isDashboard
		? { stats: [] as Array<{ label: string; value: string }> } // Title only, no stats, no link
		: isSetupDetail
			? { linkTo: "/" } // Setup detail will render its own local bar; root bar just has link
			: { linkTo: "/" }; // All other pages: default stats + link to dashboard

	// On dashboard, don't show the default global stats - pass empty stats
	// On collection, let TotalsBar fetch its own global stats (default behavior)
	const finalTotalsProps = isDashboard
		? { stats: [] as Array<{ label: string; value: string }> }
		: isCollection
			? { linkTo: "/" }
			: { linkTo: "/" };

	// FAB visibility: only show on /collection route when gear tab is active
	const collectionSearch = matchRoute({ to: "/collection" }) as
		| { tab?: string }
		| false;
	const showFab =
		isCollection &&
		(!collectionSearch ||
			!(collectionSearch as Record<string, string>).tab ||
			(collectionSearch as Record<string, string>).tab === "gear");

	// Show a minimal loading state while checking onboarding status
	if (onboardingLoading) {
		return (
			<div className="min-h-screen bg-gray-50 flex items-center justify-center">
				<div className="w-6 h-6 border-2 border-gray-600 border-t-transparent rounded-full animate-spin" />
			</div>
		);
	}

	return (
		<div className="min-h-screen bg-gray-50">
			<TotalsBar {...finalTotalsProps} />
			<Outlet />

			{/* Item Slide-out Panel */}
			<SlideOutPanel
				isOpen={isItemPanelOpen}
				onClose={closePanel}
				title={panelMode === "add" ? "Add Item" : "Edit Item"}
			>
				{panelMode === "add" && <ItemForm mode="add" />}
				{panelMode === "edit" && (
					<ItemForm mode="edit" itemId={editingItemId} />
				)}
			</SlideOutPanel>

			{/* Candidate Slide-out Panel */}
			{currentThreadId != null && (
				<SlideOutPanel
					isOpen={isCandidatePanelOpen}
					onClose={closeCandidatePanel}
					title={
						candidatePanelMode === "add" ? "Add Candidate" : "Edit Candidate"
					}
				>
					{candidatePanelMode === "add" && (
						<CandidateForm mode="add" threadId={currentThreadId} />
					)}
					{candidatePanelMode === "edit" && (
						<CandidateForm
							mode="edit"
							threadId={currentThreadId}
							candidateId={editingCandidateId}
						/>
					)}
				</SlideOutPanel>
			)}

			{/* Item Confirm Delete Dialog */}
			<ConfirmDialog />

			{/* External Link Confirmation Dialog */}
			<ExternalLinkDialog />

			{/* Candidate Delete Confirm Dialog */}
			{confirmDeleteCandidateId != null && currentThreadId != null && (
				<CandidateDeleteDialog
					candidateId={confirmDeleteCandidateId}
					threadId={currentThreadId}
					onClose={closeConfirmDeleteCandidate}
				/>
			)}

			{/* Resolution Confirm Dialog */}
			{resolveThreadId != null && resolveCandidateId != null && (
				<ResolveDialog
					threadId={resolveThreadId}
					candidateId={resolveCandidateId}
					onClose={closeResolveDialog}
					onResolved={() => {
						closeResolveDialog();
						navigate({ to: "/collection", search: { tab: "planning" } });
					}}
				/>
			)}

			{/* Floating Add Button - only on collection gear tab */}
			{showFab && isAuthenticated && (
				<button
					type="button"
					onClick={openAddPanel}
					className="fixed bottom-6 right-6 z-20 w-14 h-14 bg-gray-700 hover:bg-gray-800 text-white rounded-full shadow-lg hover:shadow-xl transition-all flex items-center justify-center"
					title="Add new item"
				>
					<svg
						className="w-6 h-6"
						fill="none"
						stroke="currentColor"
						viewBox="0 0 24 24"
					>
						<path
							strokeLinecap="round"
							strokeLinejoin="round"
							strokeWidth={2}
							d="M12 4v16m8-8H4"
						/>
					</svg>
				</button>
			)}

			{/* Onboarding Wizard */}
			{showWizard && (
				<OnboardingWizard onComplete={() => setWizardDismissed(true)} />
			)}
		</div>
	);
}

function CandidateDeleteDialog({
	candidateId,
	threadId,
	onClose,
}: {
	candidateId: number;
	threadId: number;
	onClose: () => void;
}) {
	const deleteCandidate = useDeleteCandidate(threadId);
	const { data: thread } = useThread(threadId);
	const candidate = thread?.candidates.find((c) => c.id === candidateId);
	const candidateName = candidate?.name ?? "this candidate";

	function handleDelete() {
		deleteCandidate.mutate(candidateId, {
			onSuccess: () => onClose(),
		});
	}

	return (
		<div className="fixed inset-0 z-50 flex items-center justify-center">
			<div
				className="absolute inset-0 bg-black/30"
				onClick={onClose}
				onKeyDown={(e) => {
					if (e.key === "Escape") onClose();
				}}
			/>
			<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 Candidate
				</h3>
				<p className="text-sm text-gray-600 mb-6">
					Are you sure you want to delete{" "}
					<span className="font-medium">{candidateName}</span>? This action
					cannot be undone.
				</p>
				<div className="flex justify-end gap-3">
					<button
						type="button"
						onClick={onClose}
						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={deleteCandidate.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"
					>
						{deleteCandidate.isPending ? "Deleting..." : "Delete"}
					</button>
				</div>
			</div>
		</div>
	);
}

function ResolveDialog({
	threadId,
	candidateId,
	onClose,
	onResolved,
}: {
	threadId: number;
	candidateId: number;
	onClose: () => void;
	onResolved: () => void;
}) {
	const resolveThread = useResolveThread();
	const { data: thread } = useThread(threadId);
	const candidate = thread?.candidates.find((c) => c.id === candidateId);
	const candidateName = candidate?.name ?? "this candidate";

	function handleResolve() {
		resolveThread.mutate(
			{ threadId, candidateId },
			{ onSuccess: () => onResolved() },
		);
	}

	return (
		<div className="fixed inset-0 z-50 flex items-center justify-center">
			<div
				className="absolute inset-0 bg-black/30"
				onClick={onClose}
				onKeyDown={(e) => {
					if (e.key === "Escape") onClose();
				}}
			/>
			<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">
					Pick Winner
				</h3>
				<p className="text-sm text-gray-600 mb-6">
					Pick <span className="font-medium">{candidateName}</span> as the
					winner? This will add it to your collection and archive the thread.
				</p>
				<div className="flex justify-end gap-3">
					<button
						type="button"
						onClick={onClose}
						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={handleResolve}
						disabled={resolveThread.isPending}
						className="px-4 py-2 text-sm font-medium text-white bg-amber-600 hover:bg-amber-700 disabled:opacity-50 rounded-lg transition-colors"
					>
						{resolveThread.isPending ? "Resolving..." : "Pick Winner"}
					</button>
				</div>
			</div>
		</div>
	);
}
