import { ExternalLink, Package, PackageCheck, UserCircle } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/router";
import { type ReactNode, useEffect } from "react";
import toast from "react-hot-toast";
import { InteressatoButtonBatchV } from "~/components/annuncio-interactions/annuncio_interactions";
import { AddButton } from "~/components/servizio/annuncio_actions";
import {
	AnnuncioCard,
	BasicAnnuncioCard,
} from "~/components/servizio/annuncio_card";
import { SaldoButton } from "~/components/servizio/interactions";
import { ServizioDuration } from "~/components/servizio/service-duration-display";
import {
	ServizioActions,
	ServizioActions2,
} from "~/components/servizio/servizio_actions";
import {
	AnnunciCompatibili,
	AnnunciInConferma,
	AnnunciSelezionati,
} from "~/components/servizio/servizio_annunci_accordions";
import { Button } from "~/components/ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardHeader,
	CardTitle,
} from "~/components/ui/card";
import {
	Dialog,
	DialogContent,
	DialogDescription,
	DialogHeader,
	DialogTitle,
	DialogTrigger,
} from "~/components/ui/dialog";
import { Progress } from "~/components/ui/progress";
import { cn } from "~/lib/utils";
import {
	ServizioAnnuncioProvider,
	ServizioProvider,
	useServizio,
} from "~/providers/ServizioProvider";
import type { UsersId } from "~/schemas/public/Users";
import type { ServizioData } from "~/server/controllers/servizio.controller";
import { api } from "~/utils/api";

export const ServizioContainer = ({
	servizio,
	userId,
	isAdmin,
}: {
	servizio: ServizioData;
	userId: UsersId;
	isAdmin: boolean;
}) => {
	return (
		<ServizioProvider
			isAdmin={isAdmin}
			servizio={servizio}
			servizioId={servizio.servizio_id}
			userId={userId}
		>
			<ServizioMain />
		</ServizioProvider>
	);
};

const ServizioCard = ({
	cardClassName,
	header,
	headerClassName,
	content,
	contentClassName,
}: {
	cardClassName?: string;
	header: React.ReactNode;
	headerClassName?: string;
	content: React.ReactNode;
	contentClassName?: string;
}) => {
	return (
		<Card
			className={cn("gap-2 border-neutral-200 bg-neutral-200", cardClassName)}
		>
			<CardHeader
				className={cn(
					"flex flex-col items-start justify-between gap-3 space-y-0 px-4 pb-8 sm:flex-row",
					headerClassName,
				)}
			>
				{header}
			</CardHeader>
			<CardContent className={cn("space-y-4 p-4 pt-0", contentClassName)}>
				{content}
			</CardContent>
		</Card>
	);
};

export const ServizioContent = () => {
	const { servizio, isAdmin, userId } = useServizio();
	const utils = api.useUtils();
	const { mutate: updateServizio } = api.servizio.updateServizio.useMutation({
		onError: (error) => {
			toast.error(error.message);
		},
		onSuccess: async () => {
			toast.success("Servizio modificato con successo");
			await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
		},
	});

	const router = useRouter();
	useEffect(() => {
		const id = router.asPath.split("#")[1];
		if (id) {
			document.getElementById(id)?.scrollIntoView({
				behavior: "smooth",
			});
		}
	}, []);

	if (servizio.isInterrotto) {
		return (
			<ServizioCard
				cardClassName="bg-neutral-100 border-neutral-300"
				content={
					<>
						<p className="font-medium text-lg">Servizio interrotto</p>
						<p>
							Non è possibile riutilizzare questo servizio, poichè è stato
							interrotto.
						</p>
					</>
				}
				header={
					<>
						<div className="flex flex-col gap-4">
							<CardTitle className="flex items-center gap-2 text-xl sm:text-2xl">
								<Package className="size-6 text-primary" />
								Cerco Affitto {servizio.tipologia}
							</CardTitle>

							<CardDescription className="space-y-2 pl-2 text-foreground/70">
								<p>
									aggiunto il{" "}
									{servizio.created_at.toLocaleDateString("it", {
										day: "2-digit",
										month: "2-digit",
										year: "numeric",
									})}
								</p>
							</CardDescription>
						</div>
					</>
				}
			/>
		);
	}

	if (!servizio.isOkAcconto || servizio.decorrenza === null) {
		return (
			<ServizioCard
				content={
					<div className="flex flex-col gap-4">
						<div className="flex flex-wrap gap-3">
							<Link
								aria-label="Attiva Servizio"
								href={`/servizio/onboard/${servizio.servizio_id}`}
							>
								<Button>Procedi all&apos;attivazione</Button>
							</Link>
							{isAdmin && (
								<Button
									onClick={() =>
										updateServizio({
											data: {
												decorrenza: new Date(),
												isOkAcconto: true,
											},
											servizioId: servizio.servizio_id,
										})
									}
									variant="success"
								>
									Attiva Manualmente (Azione Admin)
								</Button>
							)}
						</div>
						{isAdmin && (
							<AnnunciSelezionati
								annunci={servizio.annunci}
								isConfirming={false}
							/>
						)}
					</div>
				}
				header={
					<div className="flex w-full flex-col gap-2">
						<span className="text-foreground/70 text-lg">
							Servizio non attivo
						</span>
						<ServizioActions2 />
					</div>
				}
			/>
		);
	}
	const annuncioConfermato = servizio.annunci.filter(
		(a) => a.accettato_conferma_at !== null,
	);

	if (servizio.isOkSaldo) {
		return (
			<ServizioCard
				content={
					<>
						{annuncioConfermato.map((data) => {
							return (
								<ServizioAnnuncioProvider data={data} key={data.id}>
									<AnnuncioCard />
								</ServizioAnnuncioProvider>
							);
						})}
					</>
				}
				header={
					<>
						<ServizioActions2 />
					</>
				}
			/>
		);
	}

	const openContattiCount = servizio.annunci.filter(
		(a) => a.open_contatti_at !== null,
	).length;

	const annunciInConferma = servizio.annunci.filter(
		(a) => a.user_confirmed_at !== null,
	);
	const annunciNotInConferma = servizio.annunci.filter(
		(a) => a.user_confirmed_at === null,
	);

	return (
		<ServizioCard
			content={
				<>
					<div className="flex flex-col gap-2">
						<div className="flex items-center justify-between">
							<div className="flex items-center gap-2">
								<UserCircle className="size-6 text-primary" />
								<span className="font-medium">Contatti sbloccati</span>
							</div>
							<span className="text-sm">{openContattiCount} / 10</span>
						</div>
						<Progress className="h-2" value={openContattiCount * 10} />
					</div>

					<ServizioDuration decorrenza={servizio.decorrenza} />

					{annuncioConfermato.length > 0 && (
						<div className="flex flex-col gap-2">
							<div className="flex items-center gap-2">
								<PackageCheck className="size-6 text-primary" />
								<span className="font-medium">Saldi in attesa:</span>
							</div>
							{servizio.annunci
								.filter((a) => a.accettato_conferma_at !== null)
								.map((a) => (
									<div
										className="flex items-center gap-2 rounded-md bg-sky-400 p-2"
										key={a.annunci_id}
									>
										<h3>
											{a.codice} - confermato il:{" "}
											{/** biome-ignore lint/style/noNonNullAssertion: <already checked above> */}
											{new Date(a.accettato_conferma_at!).toLocaleDateString(
												"it",
												{
													day: "2-digit",
													hour: "2-digit",
													minute: "2-digit",
													month: "2-digit",
													year: "numeric",
												},
											)}
										</h3>
										<SaldoButton
											annuncioId={a.annunci_id}
											className="border-none"
											variant={"outline"}
										/>
									</div>
								))}
						</div>
					)}

					{/* <div className="space-y-2">
						<AnnunciInConferma annunci={annunciInConferma} />
						<AnnunciSelezionati
							annunci={annunciNotInConferma}
							isConfirming={annunciInConferma.length > 0}
						/>
						<AnnunciCompatibili />
					</div> */}
					<div className="flex items-center justify-between">
						<DialogServizio
							title="Annunci in conferma"
							trigger={
								<div className="relative">
									<Button
										disabled={annunciInConferma.length === 0}
										size="xl"
										variant="success"
									>
										Annunci in conferma
									</Button>
									<span className="-translate-y-1/2 absolute top-0 right-0 flex min-w-6 origin-center translate-x-1/2 items-center justify-center rounded-full bg-destructive px-1 text-white">
										{annunciInConferma.length}
									</span>
								</div>
							}
						>
							<div className="flex max-h-[80vh] flex-col gap-2 overflow-y-auto">
								{annunciInConferma.map((data) => {
									return (
										<ServizioAnnuncioProvider data={data} key={data.id}>
											<AnnuncioCard className="border-2 border-green-500" />
										</ServizioAnnuncioProvider>
									);
								})}
							</div>
						</DialogServizio>
						<DialogServizio
							title="Annunci selezionati"
							trigger={
								<div className="relative">
									<Button size="xl" variant="orange">
										Annunci selezionati
									</Button>
									<span className="-translate-y-1/2 absolute top-0 right-0 flex min-w-6 origin-center translate-x-1/2 items-center justify-center rounded-full bg-destructive px-1 text-white">
										{annunciNotInConferma.length}
									</span>
								</div>
							}
						>
							<div className="flex max-h-[80vh] flex-col gap-2 overflow-y-auto">
								{annunciNotInConferma.length > 0 ? (
									annunciNotInConferma.map((data) => {
										return (
											<ServizioAnnuncioProvider data={data} key={data.id}>
												<AnnuncioCard className="border-2 border-sky-500" />
											</ServizioAnnuncioProvider>
										);
									})
								) : (
									<div className="flex items-center justify-center gap-1 rounded-md bg-white p-4 sm:flex">
										<span>
											Nessun annuncio selezionato, fai una ricerca nella pagina{" "}
											<Link
												aria-label="Annunci Compatibili"
												className="inline-flex items-center gap-1 text-blue-500 underline"
												href="/annunci"
											>
												Annunci
												<ExternalLink className="size-4" />
											</Link>
										</span>
									</div>
								)}
							</div>
						</DialogServizio>
						{(() => {
							const { servizioId, userId, isAdmin } = useServizio();
							const { data, isLoading } =
								api.servizio.getCompatibileAnnunci.useQuery({
									servizioId,
								});

							const { data: userIntrests } =
								api.intrests.getUserInterests.useQuery({
									userId,
								});

							if (isLoading) return <div>Loading...</div>;
							return (
								<DialogServizio
									title="Annunci compatibili"
									trigger={
										<div className="relative">
											<Button className="bg-purple-500" size="xl">
												Annunci compatibili
											</Button>
											<span className="-translate-y-1/2 absolute top-0 right-0 flex min-w-6 origin-center translate-x-1/2 items-center justify-center rounded-full bg-destructive px-1 text-white">
												{data?.length}
											</span>
										</div>
									}
								>
									<div className="flex max-h-[80vh] flex-col gap-2 overflow-y-auto">
										{!data || data.length === 0 ? (
											<div className="flex items-center justify-center gap-1 rounded-md bg-white p-4 sm:flex">
												<span>
													Nessun annuncio compatibile trovato. Amplia la ricerca
													per trovare annunci compatibili.
												</span>
											</div>
										) : (
											data.map((a) => {
												return (
													<BasicAnnuncioCard
														className="border-2 border-neutral-500"
														data={a}
														interactions={
															<>
																{isAdmin ? (
																	<AddButton annuncioId={a.id} />
																) : (
																	<InteressatoButtonBatchV
																		annuncioId={a.id}
																		hasInterest={
																			userIntrests?.includes(a.id) || false
																		}
																	/>
																)}
															</>
														}
														key={a.id}
													/>
												);
											})
										)}
									</div>
								</DialogServizio>
							);
						})()}
					</div>
				</>
			}
			header={
				<>
					<ServizioActions2 />
				</>
			}
		/>
	);
};

const DialogServizio = ({
	trigger,
	title,
	children,
}: {
	trigger: ReactNode;
	title: string;
	children: ReactNode;
}) => {
	return (
		<Dialog>
			<DialogTrigger asChild>{trigger}</DialogTrigger>
			<DialogContent className="md:max-w-5xl">
				<DialogHeader>
					<DialogTitle>{title}</DialogTitle>
					<DialogDescription className="sr-only">
						Servizio Dialog
					</DialogDescription>
				</DialogHeader>
				{children}
			</DialogContent>
		</Dialog>
	);
};

const ServizioMain = () => {
	const { servizio, isAdmin, userId } = useServizio();
	const utils = api.useUtils();
	const { mutate: updateServizio } = api.servizio.updateServizio.useMutation({
		onError: (error) => {
			toast.error(error.message);
		},
		onSuccess: async () => {
			toast.success("Servizio modificato con successo");
			await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
		},
	});

	const router = useRouter();
	useEffect(() => {
		const id = router.asPath.split("#")[1];
		if (id) {
			document.getElementById(id)?.scrollIntoView({
				behavior: "smooth",
			});
		}
	}, []);

	if (servizio.isInterrotto) {
		return (
			<ServizioCard
				cardClassName="bg-neutral-100 border-neutral-300"
				content={
					<>
						<p className="font-medium text-lg">Servizio interrotto</p>
						<p>
							Non è possibile riutilizzare questo servizio, poichè è stato
							interrotto.
						</p>
					</>
				}
				header={
					<>
						<div className="flex flex-col gap-4">
							<CardTitle className="flex items-center gap-2 text-xl sm:text-2xl">
								<Package className="size-6 text-primary" />
								Cerco Affitto {servizio.tipologia}
							</CardTitle>

							<CardDescription className="space-y-2 pl-2 text-foreground/70">
								<p>
									aggiunto il{" "}
									{servizio.created_at.toLocaleDateString("it", {
										day: "2-digit",
										month: "2-digit",
										year: "numeric",
									})}
								</p>
							</CardDescription>
						</div>
					</>
				}
			/>
		);
	}

	if (!servizio.isOkAcconto || servizio.decorrenza === null) {
		return (
			<ServizioCard
				content={
					<div className="flex flex-col gap-4">
						<div className="flex flex-wrap gap-3">
							<Link
								aria-label="Attiva Servizio"
								href={`/servizio/onboard/${servizio.servizio_id}`}
							>
								<Button>Procedi all&apos;attivazione</Button>
							</Link>
							{isAdmin && (
								<Button
									onClick={() =>
										updateServizio({
											data: {
												decorrenza: new Date(),
												isOkAcconto: true,
											},
											servizioId: servizio.servizio_id,
										})
									}
									variant="success"
								>
									Attiva Manualmente (Azione Admin)
								</Button>
							)}
						</div>
						{isAdmin && (
							<AnnunciSelezionati
								annunci={servizio.annunci}
								isConfirming={false}
							/>
						)}
					</div>
				}
				header={
					<>
						<div className="flex w-full flex-col gap-4">
							<CardTitle className="flex items-center gap-2 text-xl sm:text-2xl">
								<Package className="size-6 text-primary" />
								Cerco Affitto {servizio.tipologia}
							</CardTitle>
							<CardDescription className="pl-2 text-foreground/70">
								<p>Servizio non attivo</p>
							</CardDescription>
						</div>
						<ServizioActions />
					</>
				}
			/>
		);
	}
	const annuncioConfermato = servizio.annunci.filter(
		(a) => a.accettato_conferma_at !== null,
	);

	if (servizio.isOkSaldo) {
		return (
			<ServizioCard
				content={
					<>
						{annuncioConfermato.map((data) => {
							return (
								<ServizioAnnuncioProvider data={data} key={data.id}>
									<AnnuncioCard />
								</ServizioAnnuncioProvider>
							);
						})}
					</>
				}
				header={
					<>
						<div className="flex w-full flex-wrap items-center gap-2">
							<CardTitle className="flex items-center gap-2 text-xl sm:text-2xl">
								<Package className="size-6 text-primary" />
								Cerco Affitto {servizio.tipologia}
							</CardTitle>

							<CardDescription className="space-y-2 pl-2 text-foreground/70">
								<p>
									aggiunto il{" "}
									{servizio.created_at.toLocaleDateString("it", {
										day: "2-digit",
										month: "2-digit",
										year: "numeric",
									})}
								</p>
							</CardDescription>
						</div>

						<ServizioActions />
					</>
				}
			/>
		);
	}

	const openContattiCount = servizio.annunci.filter(
		(a) => a.open_contatti_at !== null,
	).length;

	const annunciInConferma = servizio.annunci.filter(
		(a) => a.user_confirmed_at !== null,
	);
	const annunciNotInConferma = servizio.annunci.filter(
		(a) => a.user_confirmed_at === null,
	);

	return (
		<ServizioCard
			content={
				<>
					<div className="flex flex-col gap-2">
						<div className="flex items-center justify-between">
							<div className="flex items-center gap-2">
								<UserCircle className="size-6 text-primary" />
								<span className="font-medium">Contatti sbloccati</span>
							</div>
							<span className="text-sm">{openContattiCount} / 10</span>
						</div>
						<Progress className="h-2" value={openContattiCount * 10} />
					</div>

					<ServizioDuration decorrenza={servizio.decorrenza} />

					{annuncioConfermato.length > 0 && (
						<div className="flex flex-col gap-2">
							<div className="flex items-center gap-2">
								<PackageCheck className="size-6 text-primary" />
								<span className="font-medium">Saldi in attesa:</span>
							</div>
							{servizio.annunci
								.filter((a) => a.accettato_conferma_at !== null)
								.map((a) => (
									<div
										className="flex items-center gap-2 rounded-md bg-sky-400 p-2"
										key={a.annunci_id}
									>
										<h3>
											{a.codice} - confermato il:{" "}
											{/** biome-ignore lint/style/noNonNullAssertion: <already checked> */}
											{new Date(a.accettato_conferma_at!).toLocaleDateString(
												"it",
												{
													day: "2-digit",
													hour: "2-digit",
													minute: "2-digit",
													month: "2-digit",
													year: "numeric",
												},
											)}
										</h3>
										<SaldoButton
											annuncioId={a.annunci_id}
											className="border-none"
											variant={"outline"}
										/>
									</div>
								))}
						</div>
					)}

					<div className="space-y-2">
						<AnnunciInConferma annunci={annunciInConferma} />
						<AnnunciSelezionati
							annunci={annunciNotInConferma}
							isConfirming={annunciInConferma.length > 0}
						/>
						<AnnunciCompatibili />
					</div>
				</>
			}
			header={
				<>
					<div className="flex w-full flex-col gap-2">
						<CardTitle className="flex items-center gap-2 text-xl sm:text-2xl">
							<Package className="size-6 text-primary" />
							Cerco Affitto {servizio.tipologia}
						</CardTitle>

						<CardDescription className="space-y-2 pl-2 text-foreground/70">
							<p>
								aggiunto il{" "}
								{servizio.created_at.toLocaleDateString("it", {
									day: "2-digit",
									month: "2-digit",
									year: "numeric",
								})}
							</p>
						</CardDescription>
					</div>

					<ServizioActions />
				</>
			}
		/>
	);
};
