import { add } from "date-fns";
import {
	ArrowRight,
	CalendarClock,
	CircleCheck,
	CircleCheckBig,
	CircleMinus,
	Clock,
	ClockFading,
	type LucideIcon,
	PackageCheck,
	Trash2,
} from "lucide-react";
import Link from "next/link";
import toast from "react-hot-toast";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
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";
import { Confirm } from "../confirm";
import { AlarmClockSVG } from "../svgs";
import { Button } from "../ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardHeader,
	CardTitle,
} from "../ui/card";
import { SaldoButton } from "./annuncio_actions";
import { AnnuncioCard, AnnuncioDisplay } from "./annuncio_card";
import { AnnunciCompatibili } from "./compatibili_dialog";
import {
	AdminActions,
	ServizioBasicActions,
	ServizioPacksInfos,
} from "./servizio_actions";

export const ServizioList = ({
	servizi,
	isAdmin,
	userId,
}: {
	servizi: ServizioData[];
	isAdmin: boolean;
	userId: UsersId;
}) => {
	const { t } = useTranslation();
	if (servizi.length === 0) {
		return (
			<div className="m-4 rounded-md bg-yellow-100 p-4 text-yellow-900">
				{t.servizio.nessun_servizio}
			</div>
		);
	}
	// if (servizi.length === 1 && servizi[0]) {
	// 	return <Servizio isAdmin={isAdmin} servizio={servizi[0]} userId={userId} />;
	// }
	return (
		<div className="flex flex-col gap-4">
			{servizi.map((servizio) => (
				<ServizioLinkCard
					isAdmin={isAdmin}
					key={servizio.servizio_id}
					servizio={servizio}
					userId={userId}
				/>
			))}
		</div>
	);
};

const ServizioLinkCard = ({
	servizio,
	isAdmin,
	userId,
}: {
	servizio: ServizioData;
	isAdmin: boolean;
	userId: UsersId;
}) => {
	const { t } = useTranslation();

	let status: keyof typeof t.servizio.status = "attivo";
	let StatusIcon: LucideIcon = CircleCheck;

	if (servizio.isInterrotto) {
		status = "interrotto";
		StatusIcon = Trash2;
	} else if (!servizio.isOkAcconto) {
		status = "in_attesa";
		StatusIcon = ClockFading;
	} else if (servizio.decorrenza) {
		const now = new Date();
		const decorrenza = new Date(servizio.decorrenza);
		if (now > add(decorrenza, { days: 60 }) && !servizio.isOkSaldo) {
			status = "scaduto";
			StatusIcon = CircleMinus;
		}
		if (servizio.isOkSaldo) {
			status = "completato";
			StatusIcon = CircleCheckBig;
		}
	}

	return (
		<Link
			className="group"
			href={
				isAdmin
					? `/area-riservata/admin/user-view/servizio/${userId}/${servizio.servizio_id}`
					: `/area-riservata/servizio/${servizio.servizio_id}`
			}
			key={servizio.servizio_id}
		>
			<Card
				className={cn(
					status === "attivo" && "border-green-500",
					status === "in_attesa" && "border-yellow-500",
					status === "interrotto" && "border-red-500",
					status === "scaduto" && "border-gray-500",
					status === "completato" && "border-blue-500",
					"transition-shadow hover:bg-muted/15 hover:shadow-md",
				)}
			>
				<CardHeader>
					<CardTitle className="group-hover:underline">
						{t.servizio.servizio_titolo} {servizio.tipologia}
					</CardTitle>
					<CardDescription className="">
						{t.servizio.servizio_creato_il}{" "}
						{servizio.created_at.toLocaleDateString("it-IT")}
					</CardDescription>
				</CardHeader>
				<CardContent className="flex flex-col flex-wrap gap-4 sm:flex-row sm:justify-between">
					<div
						className={cn(
							"flex items-center gap-2",
							status === "attivo" && "text-green-500",
							status === "in_attesa" && "text-yellow-500",
							status === "interrotto" && "text-red-500",
							status === "scaduto" && "text-gray-500",
							status === "completato" && "text-blue-500",
						)}
					>
						<StatusIcon className="size-5" />

						<span>{t.servizio.status[status]}</span>
					</div>
					<div className="flex items-center gap-2 rounded-md text-muted-foreground group-hover:text-foreground">
						<span>{t.servizio.vai_al_servizio}</span>
						<ArrowRight />
					</div>
				</CardContent>
			</Card>
		</Link>
	);
};

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

const Content = () => {
	const { servizio } = useServizio();
	const { t } = useTranslation();
	const dec_txt = servizio.decorrenza
		? new Date(servizio.decorrenza).toLocaleDateString("it-IT")
		: "N/A";
	const end_txt = servizio.decorrenza
		? new Date(add(servizio.decorrenza, { days: 60 })).toLocaleDateString(
				"it-IT",
			)
		: "N/A";

	return (
		<div className="w-full space-y-4">
			<div className="flex flex-col flex-wrap items-start justify-between gap-4 sm:flex-row">
				<div className="flex flex-col gap-1">
					<h3 className="font-semibold text-xl">
						{t.servizio.servizio_titolo} {servizio.tipologia}
					</h3>

					<div className="flex items-center gap-2 text-muted-foreground text-sm">
						<Clock className="size-5" />
						<span>
							Creato il: {servizio.created_at.toLocaleDateString("it-IT")}
						</span>
					</div>

					<div className="flex flex-wrap items-center gap-2 text-muted-foreground text-sm">
						<div className="flex items-center gap-2">
							<CalendarClock className="size-5" />
							<span>{t.servizio.durata_servizio}</span>
						</div>
						<span>
							{dec_txt} - {end_txt}
						</span>
					</div>
				</div>
				<div className="flex flex-col gap-4">
					<AdminActions />
					<ServizioBasicActions className="w-full sm:justify-end" />
				</div>
			</div>
			<ServizioPacksInfos />
			<Main />
		</div>
	);
};

const Main = () => {
	const { servizio, isAdmin, userId, servizioId } = useServizio();
	const { t } = useTranslation();
	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 });

			await utils.servizio.getServizioData.invalidate({ servizioId });
			await utils.servizio.getPacksSolution.invalidate({ servizioId });
		},
	});

	const { mutate: removeAnnuncioServizio } =
		api.servizio.removeAnnuncioServizio.useMutation({
			onError: (error) => {
				console.error(error);
				toast.error("Errore durante la rimozione dell'annuncio");
			},
			onSuccess: async () => {
				await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
				await utils.servizio.getServizioData.invalidate({ servizioId });
				await utils.servizio.getCompatibileAnnunci.invalidate({
					servizioId,
				});
				toast.success("Annuncio rimosso");
			},
		});

	if (servizio.isInterrotto) {
		return (
			<>
				<p className="font-medium text-lg">{t.servizio.servizio_interrotto}</p>
				<p>{t.servizio.servizio_interrotto_desc}</p>
			</>
		);
	}

	if (!servizio.isOkAcconto || servizio.decorrenza === null) {
		return (
			<div className="flex w-full flex-col items-center justify-center gap-4">
				<div className="flex w-full max-w-md flex-col items-center justify-center gap-4 text-center">
					<AlarmClockSVG className="size-46" />
					<h1 className="text-xl">{t.servizio.non_attivo}</h1>
					<Link
						aria-label="Attiva Servizio"
						className="w-full"
						href={`/servizio/onboard/${servizio.servizio_id}`}
					>
						<Button className="w-full text-lg" variant="success">
							<span>{t.servizio.attiva_cta}</span>
							<ArrowRight />
						</Button>
					</Link>

					{isAdmin && (
						<Button
							className="w-full"
							onClick={() =>
								updateServizio({
									data: {
										decorrenza: new Date(),
										isOkAcconto: true,
									},
									servizioId: servizio.servizio_id,
								})
							}
							variant="success"
						>
							Attiva Manualmente (Azione Admin)
						</Button>
					)}
				</div>

				{servizio.annunci.length > 0 && (
					<div className="w-full space-y-2">
						<p>
							{t.servizio.per_te_1} {servizio.annunci.length}{" "}
							{t.servizio.per_te_2}
						</p>
						<div className="grid gap-4 sm:grid-cols-2">
							{servizio.annunci.map((data) => (
								<div className="group relative" key={data.id}>
									<AnnuncioDisplay
										className="bg-[#e6e9ec]/50 dark:bg-card dark:outline dark:outline-foreground/10"
										data={{
											...data,
											modificato_il: data.modificato_il
												? new Date(data.modificato_il)
												: null,
											media_updated_at: data.media_updated_at
												? new Date(data.media_updated_at)
												: null,
										}}
									/>
									{isAdmin && (
										<Confirm
											description="Sei sicuro di voler rimuovere questo annuncio?"
											onConfirm={() => {
												removeAnnuncioServizio({
													annuncioId: data.annunci_id,
													servizioId: servizio.servizio_id,
												});
											}}
											title="Rimuovi Annuncio"
										>
											<Button
												aria-label="Rimuovi"
												className="absolute top-0 right-0 hidden group-hover:flex"
												size="sm"
												variant="destructive"
											>
												<Trash2 />
											</Button>
										</Confirm>
									)}
								</div>
							))}
							{servizio.annunci.length % 2 === 1 && (
								<div className="hidden size-full rounded-md border border-(--pattern-fg) bg-[repeating-linear-gradient(45deg,var(--pattern-fg)_0,var(--pattern-fg)_1px,transparent_0,transparent_50%)] bg-size-[10px_10px] bg-fixed opacity-10 [--pattern-fg:#696969] sm:block dark:[--pattern-fg:#e1e1e1]" />
							)}
						</div>
					</div>
				)}
			</div>
		);
	}
	if (
		new Date() >
			add(servizio.decorrenza, {
				days: 60,
			}) &&
		!servizio.isOkSaldo
	) {
		return (
			<>
				<p className="font-medium text-lg">{t.servizio.scaduto}</p>
				<p>{t.servizio.scaduto_desc}</p>
			</>
		);
	}
	const annuncioConfermato = servizio.annunci.filter(
		(a) => a.accettato_conferma_at !== null,
	);

	if (servizio.isOkSaldo && annuncioConfermato.length > 0) {
		return (
			<>
				{annuncioConfermato.map((data) => {
					return (
						<ServizioAnnuncioProvider
							data={data}
							key={data.id}
							servizioId={servizio.servizio_id}
							userId={userId}
						>
							<AnnuncioCard className="max-w-full" />
						</ServizioAnnuncioProvider>
					);
				})}
			</>
		);
	}
	return (
		<>
			{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">{t.servizio.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} -{" "}
									{a.accettato_conferma_at &&
										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="grid grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2">
				{servizio.annunci.map((data) => {
					return (
						<ServizioAnnuncioProvider
							data={data}
							key={data.id}
							servizioId={servizio.servizio_id}
							userId={userId}
						>
							<AnnuncioCard />
						</ServizioAnnuncioProvider>
					);
				})}
				{servizio.annunci.length % 2 === 1 && (
					<div className="hidden size-full rounded-md border border-(--pattern-fg) bg-[repeating-linear-gradient(45deg,var(--pattern-fg)_0,var(--pattern-fg)_1px,transparent_0,transparent_50%)] bg-size-[10px_10px] bg-fixed opacity-10 [--pattern-fg:#696969] sm:block dark:[--pattern-fg:#e1e1e1]" />
				)}
			</div>
			<div className="flex items-center justify-center">
				<AnnunciCompatibili />
			</div>
		</>
	);
};
