"use client";
import {
	RiArrowDownSLine,
	RiBarChartBoxLine,
	RiCloseLine,
} from "@remixicon/react";
import { useEffect, useMemo, useState } from "react";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
	type ChartConfig,
	ChartContainer,
	ChartTooltip,
} from "@/components/ui/chart";
import {
	Command,
	CommandEmpty,
	CommandGroup,
	CommandInput,
	CommandItem,
	CommandList,
} from "@/components/ui/command";
import {
	Popover,
	PopoverContent,
	PopoverTrigger,
} from "@/components/ui/popover";
import { WidgetEmptyState } from "@/components/widget-empty-state";
import type { CategoryHistoryData } from "@/lib/dashboard/categories/category-history";
import { getIconComponent } from "@/lib/utils/icons";

type CategoryHistoryWidgetProps = {
	data: CategoryHistoryData;
};

const STORAGE_KEY_SELECTED = "dashboard-category-history-selected";

// Vibrant colors for categories
const CHART_COLORS = [
	"#ef4444", // red-500
	"#3b82f6", // blue-500
	"#10b981", // emerald-500
	"#f59e0b", // amber-500
	"#8b5cf6", // violet-500
];

export function CategoryHistoryWidget({ data }: CategoryHistoryWidgetProps) {
	const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
	const [isClient, setIsClient] = useState(false);
	const [open, setOpen] = useState(false);

	// Load selected categories from sessionStorage on mount
	useEffect(() => {
		setIsClient(true);

		const stored = sessionStorage.getItem(STORAGE_KEY_SELECTED);
		if (stored) {
			try {
				const parsed = JSON.parse(stored);
				if (Array.isArray(parsed)) {
					const validCategories = parsed.filter((id) =>
						data.allCategories.some((cat) => cat.id === id),
					);
					setSelectedCategories(validCategories.slice(0, 5));
				}
			} catch (_e) {
				// Invalid JSON, ignore
			}
		}
	}, [data.allCategories]);

	// Save to sessionStorage when selection changes
	useEffect(() => {
		if (isClient) {
			sessionStorage.setItem(
				STORAGE_KEY_SELECTED,
				JSON.stringify(selectedCategories),
			);
		}
	}, [selectedCategories, isClient]);

	// Filter data to show only selected categories with vibrant colors
	const filteredCategories = useMemo(() => {
		return selectedCategories
			.map((id, index) => {
				const cat = data.categories.find((c) => c.id === id);
				if (!cat) return null;
				return {
					...cat,
					color: CHART_COLORS[index % CHART_COLORS.length],
				};
			})
			.filter(Boolean) as Array<{
			id: string;
			name: string;
			icon: string | null;
			color: string;
			data: Record<string, number>;
		}>;
	}, [data.categories, selectedCategories]);

	// Filter chart data to include only selected categories
	const filteredChartData = useMemo(() => {
		if (filteredCategories.length === 0) {
			return data.chartData.map((item) => ({ month: item.month }));
		}

		return data.chartData.map((item) => {
			const filtered: Record<string, number | string> = { month: item.month };
			filteredCategories.forEach((category) => {
				filtered[category.name] = item[category.name] || 0;
			});
			return filtered;
		});
	}, [data.chartData, filteredCategories]);

	// Build chart config dynamically from filtered categories
	const chartConfig = useMemo(() => {
		const config: ChartConfig = {};

		filteredCategories.forEach((category) => {
			config[category.name] = {
				label: category.name,
				color: category.color,
			};
		});

		return config;
	}, [filteredCategories]);

	const formatCurrency = (value: number) => {
		return new Intl.NumberFormat("pt-BR", {
			style: "currency",
			currency: "BRL",
			minimumFractionDigits: 2,
			maximumFractionDigits: 2,
		}).format(value);
	};

	const formatCurrencyCompact = (value: number) => {
		if (value >= 1000) {
			return new Intl.NumberFormat("pt-BR", {
				style: "currency",
				currency: "BRL",
				minimumFractionDigits: 0,
				maximumFractionDigits: 0,
				notation: "compact",
			}).format(value);
		}
		return new Intl.NumberFormat("pt-BR", {
			style: "currency",
			currency: "BRL",
			minimumFractionDigits: 0,
			maximumFractionDigits: 0,
		}).format(value);
	};

	const handleAddCategory = (categoryId: string) => {
		if (
			categoryId &&
			!selectedCategories.includes(categoryId) &&
			selectedCategories.length < 5
		) {
			setSelectedCategories([...selectedCategories, categoryId]);
			setOpen(false);
		}
	};

	const handleRemoveCategory = (categoryId: string) => {
		setSelectedCategories(selectedCategories.filter((id) => id !== categoryId));
	};

	const handleClearAll = () => {
		setSelectedCategories([]);
	};

	const availableCategories = useMemo(() => {
		return data.allCategories.filter(
			(cat) => !selectedCategories.includes(cat.id),
		);
	}, [data.allCategories, selectedCategories]);

	const selectedCategoryDetails = useMemo(() => {
		return selectedCategories
			.map((id) => data.allCategories.find((cat) => cat.id === id))
			.filter(Boolean);
	}, [selectedCategories, data.allCategories]);

	const isEmpty = filteredCategories.length === 0;

	// Group available categories by type
	const { despesaCategories, receitaCategories } = useMemo(() => {
		const despesa = availableCategories.filter((cat) => cat.type === "despesa");
		const receita = availableCategories.filter((cat) => cat.type === "receita");
		return { despesaCategories: despesa, receitaCategories: receita };
	}, [availableCategories]);

	if (!isClient) {
		return null;
	}

	return (
		<Card className="h-auto">
			<CardContent className="space-y-2.5">
				<div className="space-y-2">
					{selectedCategoryDetails.length > 0 && (
						<div className="flex items-start justify-between gap-4 mb-4">
							<div className="flex flex-wrap gap-2">
								{selectedCategoryDetails.map((category) => {
									if (!category) return null;
									const IconComponent = category.icon
										? getIconComponent(category.icon)
										: null;
									const colorIndex = selectedCategories.indexOf(category.id);
									const color = CHART_COLORS[colorIndex % CHART_COLORS.length];

									return (
										<div
											key={category.id}
											className="flex items-center gap-2 rounded-md border bg-background px-3 py-1.5 text-sm"
											style={{ borderColor: color }}
										>
											{IconComponent ? (
												<IconComponent className="size-4" style={{ color }} />
											) : (
												<div
													className="size-3 rounded-sm"
													style={{ backgroundColor: color }}
												/>
											)}
											<span className="text-foreground">{category.name}</span>
											<Button
												variant="ghost"
												size="sm"
												className="h-4 w-4 p-0 hover:bg-transparent"
												onClick={() => handleRemoveCategory(category.id)}
											>
												<RiCloseLine className="size-3" />
											</Button>
										</div>
									);
								})}
							</div>
							<div className="flex items-center gap-2 shrink-0 pt-1.5">
								<span className="text-xs text-muted-foreground whitespace-nowrap">
									{selectedCategories.length}/5 selecionadas
								</span>
								<Button
									variant="ghost"
									size="sm"
									onClick={handleClearAll}
									className="h-6 px-2 text-xs text-muted-foreground hover:text-foreground"
								>
									Limpar
								</Button>
							</div>
						</div>
					)}

					{selectedCategories.length < 5 && availableCategories.length > 0 && (
						<Popover open={open} onOpenChange={setOpen}>
							<PopoverTrigger asChild>
								<Button
									variant="outline"
									role="combobox"
									aria-expanded={open}
									className="w-full justify-between hover:scale-none"
								>
									Selecionar categorias
									<RiArrowDownSLine className="ml-2 h-4 w-4 shrink-0 opacity-50" />
								</Button>
							</PopoverTrigger>
							<PopoverContent
								className="w-(--radix-popover-trigger-width) p-0"
								align="start"
							>
								<Command>
									<CommandInput placeholder="Pesquisar categoria..." />
									<CommandList>
										<CommandEmpty>Nenhuma categoria encontrada.</CommandEmpty>

										{despesaCategories.length > 0 && (
											<CommandGroup heading="Despesas">
												{despesaCategories.map((category) => {
													const IconComponent = category.icon
														? getIconComponent(category.icon)
														: null;
													return (
														<CommandItem
															key={category.id}
															value={category.name}
															onSelect={() => handleAddCategory(category.id)}
															className="gap-2"
														>
															{IconComponent ? (
																<IconComponent className="size-4 text-red-600" />
															) : (
																<div className="size-3 rounded-sm bg-red-600" />
															)}
															<span>{category.name}</span>
														</CommandItem>
													);
												})}
											</CommandGroup>
										)}

										{receitaCategories.length > 0 && (
											<CommandGroup heading="Receitas">
												{receitaCategories.map((category) => {
													const IconComponent = category.icon
														? getIconComponent(category.icon)
														: null;
													return (
														<CommandItem
															key={category.id}
															value={category.name}
															onSelect={() => handleAddCategory(category.id)}
															className="gap-2"
														>
															{IconComponent ? (
																<IconComponent className="size-4 text-green-600" />
															) : (
																<div className="size-3 rounded-sm bg-green-600" />
															)}
															<span>{category.name}</span>
														</CommandItem>
													);
												})}
											</CommandGroup>
										)}
									</CommandList>
								</Command>
							</PopoverContent>
						</Popover>
					)}
				</div>

				{isEmpty ? (
					<div className="h-[450px] flex items-center justify-center">
						<WidgetEmptyState
							icon={
								<RiBarChartBoxLine className="size-6 text-muted-foreground" />
							}
							title="Selecione categorias para visualizar"
							description="Escolha até 5 categorias para acompanhar o histórico dos últimos 8 meses, mês atual e próximo mês."
						/>
					</div>
				) : (
					<ChartContainer config={chartConfig} className="h-[450px] w-full">
						<AreaChart
							data={filteredChartData}
							margin={{ top: 10, right: 20, left: 10, bottom: 0 }}
						>
							<defs>
								{filteredCategories.map((category) => (
									<linearGradient
										key={`gradient-${category.id}`}
										id={`gradient-${category.id}`}
										x1="0"
										y1="0"
										x2="0"
										y2="1"
									>
										<stop
											offset="5%"
											stopColor={category.color}
											stopOpacity={0.4}
										/>
										<stop
											offset="95%"
											stopColor={category.color}
											stopOpacity={0.05}
										/>
									</linearGradient>
								))}
							</defs>
							<CartesianGrid strokeDasharray="3 3" vertical={false} />
							<XAxis
								dataKey="month"
								tickLine={false}
								axisLine={false}
								tickMargin={8}
								className="text-xs"
							/>
							<YAxis
								tickLine={false}
								axisLine={false}
								tickMargin={8}
								className="text-xs"
								tickFormatter={formatCurrencyCompact}
							/>
							<ChartTooltip
								content={({ active, payload }) => {
									if (!active || !payload || payload.length === 0) {
										return null;
									}

									// Sort payload by value (descending)
									const sortedPayload = [...payload].sort(
										(a, b) => (b.value as number) - (a.value as number),
									);

									return (
										<div className="rounded-lg border bg-background p-3 shadow-lg">
											<div className="mb-2 text-xs font-medium text-muted-foreground">
												{payload[0].payload.month}
											</div>
											<div className="grid gap-1.5">
												{sortedPayload
													.filter((entry) => (entry.value as number) > 0)
													.map((entry) => {
														const config =
															chartConfig[
																entry.dataKey as keyof typeof chartConfig
															];
														const value = entry.value as number;

														return (
															<div
																key={entry.dataKey}
																className="flex items-center justify-between gap-4"
															>
																<div className="flex items-center gap-2">
																	<div
																		className="h-2.5 w-2.5 rounded-sm shrink-0"
																		style={{ backgroundColor: config?.color }}
																	/>
																	<span className="text-xs text-muted-foreground truncate max-w-[150px]">
																		{config?.label}
																	</span>
																</div>
																<span className="text-xs font-medium tabular-nums">
																	{formatCurrency(value)}
																</span>
															</div>
														);
													})}
											</div>
										</div>
									);
								}}
								cursor={{
									stroke: "hsl(var(--muted-foreground))",
									strokeWidth: 1,
								}}
							/>
							{filteredCategories.map((category) => (
								<Area
									key={category.id}
									type="monotone"
									dataKey={category.name}
									stroke={category.color}
									strokeWidth={1}
									fill={`url(#gradient-${category.id})`}
									fillOpacity={1}
									dot={false}
									activeDot={{
										r: 5,
										fill: category.color,
										stroke: "hsl(var(--background))",
										strokeWidth: 2,
									}}
								/>
							))}
						</AreaChart>
					</ChartContainer>
				)}
			</CardContent>
		</Card>
	);
}
