"use client";

import {
	closestCorners,
	DndContext,
	type DragEndEvent,
	KeyboardSensor,
	PointerSensor,
	useSensor,
	useSensors,
} from "@dnd-kit/core";
import {
	arrayMove,
	rectSortingStrategy,
	SortableContext,
	sortableKeyboardCoordinates,
} from "@dnd-kit/sortable";
import {
	RiAddCircleLine,
	RiCheckLine,
	RiCloseLine,
	RiDragMove2Line,
	RiEyeOffLine,
	RiTodoLine,
} from "@remixicon/react";
import { useCallback, useMemo, useState, useTransition } from "react";
import { toast } from "sonner";
import { NoteDialog } from "@/components/anotacoes/note-dialog";
import { SortableWidget } from "@/components/dashboard/sortable-widget";
import { WidgetSettingsDialog } from "@/components/dashboard/widget-settings-dialog";
import { LancamentoDialog } from "@/components/lancamentos/dialogs/lancamento-dialog/lancamento-dialog";
import type { SelectOption } from "@/components/lancamentos/types";
import { Button } from "@/components/ui/button";
import WidgetCard from "@/components/widget-card";
import type { DashboardData } from "@/lib/dashboard/fetch-dashboard-data";
import {
	resetWidgetPreferences,
	updateWidgetPreferences,
	type WidgetPreferences,
} from "@/lib/dashboard/widgets/actions";
import {
	type WidgetConfig,
	widgetsConfig,
} from "@/lib/dashboard/widgets/widgets-config";

type DashboardGridEditableProps = {
	data: DashboardData;
	period: string;
	initialPreferences: WidgetPreferences | null;
	quickActionOptions: {
		pagadorOptions: SelectOption[];
		splitPagadorOptions: SelectOption[];
		defaultPagadorId: string | null;
		contaOptions: SelectOption[];
		cartaoOptions: SelectOption[];
		categoriaOptions: SelectOption[];
		estabelecimentos: string[];
	};
};

export function DashboardGridEditable({
	data,
	period,
	initialPreferences,
	quickActionOptions,
}: DashboardGridEditableProps) {
	const [isEditing, setIsEditing] = useState(false);
	const [isPending, startTransition] = useTransition();

	// Initialize widget order and hidden state
	const defaultOrder = widgetsConfig.map((w) => w.id);
	const [widgetOrder, setWidgetOrder] = useState<string[]>(
		initialPreferences?.order ?? defaultOrder,
	);
	const [hiddenWidgets, setHiddenWidgets] = useState<string[]>(
		initialPreferences?.hidden ?? [],
	);

	// Keep track of original state for cancel
	const [originalOrder, setOriginalOrder] = useState(widgetOrder);
	const [originalHidden, setOriginalHidden] = useState(hiddenWidgets);

	const sensors = useSensors(
		useSensor(PointerSensor, {
			activationConstraint: {
				distance: 8,
			},
		}),
		useSensor(KeyboardSensor, {
			coordinateGetter: sortableKeyboardCoordinates,
		}),
	);

	// Get ordered and visible widgets
	const orderedWidgets = useMemo(() => {
		// Create a map for quick lookup
		const widgetMap = new Map(widgetsConfig.map((w) => [w.id, w]));

		// Get widgets in order, filtering out hidden ones
		const ordered: WidgetConfig[] = [];
		for (const id of widgetOrder) {
			const widget = widgetMap.get(id);
			if (widget && !hiddenWidgets.includes(id)) {
				ordered.push(widget);
			}
		}

		// Add any new widgets that might not be in the order yet
		for (const widget of widgetsConfig) {
			if (
				!widgetOrder.includes(widget.id) &&
				!hiddenWidgets.includes(widget.id)
			) {
				ordered.push(widget);
			}
		}

		return ordered;
	}, [widgetOrder, hiddenWidgets]);

	const handleDragEnd = useCallback((event: DragEndEvent) => {
		const { active, over } = event;

		if (over && active.id !== over.id) {
			setWidgetOrder((items) => {
				const oldIndex = items.indexOf(active.id as string);
				const newIndex = items.indexOf(over.id as string);
				return arrayMove(items, oldIndex, newIndex);
			});
		}
	}, []);

	const handleToggleWidget = useCallback(
		(widgetId: string) => {
			const newHidden = hiddenWidgets.includes(widgetId)
				? hiddenWidgets.filter((id) => id !== widgetId)
				: [...hiddenWidgets, widgetId];

			setHiddenWidgets(newHidden);

			// Salvar automaticamente ao toggle
			startTransition(async () => {
				await updateWidgetPreferences({
					order: widgetOrder,
					hidden: newHidden,
				});
			});
		},
		[hiddenWidgets, widgetOrder],
	);

	const handleHideWidget = useCallback((widgetId: string) => {
		setHiddenWidgets((prev) => [...prev, widgetId]);
	}, []);

	const handleStartEditing = useCallback(() => {
		setOriginalOrder(widgetOrder);
		setOriginalHidden(hiddenWidgets);
		setIsEditing(true);
	}, [widgetOrder, hiddenWidgets]);

	const handleCancelEditing = useCallback(() => {
		setWidgetOrder(originalOrder);
		setHiddenWidgets(originalHidden);
		setIsEditing(false);
	}, [originalOrder, originalHidden]);

	const handleSave = useCallback(() => {
		startTransition(async () => {
			const result = await updateWidgetPreferences({
				order: widgetOrder,
				hidden: hiddenWidgets,
			});

			if (result.success) {
				toast.success("Preferências salvas!");
				setIsEditing(false);
			} else {
				toast.error(result.error ?? "Erro ao salvar");
			}
		});
	}, [widgetOrder, hiddenWidgets]);

	const handleReset = useCallback(() => {
		startTransition(async () => {
			const result = await resetWidgetPreferences();

			if (result.success) {
				setWidgetOrder(defaultOrder);
				setHiddenWidgets([]);
				toast.success("Preferências restauradas!");
			} else {
				toast.error(result.error ?? "Erro ao restaurar");
			}
		});
	}, [defaultOrder]);

	return (
		<div className="space-y-4">
			{/* Toolbar */}
			<div className="flex flex-wrap items-center justify-between gap-2">
				{!isEditing ? (
					<div className="flex w-full min-w-0 flex-col gap-1 px-1 sm:w-auto sm:flex-row sm:items-center sm:gap-2">
						<span className="text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">
							Ações rápidas
						</span>
						<div className="-mb-1 grid w-full grid-cols-3 gap-1 pb-1 sm:mb-0 sm:flex sm:w-auto sm:items-center sm:gap-2 sm:overflow-visible sm:pb-0">
							<LancamentoDialog
								mode="create"
								pagadorOptions={quickActionOptions.pagadorOptions}
								splitPagadorOptions={quickActionOptions.splitPagadorOptions}
								defaultPagadorId={quickActionOptions.defaultPagadorId}
								contaOptions={quickActionOptions.contaOptions}
								cartaoOptions={quickActionOptions.cartaoOptions}
								categoriaOptions={quickActionOptions.categoriaOptions}
								estabelecimentos={quickActionOptions.estabelecimentos}
								defaultPeriod={period}
								defaultTransactionType="Receita"
								trigger={
									<Button
										size="sm"
										variant="outline"
										className="h-12 w-full min-w-0 flex-col justify-center gap-0.5 px-1.5 text-sm whitespace-normal sm:h-8 sm:w-auto sm:flex-row sm:gap-2 sm:px-3 sm:whitespace-nowrap"
									>
										<span className="flex items-center gap-0.5">
											<RiAddCircleLine className="size-3.5 shrink-0 text-success/80" />
										</span>
										<span className="sm:hidden">Receita</span>
										<span className="hidden sm:inline">Nova receita</span>
									</Button>
								}
							/>
							<LancamentoDialog
								mode="create"
								pagadorOptions={quickActionOptions.pagadorOptions}
								splitPagadorOptions={quickActionOptions.splitPagadorOptions}
								defaultPagadorId={quickActionOptions.defaultPagadorId}
								contaOptions={quickActionOptions.contaOptions}
								cartaoOptions={quickActionOptions.cartaoOptions}
								categoriaOptions={quickActionOptions.categoriaOptions}
								estabelecimentos={quickActionOptions.estabelecimentos}
								defaultPeriod={period}
								defaultTransactionType="Despesa"
								trigger={
									<Button
										size="sm"
										variant="outline"
										className="h-12 w-full min-w-0 flex-col justify-center gap-0.5 px-1.5 text-sm whitespace-normal sm:h-8 sm:w-auto sm:flex-row sm:gap-2 sm:px-3 sm:whitespace-nowrap"
									>
										<span className="flex items-center gap-0.5">
											<RiAddCircleLine className="size-3.5 shrink-0 text-destructive/80" />
										</span>
										<span className="sm:hidden">Despesa</span>
										<span className="hidden sm:inline">Nova despesa</span>
									</Button>
								}
							/>
							<NoteDialog
								mode="create"
								trigger={
									<Button
										size="sm"
										variant="outline"
										className="h-12 w-full min-w-0 flex-col justify-center gap-0.5 px-1.5 text-sm whitespace-normal sm:h-8 sm:w-auto sm:flex-row sm:gap-2 sm:px-3 sm:whitespace-nowrap"
									>
										<RiTodoLine className="size-3.5 shrink-0 text-info/80" />
										<span className="sm:hidden">Anotação</span>
										<span className="hidden sm:inline">Nova anotação</span>
									</Button>
								}
							/>
						</div>
					</div>
				) : (
					<div />
				)}

				<div className="flex w-full items-center justify-end gap-2 sm:w-auto">
					{isEditing ? (
						<>
							<Button
								variant="outline"
								size="sm"
								onClick={handleCancelEditing}
								disabled={isPending}
								className="gap-2"
							>
								<RiCloseLine className="size-4" />
								Cancelar
							</Button>
							<Button
								size="sm"
								onClick={handleSave}
								disabled={isPending}
								className="gap-2"
							>
								<RiCheckLine className="size-4" />
								Salvar
							</Button>
						</>
					) : (
						<div className="grid w-full grid-cols-2 gap-2 sm:flex sm:w-auto">
							<WidgetSettingsDialog
								hiddenWidgets={hiddenWidgets}
								onToggleWidget={handleToggleWidget}
								onReset={handleReset}
								triggerClassName="w-full sm:w-auto"
							/>
							<Button
								variant="outline"
								size="sm"
								onClick={handleStartEditing}
								className="w-full gap-2 sm:w-auto"
							>
								<RiDragMove2Line className="size-4" />
								Reordenar
							</Button>
						</div>
					)}
				</div>
			</div>

			{/* Grid */}
			<DndContext
				sensors={sensors}
				collisionDetection={closestCorners}
				onDragEnd={handleDragEnd}
			>
				<SortableContext
					items={orderedWidgets.map((w) => w.id)}
					strategy={rectSortingStrategy}
				>
					<section className="grid grid-cols-1 gap-3 @4xl/main:grid-cols-2 @6xl/main:grid-cols-3">
						{orderedWidgets.map((widget) => (
							<SortableWidget
								key={widget.id}
								id={widget.id}
								isEditing={isEditing}
							>
								<div className="relative">
									{isEditing && (
										<div className="absolute inset-0 z-10 bg-background/50 backdrop-blur-[1px] rounded-lg border-2 border-dashed border-primary/50 flex items-center justify-center">
											<div className="flex flex-col items-center gap-2">
												<RiDragMove2Line className="size-8 text-primary" />
												<span className="text-xs font-bold">
													Arraste para mover
												</span>
												<Button
													variant="destructive"
													size="sm"
													onClick={(e) => {
														e.stopPropagation();
														handleHideWidget(widget.id);
													}}
													className="gap-1 mt-2"
												>
													<RiEyeOffLine className="size-4" />
													Ocultar
												</Button>
											</div>
										</div>
									)}
									<WidgetCard
										title={widget.title}
										subtitle={widget.subtitle}
										icon={widget.icon}
										action={widget.action}
									>
										{widget.component({ data, period })}
									</WidgetCard>
								</div>
							</SortableWidget>
						))}
					</section>
				</SortableContext>
			</DndContext>

			{/* Hidden widgets indicator */}
			{hiddenWidgets.length > 0 && !isEditing && (
				<p className="text-center text-sm text-muted-foreground">
					{hiddenWidgets.length} widget(s) oculto(s) •{" "}
					<button
						onClick={handleReset}
						className="text-primary hover:underline"
					>
						Restaurar todos
					</button>
				</p>
			)}
		</div>
	);
}
