"use client";

import { RiExpandDiagonalLine } from "@remixicon/react";
import { useEffect, useRef, useState } from "react";
import { Button } from "@/shared/components/ui/button";
import {
	Dialog,
	DialogContent,
	DialogHeader,
	DialogTitle,
} from "@/shared/components/ui/dialog";
import type { WidgetCardProps } from "@/shared/components/widgets/widget-card";
import WidgetCard from "@/shared/components/widgets/widget-card";

const OVERFLOW_THRESHOLD_PX = 16;
const EXPANDABLE_CONTENT_CLASSNAME =
	"max-h-[calc(var(--spacing-custom-height-card)-5rem)] overflow-hidden md:max-h-[calc(100%-5rem)]";

export function ExpandableWidgetCard({
	title,
	subtitle,
	icon,
	children,
	action,
}: WidgetCardProps) {
	const contentRef = useRef<HTMLDivElement | null>(null);
	const [hasOverflow, setHasOverflow] = useState(false);
	const [isOpen, setIsOpen] = useState(false);

	useEffect(() => {
		const element = contentRef.current;
		if (!element) return;

		let frameId = 0;
		const observedElements = new Set<Element>();

		const checkOverflow = () => {
			cancelAnimationFrame(frameId);
			frameId = window.requestAnimationFrame(() => {
				const hasOverflowNow =
					element.scrollHeight - element.clientHeight > OVERFLOW_THRESHOLD_PX;
				setHasOverflow((currentValue) =>
					currentValue === hasOverflowNow ? currentValue : hasOverflowNow,
				);
			});
		};

		const observeContentElements = (resizeObserver: ResizeObserver) => {
			for (const child of Array.from(element.children)) {
				if (!observedElements.has(child)) {
					resizeObserver.observe(child);
					observedElements.add(child);
				}
			}
		};

		checkOverflow();

		const resizeObserver = new ResizeObserver(checkOverflow);
		resizeObserver.observe(element);
		observeContentElements(resizeObserver);

		const mutationObserver = new MutationObserver(() => {
			observeContentElements(resizeObserver);
			checkOverflow();
		});
		mutationObserver.observe(element, {
			childList: true,
			subtree: true,
		});

		return () => {
			cancelAnimationFrame(frameId);
			mutationObserver.disconnect();
			resizeObserver.disconnect();
		};
	}, []);

	return (
		<>
			<WidgetCard
				title={title}
				subtitle={subtitle}
				icon={icon}
				action={action}
				contentRef={contentRef}
				contentClassName={EXPANDABLE_CONTENT_CLASSNAME}
				overlay={
					hasOverflow ? (
						<div className="pointer-events-none absolute inset-x-0 bottom-0 flex justify-center bg-linear-to-t from-card to-transparent pt-8 pb-4">
							<Button
								variant="secondary"
								size="sm"
								className="pointer-events-auto text-xs"
								onClick={() => setIsOpen(true)}
								aria-label="Expandir para ver todo o conteúdo"
							>
								Expandir
								<RiExpandDiagonalLine className="size-3" aria-hidden="true" />
							</Button>
						</div>
					) : null
				}
			>
				{children}
			</WidgetCard>

			<Dialog open={isOpen} onOpenChange={setIsOpen}>
				<DialogContent className="max-h-[85vh] w-full max-w-[calc(100%-2rem)] sm:max-w-3xl overflow-hidden p-6">
					<DialogHeader className="text-left">
						<DialogTitle className="flex items-center gap-2">
							{icon}
							<span>{title}</span>
						</DialogTitle>
						{subtitle ? (
							<p className="text-muted-foreground text-sm">{subtitle}</p>
						) : null}
					</DialogHeader>
					<div className="-mr-3 max-h-[calc(85vh-6rem)] overflow-y-auto pb-6 pr-3 [scrollbar-gutter:stable]">
						{children}
					</div>
				</DialogContent>
			</Dialog>
		</>
	);
}
