"use client";

import { useQuery } from "@tanstack/react-query";
import { useAtom } from "jotai";
import {
	AlertCircle,
	AlertTriangle,
	BellDot,
	Check,
	CheckCheck,
	CheckCircle2,
	ChevronLeft,
	History,
	Inbox,
	LayoutGrid,
	ListFilter,
	MessageCircleReply,
	Search,
	X,
} from "lucide-react";
import { useParams, useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
import { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from "react";
import { setTargetCommentIdAtom } from "@/atoms/chat/current-thread.atom";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/animated-tabs";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import {
	Drawer,
	DrawerContent,
	DrawerHandle,
	DrawerHeader,
	DrawerTitle,
} from "@/components/ui/drawer";
import {
	DropdownMenu,
	DropdownMenuContent,
	DropdownMenuItem,
	DropdownMenuLabel,
	DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";
import { Spinner } from "@/components/ui/spinner";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
import {
	isCommentReplyMetadata,
	isConnectorIndexingMetadata,
	isDocumentProcessingMetadata,
	isInsufficientCreditsMetadata,
	isNewMentionMetadata,
} from "@/contracts/types/inbox.types";
import { useDebouncedValue } from "@/hooks/use-debounced-value";
import type { InboxItem } from "@/hooks/use-inbox";
import { useMediaQuery } from "@/hooks/use-media-query";
import { notificationsApiService } from "@/lib/apis/notifications-api.service";
import { convertRenderedToDisplay } from "@/lib/comments/utils";
import { getDocumentTypeLabel } from "@/lib/documents/document-type-labels";
import { cacheKeys } from "@/lib/query-client/cache-keys";
import { cn } from "@/lib/utils";
import { SidebarSlideOutPanel } from "./SidebarSlideOutPanel";

function getInitials(name: string | null | undefined, email: string | null | undefined): string {
	if (name) {
		return name
			.split(" ")
			.map((n) => n[0])
			.join("")
			.toUpperCase()
			.slice(0, 2);
	}
	if (email) {
		const localPart = email.split("@")[0];
		return localPart.slice(0, 2).toUpperCase();
	}
	return "U";
}

function formatInboxCount(count: number): string {
	if (count <= 999) {
		return count.toString();
	}
	const thousands = Math.floor(count / 1000);
	return `${thousands}k+`;
}

function getConnectorTypeDisplayName(connectorType: string): string {
	const displayNames: Record<string, string> = {
		GITHUB_CONNECTOR: "GitHub",
		GOOGLE_CALENDAR_CONNECTOR: "Google Calendar",
		GOOGLE_GMAIL_CONNECTOR: "Gmail",
		GOOGLE_DRIVE_CONNECTOR: "Google Drive",
		COMPOSIO_GOOGLE_DRIVE_CONNECTOR: "Composio Google Drive",
		COMPOSIO_GMAIL_CONNECTOR: "Composio Gmail",
		COMPOSIO_GOOGLE_CALENDAR_CONNECTOR: "Composio Google Calendar",
		LINEAR_CONNECTOR: "Linear",
		NOTION_CONNECTOR: "Notion",
		SLACK_CONNECTOR: "Slack",
		TEAMS_CONNECTOR: "Microsoft Teams",
		DISCORD_CONNECTOR: "Discord",
		JIRA_CONNECTOR: "Jira",
		CONFLUENCE_CONNECTOR: "Confluence",
		BOOKSTACK_CONNECTOR: "BookStack",
		CLICKUP_CONNECTOR: "ClickUp",
		AIRTABLE_CONNECTOR: "Airtable",
		LUMA_CONNECTOR: "Luma",
		ELASTICSEARCH_CONNECTOR: "Elasticsearch",
		WEBCRAWLER_CONNECTOR: "Web Crawler",
		YOUTUBE_CONNECTOR: "YouTube",
		CIRCLEBACK_CONNECTOR: "Circleback",
		MCP_CONNECTOR: "MCP",
		OBSIDIAN_CONNECTOR: "Obsidian",
		ONEDRIVE_CONNECTOR: "OneDrive",
		DROPBOX_CONNECTOR: "Dropbox",
		TAVILY_API: "Tavily",
		SEARXNG_API: "SearXNG",
		LINKUP_API: "Linkup",
		BAIDU_SEARCH_API: "Baidu",
	};

	return (
		displayNames[connectorType] ||
		connectorType
			.replace(/_/g, " ")
			.replace(/CONNECTOR|API/gi, "")
			.trim()
	);
}

type InboxTab = "comments" | "status";
type InboxFilter = "all" | "unread" | "errors";

interface TabDataSource {
	items: InboxItem[];
	unreadCount: number;
	loading: boolean;
	loadingMore: boolean;
	hasMore: boolean;
	loadMore: () => void;
	markAsRead: (id: number) => Promise<boolean>;
	markAllAsRead: () => Promise<boolean>;
}

export interface InboxSidebarContentProps {
	onOpenChange: (open: boolean) => void;
	comments: TabDataSource;
	status: TabDataSource;
	totalUnreadCount: number;
	onCloseMobileSidebar?: () => void;
}

interface InboxSidebarProps extends InboxSidebarContentProps {
	open: boolean;
}

export function InboxSidebarContent({
	onOpenChange,
	comments,
	status,
	totalUnreadCount,
	onCloseMobileSidebar,
}: InboxSidebarContentProps) {
	const t = useTranslations("sidebar");
	const router = useRouter();
	const params = useParams();
	const isMobile = !useMediaQuery("(min-width: 640px)");
	const searchSpaceId = params?.workspace_id ? Number(params.workspace_id) : null;

	const [, setTargetCommentId] = useAtom(setTargetCommentIdAtom);

	const [searchQuery, setSearchQuery] = useState("");
	const debouncedSearch = useDebouncedValue(searchQuery, 300);
	const isSearchMode = !!debouncedSearch.trim();
	const [activeTab, setActiveTab] = useState<InboxTab>("comments");
	const [activeFilter, setActiveFilter] = useState<InboxFilter>("all");
	const [selectedSource, setSelectedSource] = useState<string | null>(null);
	const [mounted, setMounted] = useState(false);
	const [openDropdown, setOpenDropdown] = useState<"filter" | null>(null);
	const [connectorScrollPos, setConnectorScrollPos] = useState<"top" | "middle" | "bottom">("top");
	const connectorRafRef = useRef<number | null>(null);
	const handleConnectorScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
		const el = e.currentTarget;
		if (connectorRafRef.current) return;
		connectorRafRef.current = requestAnimationFrame(() => {
			const atTop = el.scrollTop <= 2;
			const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight <= 2;
			setConnectorScrollPos(atTop ? "top" : atBottom ? "bottom" : "middle");
			connectorRafRef.current = null;
		});
	}, []);
	useEffect(
		() => () => {
			if (connectorRafRef.current) cancelAnimationFrame(connectorRafRef.current);
		},
		[]
	);
	const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);
	const [markingAsReadId, setMarkingAsReadId] = useState<number | null>(null);

	const prefetchTriggerRef = useRef<HTMLDivElement>(null);

	// Server-side search query
	const searchTypeFilter = activeTab === "comments" ? ("new_mention" as const) : undefined;
	const { data: searchResponse, isLoading: isSearchLoading } = useQuery({
		queryKey: cacheKeys.notifications.search(searchSpaceId, debouncedSearch.trim(), activeTab),
		queryFn: () =>
			notificationsApiService.getNotifications({
				queryParams: {
					workspace_id: searchSpaceId ?? undefined,
					type: searchTypeFilter,
					search: debouncedSearch.trim(),
					limit: 50,
				},
			}),
		staleTime: 30 * 1000,
		enabled: isSearchMode,
	});

	useEffect(() => {
		setMounted(true);
	}, []);

	useEffect(() => {
		if (!isMobile) return;
		const originalOverflow = document.body.style.overflow;
		document.body.style.overflow = "hidden";
		return () => {
			document.body.style.overflow = originalOverflow;
		};
	}, [isMobile]);

	useEffect(() => {
		if (activeTab !== "status") {
			setSelectedSource(null);
		}
	}, [activeTab]);

	// Active tab's data source — fully independent loading, pagination, and counts
	const activeSource = activeTab === "comments" ? comments : status;

	// Fetch source types for the status tab filter
	const { data: sourceTypesData } = useQuery({
		queryKey: cacheKeys.notifications.sourceTypes(searchSpaceId),
		queryFn: () => notificationsApiService.getSourceTypes(searchSpaceId ?? undefined),
		staleTime: 60 * 1000,
		enabled: activeTab === "status",
	});

	const statusSourceOptions = useMemo(() => {
		if (!sourceTypesData?.sources) return [];

		return sourceTypesData.sources.map((source) => ({
			key: source.key,
			type: source.type,
			category: source.category,
			displayName:
				source.category === "connector"
					? getConnectorTypeDisplayName(source.type)
					: getDocumentTypeLabel(source.type),
		}));
	}, [sourceTypesData]);

	// Client-side filter: source type
	const matchesSourceFilter = useCallback(
		(item: InboxItem): boolean => {
			if (!selectedSource) return true;
			if (selectedSource.startsWith("connector:")) {
				const connectorType = selectedSource.slice("connector:".length);
				return (
					item.type === "connector_indexing" &&
					isConnectorIndexingMetadata(item.metadata) &&
					item.metadata.connector_type === connectorType
				);
			}
			if (selectedSource.startsWith("doctype:")) {
				const docType = selectedSource.slice("doctype:".length);
				return (
					item.type === "document_processing" &&
					isDocumentProcessingMetadata(item.metadata) &&
					item.metadata.document_type === docType
				);
			}
			return true;
		},
		[selectedSource]
	);

	// Client-side filter: unread / errors
	const matchesActiveFilter = useCallback(
		(item: InboxItem): boolean => {
			if (activeFilter === "unread") return !item.read;
			if (activeFilter === "errors") {
				if (item.type === "insufficient_credits") return true;
				const meta = item.metadata as Record<string, unknown> | undefined;
				return typeof meta?.status === "string" && meta.status === "failed";
			}
			return true;
		},
		[activeFilter]
	);

	// Defer non-urgent list updates so the search input stays responsive.
	// The deferred snapshot lags one render behind the live value intentionally.
	const deferredTabItems = useDeferredValue(activeSource.items);
	const deferredSearchItems = useDeferredValue(searchResponse?.items ?? []);

	// Two data paths: search mode (API) or default (per-tab data source)
	const filteredItems = useMemo(() => {
		const tabItems: InboxItem[] = isSearchMode ? deferredSearchItems : deferredTabItems;

		let result = tabItems;
		if (activeFilter !== "all") {
			result = result.filter(matchesActiveFilter);
		}
		if (activeTab === "status" && selectedSource) {
			result = result.filter(matchesSourceFilter);
		}

		return result;
	}, [
		isSearchMode,
		deferredSearchItems,
		deferredTabItems,
		activeTab,
		activeFilter,
		selectedSource,
		matchesActiveFilter,
		matchesSourceFilter,
	]);

	// Infinite scroll — uses active tab's pagination
	useEffect(() => {
		if (!activeSource.hasMore || activeSource.loadingMore || isSearchMode) return;

		const observer = new IntersectionObserver(
			(entries) => {
				if (entries[0]?.isIntersecting) {
					activeSource.loadMore();
				}
			},
			{
				root: null,
				rootMargin: "100px",
				threshold: 0,
			}
		);

		if (prefetchTriggerRef.current) {
			observer.observe(prefetchTriggerRef.current);
		}

		return () => observer.disconnect();
	}, [activeSource.hasMore, activeSource.loadingMore, activeSource.loadMore, isSearchMode]);

	const handleItemClick = useCallback(
		async (item: InboxItem) => {
			if (!item.read) {
				setMarkingAsReadId(item.id);
				await activeSource.markAsRead(item.id);
				setMarkingAsReadId(null);
			}

			if (item.type === "new_mention") {
				if (isNewMentionMetadata(item.metadata)) {
					const searchSpaceId = item.workspace_id;
					const threadId = item.metadata.thread_id;
					const commentId = item.metadata.comment_id;

					if (searchSpaceId && threadId) {
						if (commentId) {
							setTargetCommentId(commentId);
						}
						const url = commentId
							? `/dashboard/${searchSpaceId}/new-chat/${threadId}?commentId=${commentId}`
							: `/dashboard/${searchSpaceId}/new-chat/${threadId}`;
						onOpenChange(false);
						onCloseMobileSidebar?.();
						router.push(url);
					}
				}
			} else if (item.type === "comment_reply") {
				if (isCommentReplyMetadata(item.metadata)) {
					const searchSpaceId = item.workspace_id;
					const threadId = item.metadata.thread_id;
					const replyId = item.metadata.reply_id;

					if (searchSpaceId && threadId) {
						if (replyId) {
							setTargetCommentId(replyId);
						}
						const url = replyId
							? `/dashboard/${searchSpaceId}/new-chat/${threadId}?commentId=${replyId}`
							: `/dashboard/${searchSpaceId}/new-chat/${threadId}`;
						onOpenChange(false);
						onCloseMobileSidebar?.();
						router.push(url);
					}
				}
			} else if (item.type === "insufficient_credits") {
				if (isInsufficientCreditsMetadata(item.metadata)) {
					const actionUrl = item.metadata.action_url;
					if (actionUrl) {
						onOpenChange(false);
						onCloseMobileSidebar?.();
						router.push(actionUrl);
					}
				}
			}
		},
		[activeSource.markAsRead, router, onOpenChange, onCloseMobileSidebar, setTargetCommentId]
	);

	const handleMarkAllAsRead = useCallback(async () => {
		await Promise.all([comments.markAllAsRead(), status.markAllAsRead()]);
	}, [comments.markAllAsRead, status.markAllAsRead]);

	const handleClearSearch = useCallback(() => {
		setSearchQuery("");
	}, []);

	const formatTime = (dateString: string) => {
		try {
			const date = new Date(dateString);
			const now = new Date();
			const diffMs = now.getTime() - date.getTime();
			const diffMins = Math.floor(diffMs / (1000 * 60));
			const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
			const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));

			if (diffMins < 1) return "now";
			if (diffMins < 60) return `${diffMins}m`;
			if (diffHours < 24) return `${diffHours}h`;
			if (diffDays < 7) return `${diffDays}d`;
			return `${Math.floor(diffDays / 7)}w`;
		} catch {
			return "now";
		}
	};

	const getStatusIcon = (item: InboxItem) => {
		if (item.type === "new_mention" || item.type === "comment_reply") {
			const metadata =
				item.type === "new_mention"
					? isNewMentionMetadata(item.metadata)
						? item.metadata
						: null
					: isCommentReplyMetadata(item.metadata)
						? item.metadata
						: null;

			if (metadata) {
				return (
					<Avatar className="h-8 w-8">
						{metadata.author_avatar_url && (
							<AvatarImage src={metadata.author_avatar_url} alt={metadata.author_name || "User"} />
						)}
						<AvatarFallback className="text-[10px] bg-primary/10 text-primary">
							{getInitials(metadata.author_name, metadata.author_email)}
						</AvatarFallback>
					</Avatar>
				);
			}
			return (
				<Avatar className="h-8 w-8">
					<AvatarFallback className="text-[10px] bg-primary/10 text-primary">
						{getInitials(null, null)}
					</AvatarFallback>
				</Avatar>
			);
		}

		if (item.type === "insufficient_credits") {
			return (
				<div className="h-8 w-8 flex items-center justify-center rounded-full bg-amber-500/10">
					<AlertTriangle className="h-4 w-4 text-amber-500" />
				</div>
			);
		}

		const metadata = item.metadata as Record<string, unknown>;
		const status = typeof metadata?.status === "string" ? metadata.status : undefined;

		switch (status) {
			case "in_progress":
				return (
					<div className="h-8 w-8 flex items-center justify-center rounded-full bg-muted">
						<Spinner size="sm" className="text-foreground" />
					</div>
				);
			case "completed":
				return (
					<div className="h-8 w-8 flex items-center justify-center rounded-full bg-green-500/10">
						<CheckCircle2 className="h-4 w-4 text-green-500" />
					</div>
				);
			case "failed":
				return (
					<div className="h-8 w-8 flex items-center justify-center rounded-full bg-red-500/10">
						<AlertCircle className="h-4 w-4 text-red-500" />
					</div>
				);
			default:
				return (
					<div className="h-8 w-8 flex items-center justify-center rounded-full bg-muted">
						<History className="h-4 w-4 text-muted-foreground" />
					</div>
				);
		}
	};

	const getEmptyStateMessage = () => {
		if (activeTab === "comments") {
			return {
				title: t("no_comments") || "No comments",
				hint: t("no_comments_hint") || "You'll see mentions and replies here",
			};
		}
		return {
			title: t("no_status_updates") || "No status updates",
			hint: t("no_status_updates_hint") || "Document and connector updates will appear here",
		};
	};

	if (!mounted) return null;

	const isLoading = isSearchMode ? isSearchLoading : activeSource.loading;

	return (
		<>
			<div className="shrink-0 p-3 pb-1.5 space-y-2">
				<div className="flex items-center justify-between">
					<div className="flex items-center gap-2">
						{isMobile && (
							<Button
								variant="ghost"
								size="icon"
								className="h-8 w-8 rounded-full text-muted-foreground hover:text-accent-foreground"
								onClick={() => onOpenChange(false)}
							>
								<ChevronLeft className="h-4 w-4" />
								<span className="sr-only">{t("close") || "Close"}</span>
							</Button>
						)}
						<h2 className="text-lg font-semibold">{t("inbox") || "Inbox"}</h2>
					</div>
					<div className="flex items-center gap-1">
						{isMobile ? (
							<>
								<Button
									variant="ghost"
									size="icon"
									className="h-7 w-7 rounded-full"
									onClick={() => setFilterDrawerOpen(true)}
								>
									<ListFilter className="h-4 w-4 text-muted-foreground" />
									<span className="sr-only">{t("filter") || "Filter"}</span>
								</Button>
								<Drawer
									open={filterDrawerOpen}
									onOpenChange={setFilterDrawerOpen}
									shouldScaleBackground={false}
								>
									<DrawerContent
										className="max-h-[70vh] z-80 bg-popover text-popover-foreground"
										overlayClassName="z-80"
									>
										<DrawerHandle />
										<DrawerHeader className="px-4 pb-3 pt-2">
											<DrawerTitle className="flex items-center gap-2 text-base font-semibold">
												<ListFilter className="size-5" />
												{t("filter") || "Filter"}
											</DrawerTitle>
										</DrawerHeader>
										<div className="flex-1 overflow-y-auto p-4 space-y-4">
											<div className="space-y-2">
												<p className="text-xs text-muted-foreground/80 font-medium px-1">
													{t("filter") || "Filter"}
												</p>
												<div className="space-y-1">
													<Button
														type="button"
														variant="ghost"
														onClick={() => {
															setActiveFilter("all");
															setFilterDrawerOpen(false);
														}}
														className={cn(
															"h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
															activeFilter === "all"
																? "bg-primary/10 text-primary"
																: "hover:bg-muted"
														)}
													>
														<span className="flex items-center gap-2">
															<Inbox className="h-4 w-4" />
															<span>{t("all") || "All"}</span>
														</span>
														{activeFilter === "all" && <Check className="h-4 w-4" />}
													</Button>
													<Button
														type="button"
														variant="ghost"
														onClick={() => {
															setActiveFilter("unread");
															setFilterDrawerOpen(false);
														}}
														className={cn(
															"h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
															activeFilter === "unread"
																? "bg-primary/10 text-primary"
																: "hover:bg-muted"
														)}
													>
														<span className="flex items-center gap-2">
															<BellDot className="h-4 w-4" />
															<span>{t("unread") || "Unread"}</span>
														</span>
														{activeFilter === "unread" && <Check className="h-4 w-4" />}
													</Button>
													{activeTab === "status" && (
														<Button
															type="button"
															variant="ghost"
															onClick={() => {
																setActiveFilter("errors");
																setFilterDrawerOpen(false);
															}}
															className={cn(
																"h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
																activeFilter === "errors"
																	? "bg-primary/10 text-primary"
																	: "hover:bg-muted"
															)}
														>
															<span className="flex items-center gap-2">
																<AlertCircle className="h-4 w-4" />
																<span>{t("errors_only") || "Errors only"}</span>
															</span>
															{activeFilter === "errors" && <Check className="h-4 w-4" />}
														</Button>
													)}
												</div>
											</div>
											{activeTab === "status" && statusSourceOptions.length > 0 && (
												<div className="space-y-2">
													<p className="text-xs text-muted-foreground/80 font-medium px-1">
														{t("sources") || "Sources"}
													</p>
													<div className="space-y-1">
														<Button
															type="button"
															variant="ghost"
															onClick={() => {
																setSelectedSource(null);
																setFilterDrawerOpen(false);
															}}
															className={cn(
																"h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
																selectedSource === null
																	? "bg-primary/10 text-primary"
																	: "hover:bg-muted"
															)}
														>
															<span className="flex items-center gap-2">
																<LayoutGrid className="h-4 w-4" />
																<span>{t("all_sources") || "All sources"}</span>
															</span>
															{selectedSource === null && <Check className="h-4 w-4" />}
														</Button>
														{statusSourceOptions.map((source) => (
															<Button
																key={source.key}
																type="button"
																variant="ghost"
																onClick={() => {
																	setSelectedSource(source.key);
																	setFilterDrawerOpen(false);
																}}
																className={cn(
																	"h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
																	selectedSource === source.key
																		? "bg-primary/10 text-primary"
																		: "hover:bg-muted"
																)}
															>
																<span className="flex items-center gap-2">
																	{getConnectorIcon(source.type, "h-4 w-4")}
																	<span>{source.displayName}</span>
																</span>
																{selectedSource === source.key && <Check className="h-4 w-4" />}
															</Button>
														))}
													</div>
												</div>
											)}
										</div>
									</DrawerContent>
								</Drawer>
							</>
						) : (
							<DropdownMenu
								open={openDropdown === "filter"}
								onOpenChange={(isOpen) => setOpenDropdown(isOpen ? "filter" : null)}
							>
								<Tooltip>
									<TooltipTrigger asChild>
										<DropdownMenuTrigger asChild>
											<Button variant="ghost" size="icon" className="h-7 w-7 rounded-full">
												<ListFilter className="h-4 w-4 text-muted-foreground" />
												<span className="sr-only">{t("filter") || "Filter"}</span>
											</Button>
										</DropdownMenuTrigger>
									</TooltipTrigger>
									<TooltipContent className="z-80">{t("filter") || "Filter"}</TooltipContent>
								</Tooltip>
								<DropdownMenuContent
									align="end"
									className={cn(
										"z-80 select-none max-h-[60vh] overflow-hidden flex flex-col",
										activeTab === "status" ? "w-52" : "w-44"
									)}
								>
									<DropdownMenuLabel className="text-xs text-muted-foreground/80 font-normal">
										{t("filter") || "Filter"}
									</DropdownMenuLabel>
									<DropdownMenuItem
										onClick={() => setActiveFilter("all")}
										className="flex items-center justify-between"
									>
										<span className="flex items-center gap-2">
											<Inbox className="h-4 w-4" />
											<span>{t("all") || "All"}</span>
										</span>
										{activeFilter === "all" && <Check className="h-4 w-4" />}
									</DropdownMenuItem>
									<DropdownMenuItem
										onClick={() => setActiveFilter("unread")}
										className="flex items-center justify-between"
									>
										<span className="flex items-center gap-2">
											<BellDot className="h-4 w-4" />
											<span>{t("unread") || "Unread"}</span>
										</span>
										{activeFilter === "unread" && <Check className="h-4 w-4" />}
									</DropdownMenuItem>
									{activeTab === "status" && (
										<DropdownMenuItem
											onClick={() => setActiveFilter("errors")}
											className="flex items-center justify-between"
										>
											<span className="flex items-center gap-2">
												<AlertCircle className="h-4 w-4" />
												<span>{t("errors_only") || "Errors only"}</span>
											</span>
											{activeFilter === "errors" && <Check className="h-4 w-4" />}
										</DropdownMenuItem>
									)}
									{activeTab === "status" && statusSourceOptions.length > 0 && (
										<>
											<DropdownMenuLabel className="text-xs text-muted-foreground/80 font-normal mt-2">
												{t("sources") || "Sources"}
											</DropdownMenuLabel>
											<div
												className="relative max-h-[30vh] overflow-y-auto overflow-x-hidden -mb-1"
												onScroll={handleConnectorScroll}
												style={{
													maskImage: `linear-gradient(to bottom, ${connectorScrollPos === "top" ? "black" : "transparent"}, black 16px, black calc(100% - 16px), ${connectorScrollPos === "bottom" ? "black" : "transparent"})`,
													WebkitMaskImage: `linear-gradient(to bottom, ${connectorScrollPos === "top" ? "black" : "transparent"}, black 16px, black calc(100% - 16px), ${connectorScrollPos === "bottom" ? "black" : "transparent"})`,
												}}
											>
												<DropdownMenuItem
													onClick={() => setSelectedSource(null)}
													className="flex items-center justify-between"
												>
													<span className="flex items-center gap-2">
														<LayoutGrid className="h-4 w-4" />
														<span>{t("all_sources") || "All sources"}</span>
													</span>
													{selectedSource === null && <Check className="h-4 w-4" />}
												</DropdownMenuItem>
												{statusSourceOptions.map((source) => (
													<DropdownMenuItem
														key={source.key}
														onClick={() => setSelectedSource(source.key)}
														className="flex items-center justify-between"
													>
														<span className="flex items-center gap-2">
															{getConnectorIcon(source.type, "h-4 w-4")}
															<span>{source.displayName}</span>
														</span>
														{selectedSource === source.key && <Check className="h-4 w-4" />}
													</DropdownMenuItem>
												))}
											</div>
										</>
									)}
								</DropdownMenuContent>
							</DropdownMenu>
						)}
						<Tooltip>
							<TooltipTrigger asChild>
								<Button
									variant="ghost"
									size="icon"
									className="h-7 w-7 rounded-full"
									onClick={handleMarkAllAsRead}
									disabled={totalUnreadCount === 0}
								>
									<CheckCheck className="h-4 w-4 text-muted-foreground" />
									<span className="sr-only">{t("mark_all_read") || "Mark all as read"}</span>
								</Button>
							</TooltipTrigger>
							<TooltipContent className="z-80">
								{t("mark_all_read") || "Mark all as read"}
							</TooltipContent>
						</Tooltip>
					</div>
				</div>

				<div className="relative">
					<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
					<Input
						type="text"
						placeholder={t("search_inbox") || "Search inbox"}
						value={searchQuery}
						onChange={(e) => setSearchQuery(e.target.value)}
						className="h-8 border-0 bg-muted pl-8 pr-7 text-sm shadow-none"
					/>
					{searchQuery && (
						<Button
							variant="ghost"
							size="icon"
							className="absolute right-1 top-1/2 h-5 w-5 -translate-y-1/2 rounded-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"
							onClick={handleClearSearch}
						>
							<X className="h-3.5 w-3.5" />
							<span className="sr-only">{t("clear_search") || "Clear search"}</span>
						</Button>
					)}
				</div>
			</div>

			<Tabs
				value={activeTab}
				onValueChange={(value) => {
					const tab = value as InboxTab;
					setActiveTab(tab);
					if (tab !== "status" && activeFilter === "errors") {
						setActiveFilter("all");
					}
				}}
				className="shrink-0 mx-3 mt-1.5"
			>
				<TabsList stretch showBottomBorder size="sm">
					<TabsTrigger value="comments">
						<span className="inline-flex items-center gap-1.5">
							<MessageCircleReply className="h-3.5 w-3.5" />
							<span>{t("comments") || "Comments"}</span>
							<span className="inline-flex h-4.5 min-w-4.5 items-center justify-center rounded-full bg-primary/20 px-1 text-[10px] font-medium text-muted-foreground">
								{formatInboxCount(comments.unreadCount)}
							</span>
						</span>
					</TabsTrigger>
					<TabsTrigger value="status">
						<span className="inline-flex items-center gap-1.5">
							<History className="h-3.5 w-3.5" />
							<span>{t("status") || "Status"}</span>
							<span className="inline-flex h-4.5 min-w-4.5 items-center justify-center rounded-full bg-primary/20 px-1 text-[10px] font-medium text-muted-foreground">
								{formatInboxCount(status.unreadCount)}
							</span>
						</span>
					</TabsTrigger>
				</TabsList>
			</Tabs>

			<div className="flex-1 overflow-y-auto overflow-x-hidden p-2">
				{isLoading ? (
					<div className="space-y-2">
						{activeTab === "comments"
							? [85, 60, 90, 70, 50, 75].map((titleWidth) => (
									<div
										key={`skeleton-comment-${titleWidth}`}
										className="flex items-center gap-3 rounded-lg px-3 py-3 h-[80px]"
									>
										<Skeleton className="h-8 w-8 rounded-full shrink-0" />
										<div className="flex-1 min-w-0 space-y-2">
											<Skeleton className="h-3 rounded" style={{ width: `${titleWidth}%` }} />
											<Skeleton className="h-2.5 w-[70%] rounded" />
										</div>
										<Skeleton className="h-3 w-6 shrink-0 rounded" />
									</div>
								))
							: [75, 90, 55, 80, 65, 85].map((titleWidth) => (
									<div
										key={`skeleton-status-${titleWidth}`}
										className="flex items-center gap-3 rounded-lg px-3 py-3 h-[80px]"
									>
										<Skeleton className="h-8 w-8 rounded-full shrink-0" />
										<div className="flex-1 min-w-0 space-y-2">
											<Skeleton className="h-3 rounded" style={{ width: `${titleWidth}%` }} />
											<Skeleton className="h-2.5 w-[60%] rounded" />
										</div>
										<div className="flex items-center gap-1.5 shrink-0">
											<Skeleton className="h-3 w-6 rounded" />
											<Skeleton className="h-2 w-2 rounded-full" />
										</div>
									</div>
								))}
					</div>
				) : filteredItems.length > 0 ? (
					<div className="space-y-2">
						{filteredItems.map((item, index) => {
							const isMarkingAsRead = markingAsReadId === item.id;
							const isPrefetchTrigger =
								!isSearchMode && activeSource.hasMore && index === filteredItems.length - 5;

							return (
								<div
									key={item.id}
									ref={isPrefetchTrigger ? prefetchTriggerRef : undefined}
									className={cn(
										"group flex items-center gap-3 rounded-lg px-3 py-3 text-sm h-[80px] overflow-hidden",
										"hover:bg-accent hover:text-accent-foreground",
										"transition-colors cursor-pointer",
										isMarkingAsRead && "opacity-50 pointer-events-none"
									)}
									style={{ contentVisibility: "auto", containIntrinsicSize: "0 80px" }}
								>
									{activeTab === "status" ? (
										<Tooltip delayDuration={600}>
											<TooltipTrigger asChild>
												<Button
													type="button"
													variant="ghost"
													onClick={() => handleItemClick(item)}
													disabled={isMarkingAsRead}
													className="h-auto flex-1 justify-start gap-3 overflow-hidden bg-transparent p-0 text-left hover:bg-transparent"
												>
													<div className="shrink-0">{getStatusIcon(item)}</div>
													<div className="flex-1 min-w-0 overflow-hidden">
														<p
															className={cn(
																"text-xs font-medium line-clamp-2",
																!item.read && "font-semibold"
															)}
														>
															{item.title}
														</p>
														<p className="text-[11px] text-muted-foreground line-clamp-2 mt-0.5">
															{convertRenderedToDisplay(item.message)}
														</p>
													</div>
												</Button>
											</TooltipTrigger>
											<TooltipContent side="bottom" align="start" className="max-w-[250px]">
												<p className="font-medium">{item.title}</p>
												<p className="text-muted-foreground mt-1">
													{convertRenderedToDisplay(item.message)}
												</p>
											</TooltipContent>
										</Tooltip>
									) : (
										<Button
											type="button"
											variant="ghost"
											onClick={() => handleItemClick(item)}
											disabled={isMarkingAsRead}
											className="h-auto flex-1 justify-start gap-3 overflow-hidden bg-transparent p-0 text-left hover:bg-transparent"
										>
											<div className="shrink-0">{getStatusIcon(item)}</div>
											<div className="flex-1 min-w-0 overflow-hidden">
												<p
													className={cn(
														"text-xs font-medium line-clamp-2",
														!item.read && "font-semibold"
													)}
												>
													{item.title}
												</p>
												<p className="text-[11px] text-muted-foreground line-clamp-2 mt-0.5">
													{convertRenderedToDisplay(item.message)}
												</p>
											</div>
										</Button>
									)}

									<div className="flex items-center justify-end gap-1.5 shrink-0 w-10">
										<span className="text-[10px] text-muted-foreground">
											{formatTime(item.created_at)}
										</span>
										{!item.read && <span className="h-2 w-2 rounded-full bg-blue-500 shrink-0" />}
									</div>
								</div>
							);
						})}
						{!isSearchMode && filteredItems.length < 5 && activeSource.hasMore && (
							<div ref={prefetchTriggerRef} className="h-1" />
						)}
						{activeSource.loadingMore &&
							(activeTab === "comments"
								? [80, 60, 90].map((titleWidth) => (
										<div
											key={`loading-more-comment-${titleWidth}`}
											className="flex items-center gap-3 rounded-lg px-3 py-3 h-[80px]"
										>
											<Skeleton className="h-8 w-8 rounded-full shrink-0" />
											<div className="flex-1 min-w-0 space-y-2">
												<Skeleton className="h-3 rounded" style={{ width: `${titleWidth}%` }} />
												<Skeleton className="h-2.5 w-[70%] rounded" />
											</div>
											<Skeleton className="h-3 w-6 shrink-0 rounded" />
										</div>
									))
								: [70, 85, 55].map((titleWidth) => (
										<div
											key={`loading-more-status-${titleWidth}`}
											className="flex items-center gap-3 rounded-lg px-3 py-3 h-[80px]"
										>
											<Skeleton className="h-8 w-8 rounded-full shrink-0" />
											<div className="flex-1 min-w-0 space-y-2">
												<Skeleton className="h-3 rounded" style={{ width: `${titleWidth}%` }} />
												<Skeleton className="h-2.5 w-[60%] rounded" />
											</div>
											<div className="flex items-center gap-1.5 shrink-0">
												<Skeleton className="h-3 w-6 rounded" />
												<Skeleton className="h-2 w-2 rounded-full" />
											</div>
										</div>
									)))}
					</div>
				) : isSearchMode ? (
					<div className="text-center py-8">
						<Search className="mx-auto mb-2.5 h-10 w-10 text-muted-foreground" />
						<p className="text-xs text-muted-foreground">
							{t("no_results_found") || "No results found"}
						</p>
						<p className="mt-1 text-[11px] text-muted-foreground/70">
							{t("try_different_search") || "Try a different search term"}
						</p>
					</div>
				) : (
					<div className="text-center py-8">
						{activeTab === "comments" ? (
							<MessageCircleReply className="mx-auto mb-2.5 h-10 w-10 text-muted-foreground" />
						) : (
							<History className="mx-auto mb-2.5 h-10 w-10 text-muted-foreground" />
						)}
						<p className="text-xs text-muted-foreground">{getEmptyStateMessage().title}</p>
						<p className="mt-1 text-[11px] text-muted-foreground/70">
							{getEmptyStateMessage().hint}
						</p>
					</div>
				)}
			</div>
		</>
	);
}

export function InboxSidebar({
	open,
	onOpenChange,
	comments,
	status,
	totalUnreadCount,
	onCloseMobileSidebar,
}: InboxSidebarProps) {
	const t = useTranslations("sidebar");

	return (
		<SidebarSlideOutPanel open={open} onOpenChange={onOpenChange} ariaLabel={t("inbox") || "Inbox"}>
			<InboxSidebarContent
				onOpenChange={onOpenChange}
				comments={comments}
				status={status}
				totalUnreadCount={totalUnreadCount}
				onCloseMobileSidebar={onCloseMobileSidebar}
			/>
		</SidebarSlideOutPanel>
	);
}
