import {
	BedDouble,
	CalendarClock,
	MapPin,
	Maximize2,
	Ruler,
	Siren,
	Star,
	TrafficCone,
} from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import { type RefObject, useEffect, useRef, useState } from "react";
import { useIntersection } from "react-use";
import {
	Carousel,
	CarouselContent,
	CarouselItem,
	CarouselNext,
	CarouselPrevious,
} from "~/components/ui/carousel";
import {
	Dialog,
	DialogContent,
	DialogDescription,
	DialogHeader,
	DialogTitle,
} from "~/components/ui/dialog";
import { camereTesti, handleConsegna } from "~/lib/annuncio_details";
import { getStorageUrl } from "~/lib/storage_utils";
import { cn, formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import type { ImagesRefs } from "~/schemas/public/ImagesRefs";
import type { VideosRefs } from "~/schemas/public/VideosRefs";
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
import { Badge } from "./ui/badge";
import { Skeleton } from "./ui/skeleton";
import { VideoPlayer } from "./videoPlayer";

type CardAnnuncioProps = AnnuncioRicerca & {
	className?: string;
	noLink?: boolean;
	onlyFirstImage?: boolean;
	eager?: boolean;
};

export const LazyCardAnnuncio = (props: CardAnnuncioProps) => {
	const { eager = false } = props;
	const intersectionRef = useRef<HTMLDivElement>(null);
	const hasRenderedRef = useRef(eager);
	const [shouldRender, setShouldRender] = useState(eager);

	const intersection = useIntersection(
		intersectionRef as RefObject<HTMLElement>,
		{
			root: null,
			rootMargin: "300px",
			threshold: 0.01,
		},
	);

	useEffect(() => {
		if (
			!hasRenderedRef.current &&
			intersection &&
			intersection.intersectionRatio > 0
		) {
			hasRenderedRef.current = true;
			setShouldRender(true);
		}
	}, [intersection]);

	return (
		<div
			className="min-h-[31.1rem]"
			onClick={(e) => {
				e.preventDefault();
				e.stopPropagation();
			}}
			onKeyDown={(e) => e.stopPropagation()}
			ref={intersectionRef}
			role="button"
			tabIndex={0}
		>
			{shouldRender ? <CardAnnuncio {...props} /> : <SkeletonCardAnnuncio />}
		</div>
	);
};

const SkeletonCardAnnuncio = () => {
	return (
		<div className="h-[31.1rem] rounded-md bg-secondary p-2 outline outline-neutral-300 hover:outline-neutral-600">
			<div className="flex h-full flex-col gap-2 p-2">
				<Skeleton className="h-64 w-full rounded-t-md" />
				<div className="flex flex-col gap-2">
					<Skeleton className="h-8 w-full rounded-md" />

					<div className="flex flex-row justify-between gap-3 px-4">
						<Skeleton className="h-10 w-full rounded-md" />
						<Skeleton className="h-10 w-full rounded-md" />
					</div>
					<div className="flex h-34 flex-col justify-between">
						<Skeleton className="h-20 w-full rounded-md" />

						<div className="flex h-9 items-center justify-around gap-1.5">
							<Skeleton className="size-full rounded-md" />
							<Skeleton className="size-full rounded-md" />
							<Skeleton className="size-full rounded-md" />
						</div>
					</div>
				</div>
			</div>
		</div>
	);
};
export const CardAnnuncio = ({
	id,
	codice,
	prezzo,
	titolo_it,
	titolo_en,
	mq,
	comune,
	provincia,
	consegna,
	numero_camere: camere,
	tipo,
	stato,
	className,
	videos,
	media_updated_at,
	images,
	homepage,
	noLink = false,
	onlyFirstImage = false,
}: CardAnnuncioProps) => {
	const { t, locale } = useTranslation();
	const currentMonth = new Date().getMonth() + 1;
	const isAvailableNow = consegna === 0 || consegna === currentMonth;

	const Wrapper = ({ children }: { children: React.ReactNode }) => {
		if (noLink) {
			return <div className="flex h-full flex-col gap-2 p-2">{children}</div>;
		}
		return (
			<Link
				className="flex h-full flex-col gap-2 p-2"
				href={`/annuncio/${codice}`}
			>
				{children}
			</Link>
		);
	};

	return (
		<div
			className={cn(
				"relative h-[31.1rem] rounded-md bg-secondary outline outline-primary/60 hover:outline-primary dark:bg-primary dark:outline-primary",
				className,
			)}
			id={`card-annuncio-${id}`}
		>
			<Wrapper>
				<div
					className={cn("group relative overflow-clip text-clip rounded-md")}
				>
					<div
						className={cn(
							"pointer-events-none absolute inset-0 z-20 size-full rounded-md",
							homepage &&
								(isAvailableNow
									? "border-[.35rem] border-dasubito"
									: "border-[.35rem] border-evidenza"),

							stato === "Trattativa" && "border-[.35rem] border-trattativa",
						)}
					></div>
					{stato !== "Trattativa" && homepage && (
						<div className="absolute top-1 z-20 flex w-full justify-center px-2">
							<Badge
								className={cn(
									"flex items-center gap-1.5 rounded-t-none px-1 py-0.5 font-semibold text-base text-white [&>svg]:size-4.5",
									isAvailableNow
										? "bg-dasubito"
										: "bg-evidenza text-primary dark:text-accent",
								)}
							>
								{isAvailableNow ? (
									<>
										<span>Libero Subito</span>
										<Siren />
									</>
								) : (
									<>
										<span>In Evidenza</span>
										<Star />
									</>
								)}
							</Badge>
						</div>
					)}
					{stato === "Trattativa" && (
						<div className="absolute top-1 z-20 flex w-full justify-center px-2">
							<Badge
								className={cn(
									"flex items-center gap-1.5 rounded-t-none bg-trattativa px-1 py-0.5 font-semibold text-base text-white [&>svg]:size-4.5",
								)}
							>
								<span>In Trattativa</span>
								<TrafficCone />
							</Badge>
						</div>
					)}
					{!onlyFirstImage ? (
						<Carousel opts={{ loop: true }}>
							<CarouselContent>
								{images?.map((img, idx) => (
									<CarouselItem key={`${img.img}key`}>
										<Image
											alt={t.card.alt_immagine}
											blurDataURL={getStorageUrl({
												storageId: img.thumb,
												params: {
													cacheKey: media_updated_at?.toISOString(),
													media: "image",
												},
											})}
											className={cn(
												"h-64 w-full bg-[#e6e9ec] object-cover",
												(stato === "Trattativa" || homepage) && "rounded-[7px]",
											)}
											height={1080}
											priority={idx === 0}
											src={getStorageUrl({
												storageId: img.img,
												params: {
													cacheKey: media_updated_at?.toISOString(),
													media: "image",
												},
											})}
											width={1920}
										/>
									</CarouselItem>
								))}
								{videos?.map((video) => {
									return (
										<CarouselItem
											className={cn("group relative")}
											key={`videoplayer-${video}`}
											onClick={(e) => {
												e.preventDefault();
												e.stopPropagation();
											}}
										>
											<VideoPlayer
												className="h-64 object-cover"
												coverImage={getStorageUrl({
													storageId: video.thumb,
													params: {
														cacheKey: media_updated_at?.toISOString(),
														media: "image",
													},
												})}
												key={`videoplayer-${video}`}
												videoSrc={getStorageUrl({
													storageId: video.video,
													params: {
														cacheKey: media_updated_at?.toISOString(),
														media: "video",
													},
												})}
											/>
										</CarouselItem>
									);
								})}
							</CarouselContent>

							<div
								className="block opacity-0 transition-all duration-200 group-hover:opacity-60 disabled:group-hover:opacity-0"
								onClick={(e) => {
									e.preventDefault();
									e.stopPropagation();
								}}
								onKeyDown={(e) => e.stopPropagation()}
								role="button"
								tabIndex={0}
							>
								<CarouselPrevious
									className="left-2 cursor-pointer"
									disabled={!images || images.length === 1}
								/>
								<CarouselNext
									className="right-2 cursor-pointer"
									disabled={!images || images.length === 1}
								/>
							</div>
						</Carousel>
					) : (
						<>
							{images && images.length > 0 && images[0] ? (
								<Image
									alt={t.card.alt_immagine}
									blurDataURL={getStorageUrl({
										storageId: images[0].thumb,
										params: {
											cacheKey: media_updated_at?.toISOString(),
											media: "image",
										},
									})}
									className={"h-64 w-full bg-[#e6e9ec] object-cover"}
									height={1080}
									priority={true}
									src={getStorageUrl({
										storageId: images[0].img,
										params: {
											cacheKey: media_updated_at?.toISOString(),
											media: "image",
										},
									})}
									width={1920}
								/>
							) : (
								<div className="flex h-64 w-full items-center justify-center bg-neutral-200 text-neutral-500"></div>
							)}
						</>
					)}
				</div>
				<div className="flex h-full grow flex-col gap-2">
					<Badge
						className={cn(
							"w-full font-semibold text-md text-white",
							tipo === "Transitorio" && "bg-transitorio",
							tipo === "Stabile" && "bg-stabile",
							tipo === "Cessione" && "bg-blue-400",
							tipo === "Vendita" && "bg-green-400",
						)}
					>
						Affitto {tipo}
					</Badge>
					<div className="flex flex-row justify-between gap-3 px-4">
						<div className="w-full text-center">
							<span className="sr-only">{t.card.codice}</span>

							<span className="font-semibold text-destructive text-xl">
								Cod: {codice}
							</span>
						</div>
						<div className="w-full text-center text-primary dark:text-accent">
							<span className="sr-only">{t.card.prezzo}</span>

							<span className="font-semibold text-xl">
								{formatCurrency(prezzo / 1e2)}
							</span>
						</div>
					</div>
					<div className="flex h-full grow flex-col justify-between">
						<div className="px-4 text-center text-primary dark:text-accent">
							<span className="sr-only">{t.card.titolo}</span>

							<span className="line-clamp-3 overflow-ellipsis font-medium text-base">
								{locale === "it" ? titolo_it : titolo_en}
							</span>
						</div>

						<div className="text-center text-primary dark:text-accent">
							<span className="sr-only">{t.card.indirizzo}</span>
							<MapPin className="mr-1 mb-1 inline-block size-4" />
							<span className="font-medium text-sm">
								{comune && provincia && `${comune} (${provincia})`}
							</span>
						</div>

						<div className="flex h-9 items-center justify-around gap-1.5 text-primary text-xs">
							<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-primary-foreground">
								<Ruler className="size-4" />

								<div>
									<p className="font-medium">
										{mq ? Number(mq).toLocaleString("it-IT") : "--"}{" "}
										<span>
											m<sup>2</sup>
										</span>
									</p>
								</div>
							</div>
							<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-primary-foreground">
								<BedDouble className="size-4" />

								<div>
									<p className="font-medium">
										{camereTesti({ camere: camere, testi: t.card })}
									</p>
								</div>
							</div>
							<div className="flex h-full w-full items-center justify-center gap-1 rounded-md bg-primary-foreground">
								<CalendarClock className="size-4" />

								<div>
									<p className="truncate font-medium">
										{handleConsegna({
											aggiornamento: t.card.in_aggiornamento,
											consegna: consegna,
											consegna_da: t.card.consegna_da,
											mesi: t.parametri.mesi,
											subito: t.card.consegna_subito,
										})}
									</p>
								</div>
							</div>
						</div>
					</div>
				</div>
			</Wrapper>
		</div>
	);
};

export const CarouselAnnuncio = ({
	single,
	immagini,
	videos,
	updated_at,
}: {
	single?: boolean;
	immagini: Pick<ImagesRefs, "img" | "thumb">[];
	videos: Pick<VideosRefs, "video" | "thumb">[];
	updated_at: Date | null;
}) => {
	const [openModal, setOpenModal] = useState(false);
	const [idxModal, setIdxModal] = useState(0);
	function handleOpenModal(position: number) {
		setIdxModal(position);
		setOpenModal(true);
	}
	return (
		<>
			<div className="mx-auto my-4 w-full text-clip rounded-md">
				<div className="relative">
					<Carousel opts={{ align: "start", loop: true }}>
						<CarouselContent>
							{immagini?.map((img, idx) => (
								<CarouselItem
									className={cn(
										"group relative flex items-center justify-center",
										immagini && immagini.length === 1
											? ""
											: !single && "md:basis-1/2 lg:basis-1/3",
									)}
									key={`${img.img}-cF`}
								>
									<Image
										alt={img.img}
										className={cn(
											"aspect-square max-h-92 w-full rounded-md bg-[#e6e9ec] object-cover sm:max-h-80 xl:max-h-100",
											immagini.length === 1 && "object-contain",
										)}
										height={400}
										onClick={() => handleOpenModal(idx)}
										priority={idx === 0}
										src={getStorageUrl({
											storageId: img.img,
											params: {
												cacheKey: updated_at?.toISOString(),
												media: "image",
											},
										})}
										width={800}
									/>
									<Maximize2
										className="absolute right-2 bottom-2 size-7 origin-bottom-right cursor-pointer rounded-md bg-muted-foreground/60 stroke-2 stroke-muted p-1 transition-all duration-300 ease-in-out hover:scale-150 group-hover:opacity-100 sm:opacity-0"
										onClick={() => handleOpenModal(idx)}
									/>
								</CarouselItem>
							))}
							{videos?.map((video, idx) => {
								return (
									<CarouselItem
										className={cn(
											"group relative",
											immagini && immagini.length === 1
												? ""
												: !single && "md:basis-1/2 lg:basis-1/3",
										)}
										key={`videoplayer-${video.video}`}
									>
										<VideoPlayer
											className="aspect-square max-h-92 object-cover sm:max-h-80 xl:max-h-100"
											coverImage={getStorageUrl({
												storageId: video.thumb,
												params: {
													cacheKey: updated_at?.toISOString(),
													media: "image",
												},
											})}
											key={`videoplayer-${idx}-${openModal}`}
											videoSrc={getStorageUrl({
												storageId: video.video,
												params: {
													cacheKey: updated_at?.toISOString(),
													media: "video",
												},
											})}
										/>

										<Maximize2
											className="absolute right-2 bottom-2 size-7 origin-bottom-right cursor-pointer rounded-md bg-muted-foreground/60 stroke-2 stroke-muted p-1 transition-all duration-300 ease-in-out hover:scale-150 group-hover:opacity-100 sm:opacity-0"
											onClick={() =>
												handleOpenModal(immagini?.length || 0 + idx)
											}
										/>
									</CarouselItem>
								);
							})}
						</CarouselContent>

						<CarouselPrevious
							className="left-2 cursor-pointer opacity-60 disabled:opacity-0 dark:border-muted-foreground dark:bg-muted-foreground dark:text-muted hover:dark:bg-muted-foreground/80"
							disabled={!immagini || immagini.length === 1}
							type="button"
						/>
						<CarouselNext
							className="right-2 cursor-pointer opacity-60 disabled:opacity-0 dark:border-muted-foreground dark:bg-muted-foreground dark:text-muted hover:dark:bg-muted-foreground/80"
							disabled={!immagini || immagini.length === 1}
							type="button"
						/>
					</Carousel>
				</div>
			</div>
			<Dialog onOpenChange={setOpenModal} open={openModal}>
				<DialogContent className="flex h-full w-full max-w-full items-center justify-center border-transparent border-none bg-background p-0 md:max-w-[80vw] md:p-6 [&_#dialog-close>svg]:size-8">
					<DialogHeader className="absolute top-0 right-0 left-0 z-10">
						<DialogTitle className="sr-only">Image Dialog</DialogTitle>
						<DialogDescription className="sr-only">Immagine</DialogDescription>
					</DialogHeader>
					<Carousel opts={{ loop: true, startIndex: idxModal }}>
						<CarouselContent>
							{immagini?.map((img, idx) => (
								<CarouselItem key={`${img.img}-cD`}>
									<Image
										alt={`carousel-img-${idx}`}
										className="mx-auto h-[90vh] w-full rounded-md bg-[#e6e9ec] object-contain sm:w-[80vw]"
										height={1080}
										src={getStorageUrl({
											storageId: img.img,
											params: {
												cacheKey: updated_at?.toISOString(),
												media: "image",
											},
										})}
										width={1920}
									/>
								</CarouselItem>
							))}
							{videos?.map((video) => {
								return (
									<CarouselItem
										className="relative flex items-center justify-center"
										key={`carousel-videoplayer-${video.video}`}
									>
										<VideoPlayer
											className="absolute mx-auto h-[90vh] w-full max-w-fit rounded-md object-contain"
											coverImage={getStorageUrl({
												storageId: video.thumb,
												params: {
													cacheKey: updated_at?.toISOString(),
													media: "image",
												},
											})}
											videoSrc={getStorageUrl({
												storageId: video.video,
												params: {
													cacheKey: updated_at?.toISOString(),
													media: "video",
												},
											})}
										/>
									</CarouselItem>
								);
							})}
						</CarouselContent>

						<CarouselPrevious
							className="left-2 cursor-pointer opacity-60 disabled:opacity-0"
							disabled={!immagini || immagini.length === 1}
							type="button"
						/>
						<CarouselNext
							className="right-2 cursor-pointer opacity-60 disabled:opacity-0"
							disabled={!immagini || immagini.length === 1}
							type="button"
						/>
					</Carousel>
				</DialogContent>
			</Dialog>
		</>
	);
};
