"use client";
import { CircleOff } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect, useRef, useState } from "react";
import Input from "~/components/custom_ui/input";
import { StaggeredFade } from "~/components/custom_ui/staggered-fade";
import { useClickOutside } from "~/hooks/useClickOutside";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { api } from "~/utils/api";

export const CodiceBox = ({
	className,
	optionBoxClassName,
	optionsClassName,
	containerClassName,
	inputId,
}: {
	className?: string;
	optionBoxClassName?: string;
	optionsClassName?: string;
	containerClassName?: string;
	inputId: string;
}) => {
	const { data: codici, isLoading: loading } = api.annunci.getCodici.useQuery();
	const { locale } = useTranslation();

	return (
		<AutocompleteSearchBox
			className={className}
			containerClassName={containerClassName}
			inputId={inputId}
			key={locale}
			loading={loading}
			optionBoxClassName={optionBoxClassName}
			options={codici || []}
			optionsClassName={optionsClassName}
		/>
	);
};

type SearchBoxProps = {
	options: string[];
	loading: boolean;
	className?: string;
	optionBoxClassName?: string;
	optionsClassName?: string;
	containerClassName?: string;
	inputId: string;
};

const AutocompleteSearchBox = ({
	options,
	loading,
	className,
	optionBoxClassName,
	optionsClassName,
	containerClassName,
	inputId,
}: SearchBoxProps) => {
	const router = useRouter();
	const [open, setOpen] = useState<boolean>(false);
	const [results, setResults] = useState<string[]>(options);
	const [isFocused, setIsFocused] = useState<boolean>(false);
	const [searchValue, setSearchValue] = useState<string>("");
	const [navigationEnter, setNavigationEnter] = useState<boolean>(false);

	const wrapperRef = useRef<HTMLDivElement | null>(null);
	const listRef = useRef<HTMLDivElement | null>(null);

	useClickOutside([wrapperRef, listRef], () => setOpen(false));

	useEffect(() => {
		if (searchValue.trim() === "" || searchValue.length === 0) {
			setResults(options);
		} else {
			setResults(
				options.filter((option) => option.includes(searchValue.trim())),
			);
		}
	}, [searchValue, options]);

	return (
		<div className="z-[5000] w-full" ref={wrapperRef}>
			<div
				className={cn(
					"relative flex w-full items-center justify-center rounded-md bg-[color-mix(in_oklch,var(--fxd-secondary)50%,white)]",

					containerClassName,
				)}
				id="searchContainer"
			>
				<label className="sr-only" htmlFor={inputId || "search"}>
					Search Box
				</label>
				<Input
					className={cn(
						"z-10 cursor-pointer search-cancel:cursor-pointer rounded-md border-fxd-foreground bg-transparent text-fxd-foreground text-xl search-cancel:brightness-75 search-cancel:grayscale placeholder:font-bold placeholder:text-primary focus:ring-fxd-secondary",
						className,
					)}
					id={inputId || "search"}
					onBlur={() => {
						setIsFocused(false);
					}}
					onChange={(e) => setSearchValue(e.target.value)}
					onFocus={() => {
						setOpen(true);
						setIsFocused(true);
					}}
					onKeyDown={async (e) => {
						if (e.key === "Enter" && results[0] && results.length > 0) {
							setNavigationEnter(true);
							await router.push(`/annuncio/${results[0].trim()}`);
						}
					}}
					type="search"
					value={searchValue}
				/>
				<MovingText hidden={isFocused || searchValue !== ""} />
			</div>
			{open && (
				<div
					className={cn(
						"absolute z-50 mt-1 max-h-64 w-full overflow-hidden rounded-md border border-fxd-foreground bg-fxd-secondary shadow-xs ring-1 ring-fxd-secondary",

						optionBoxClassName,
					)}
					id="searchOptionsBox"
					ref={listRef}
				>
					<ul
						className={cn(
							"max-h-64 w-full overflow-y-auto",
							navigationEnter &&
								"[&>li:first-child>a]:underline [&>li:first-child>a]:underline-offset-2",
							"scrollbar-default",
						)}
						// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: <need list>
						role="listbox"
					>
						{loading ? (
							<li className={"px-3 py-2 text-center text-neutral-600 text-xl"}>
								<span>Caricamento...</span>
							</li>
						) : (
							<>
								{results.length === 0 && (
									<li
										className={"px-3 py-2 text-center text-neutral-600 text-xl"}
									>
										<span>
											<CircleOff className="inline size-6" />
										</span>
									</li>
								)}

								{results.map((item) => (
									<li key={item}>
										<Link
											className={cn(
												"flex w-full cursor-pointer items-center justify-between border-fxd-foreground border-b bg-[color-mix(in_oklch,var(--fxd-secondary)50%,white)] px-4 py-2 text-fxd-foreground text-xl duration-150 hover:bg-fxd-secondary hover:text-[color-mix(in_oklch,var(--fxd-foreground)90%,black)] hover:underline hover:underline-offset-2",
												optionsClassName,
											)}
											href={`/annuncio/${item}`}
										>
											{item}
										</Link>
									</li>
								))}
							</>
						)}
					</ul>
				</div>
			)}
		</div>
	);
};

const backupFrase = "Inserisci il codice 👈";
const MovingText = ({ hidden }: { hidden: boolean }) => {
	const { t } = useTranslation();

	const [randomFrase, setRandomFrase] = useState<string>(
		t.code_search_frases[0] || backupFrase,
	);
	useEffect(() => {
		const interval = setInterval(() => {
			const randomIndex = Math.floor(
				Math.random() * t.code_search_frases.length,
			);
			setRandomFrase(t.code_search_frases[randomIndex] || backupFrase);
		}, 5000);

		return () => clearInterval(interval);
	}, [t]);

	return (
		<StaggeredFade
			className="pointer-events-none absolute select-none font-bold text-2xl text-primary dark:text-primary-foreground"
			hide={hidden}
			key={randomFrase}
			text={randomFrase}
		/>
	);
};
