import {
	CircleCheck,
	CircleUser,
	Navigation,
	Phone,
	TriangleAlert,
} from "lucide-react";
import Link from "next/link";
import { useMemo } from "react";
import toast from "react-hot-toast";
import { useTranslation } from "~/providers/I18nProvider";
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import type { UsersStorageUserStorageId } from "~/schemas/public/UsersStorage";
import { api } from "~/utils/api";
import {
	Credenza,
	CredenzaBody,
	CredenzaClose,
	CredenzaContent,
	CredenzaDescription,
	CredenzaFooter,
	CredenzaHeader,
	CredenzaTitle,
	CredenzaTrigger,
} from "../custom_ui/credenza";
import { LoadingPage } from "../loading";
import { WhatsAppIcon2 } from "../svgs";
import { Button } from "../ui/button";
import { type UploadCallback, UploadModal } from "../upload_modal";

export const ContattiProprietarioModal = () => {
	const { servizio } = useServizio();
	const { data } = useServizioAnnuncio();
	const { t } = useTranslation();

	const isUnlocked = data.open_contatti_at != null;
	const needsDocuments =
		!servizio.skipControlloDoc &&
		(!servizio.doc_personale_fronte || !servizio.doc_personale_retro);

	return (
		<Credenza>
			<CredenzaTrigger asChild>
				{data.open_contatti_at != null ? (
					<Button
						aria-label="Vedi contatti proprietario"
						className="w-fit"
						variant="success"
					>
						<CircleUser className="size-7" />
						Vedi i contatti
					</Button>
				) : (
					<Button
						aria-label="Contatta proprietario"
						className="w-fit"
						variant="warning"
					>
						<CircleUser className="size-7" />
						Ottieni i contatti
					</Button>
				)}
			</CredenzaTrigger>
			<CredenzaContent className="max-h-[90vh] sm:max-w-2xl">
				<CredenzaHeader>
					<CredenzaTitle className="text-xl">{t.contatto.title}</CredenzaTitle>
					<CredenzaDescription className="sr-only">
						{t.contatto.descrizione}
					</CredenzaDescription>
				</CredenzaHeader>
				{needsDocuments ? (
					<DocCheckpoint />
				) : isUnlocked ? (
					<PostUnlock />
				) : (
					<PreUnlock />
				)}
			</CredenzaContent>
		</Credenza>
	);
};

const DocComponent = ({
	docInfo,
	cb,
}: {
	docInfo: {
		storageId: string;
		ref: UsersStorageUserStorageId | null;
	} | null;
	cb: UploadCallback;
}) => {
	const { isAdmin, userId } = useServizio();

	if (docInfo?.storageId) {
		return (
			<div className="flex items-center gap-2 text-green-500">
				<CircleCheck className="size-5" />
				<span>Documento caricato</span>
			</div>
		);
	}

	return (
		<UploadModal
			cb_onUpload={cb}
			isAdmin={isAdmin}
			maxFiles={1}
			userId={userId}
		/>
	);
};

const DocCheckpoint = () => {
	const { t } = useTranslation();
	const { userId, servizio } = useServizio();
	const utils = api.useUtils();
	const { mutate, isPending } = api.servizio.updateServizio.useMutation({
		onSuccess: async () => {
			await utils.servizio.getAllServizioAnnunci.invalidate({
				userId,
			});
			await utils.storage.retrieveUserFileData.invalidate({ userId });
			await utils.servizio.getServizio.invalidate({
				servizioId: servizio.servizio_id,
			});
		},
		onError: (err) => {
			toast.error(`Errore aggiornamento servizio: ${err.message}`);
		},
	});
	const handleUpload = (
		field: "doc_personale_fronte_ref" | "doc_personale_retro_ref",
		id: UsersStorageUserStorageId,
	) => {
		mutate({
			servizioId: servizio.servizio_id,
			data: { [field]: id },
		});
	};
	return (
		<>
			<CredenzaBody className="max-h-[80vh] overflow-auto pb-5">
				<div className="space-y-5">
					<p>Devi ancora caricare un tuo documento</p>
					<div className="flex flex-col gap-2">
						<span>Fronte documento:</span>
						<DocComponent
							cb={({ userStorageIds }) =>
								userStorageIds.length > 0 &&
								userStorageIds[0] &&
								handleUpload("doc_personale_fronte_ref", userStorageIds[0])
							}
							docInfo={servizio.doc_personale_fronte}
						/>
					</div>
					<div className="flex flex-col gap-2">
						<span>Retro documento:</span>
						<DocComponent
							cb={({ userStorageIds }) =>
								userStorageIds.length > 0 &&
								userStorageIds[0] &&
								handleUpload("doc_personale_retro_ref", userStorageIds[0])
							}
							docInfo={servizio.doc_personale_retro}
						/>
					</div>

					<br />
					<br />
					<p className="text-muted-foreground text-sm">
						I tuoi dati saranno conservati solamente per la durata del servizio,
						in conformità con la nostra{" "}
						<Link className="underline" href="/privacy-policy" target="_blank">
							Informativa sulla Privacy
						</Link>
					</p>
				</div>
			</CredenzaBody>
			<CredenzaFooter>
				<CredenzaClose asChild>
					<Button aria-label="Chiudi" disabled={isPending} variant="outline">
						{t.chiudi}
					</Button>
				</CredenzaClose>
			</CredenzaFooter>
		</>
	);
};

const PreUnlock = () => {
	const { userId, servizioId } = useServizio();
	const { annuncioId } = useServizioAnnuncio();
	const { t } = useTranslation();

	const utils = api.useUtils();

	const { mutate, isPending } = api.servizio.unlockServizioContatti.useMutation(
		{
			onError: (err) => {
				toast.error(err.message, {
					id: "unlock-contacts",
				});
			},
			onMutate: () => {
				toast.loading("Caricamento ...", {
					id: "unlock-contacts",
				});
			},
			onSuccess: async (data) => {
				if (!data) {
					toast.error("Limite di sblocchi raggiunto", {
						id: "unlock-contacts",
					});
					return;
				}
				toast.success("Successo", {
					id: "unlock-contacts",
				});
				await utils.servizio.getAllServizioAnnunci.invalidate({
					userId,
				});
			},
		},
	);

	const currentHour = new Date().getHours();
	const isOutsideBusinessHours = currentHour < 9 || currentHour >= 20;
	return (
		<>
			<CredenzaBody className="max-h-[80vh] overflow-auto pb-5">
				<div className="space-y-5">
					<p>{t.contatto.disclaimer}</p>
					<p>{t.contatto.disclaimer2}</p>
					<p className="text-muted-foreground text-xs">
						{t.contatto.disclaimer3}
					</p>
					{isOutsideBusinessHours && (
						<div className="flex items-center gap-2 rounded-md bg-yellow-200 p-2">
							<TriangleAlert className="size-8" />
							<p>
								Il proprietario riceverà la notifica alle ore 9.00{" "}
								{currentHour >= 20 && "di domani"}
							</p>
						</div>
					)}
				</div>
			</CredenzaBody>
			<CredenzaFooter>
				<Button
					aria-label="Contatta proprietario"
					disabled={isPending}
					onClick={() =>
						mutate({
							annuncioId,
							servizioId,
						})
					}
					variant="success"
				>
					{t.accetta}
				</Button>

				<CredenzaClose asChild>
					<Button
						aria-label="Chiudi modal credenza"
						disabled={isPending}
						variant="outline"
					>
						{t.chiudi}
					</Button>
				</CredenzaClose>
			</CredenzaFooter>
		</>
	);
};

function getNavigationUrl(lat: string, lon: string): string {
	if (typeof window === "undefined") {
		return `https://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=${lat},${lon}`;
	}
	const isIOS = /iPad|iPhone|iPod|Mac/.test(navigator.userAgent);
	const protocol = isIOS ? "maps" : "https";

	return `${protocol}://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=${lat},${lon}`;
}

const PostUnlock = () => {
	const { servizioId } = useServizio();
	const { annuncioId } = useServizioAnnuncio();
	const { data, isLoading } = api.annunci.getProprietarioData.useQuery({
		annuncioId,
		servizioId,
	});

	const { t } = useTranslation();

	// Memoize navigation URL
	const navigationUrl = useMemo(() => {
		if (!data?.propData || !data.propData.lat || !data.propData.lon)
			return undefined;
		return getNavigationUrl(data.propData.lat, data.propData.lon);
	}, [data?.propData]);

	if (isLoading) {
		return (
			<CredenzaBody className="flex justify-center p-8">
				<LoadingPage />
			</CredenzaBody>
		);
	}
	if (!data || !data.propData) {
		return (
			<CredenzaBody>
				<p className="text-destructive">{t.contatto.error}</p>
			</CredenzaBody>
		);
	}
	const { opened_at, propData } = data;
	return (
		<>
			<CredenzaBody className="max-h-[80vh] overflow-auto pb-5 sm:max-w-xl">
				<div className="space-y-10">
					{/* Proprietario Section */}
					<section>
						<h3 className="mb-2 font-semibold">{t.contatto.propietario}:</h3>
						<p className="mb-2">
							{t.contatto.nome}: {propData.locatore}
						</p>
						<div className="flex flex-wrap items-center gap-5">
							<a
								className="flex items-center gap-2 text-blue-600 hover:underline"
								href={`tel:${propData.numero}`}
							>
								<Phone className="size-4" />
								<span>{propData.numero}</span>
							</a>
							<Link href={`https://wa.me/${propData.numero}`} target="_blank">
								<Button size="sm" variant="success">
									<WhatsAppIcon2 className="size-4 fill-white" />
									WhatsApp
								</Button>
							</Link>
						</div>
					</section>

					{/* Immobile Section */}
					<section>
						<h3 className="mb-2 font-semibold">{t.contatto.immobile}:</h3>
						<p className="mb-2">
							{t.contatto.indirizzo}: {propData.indirizzo}, {propData.civico}{" "}
							{propData.comune} ({propData.provincia})
						</p>
						{navigationUrl && (
							<a
								className="inline-flex items-center gap-2 rounded-md border border-border px-3 py-2 hover:bg-accent"
								href={navigationUrl}
								rel="noreferrer"
								target="_blank"
							>
								<Navigation className="size-4" />
								<span>{t.contatto.apri_nav}</span>
							</a>
						)}
					</section>

					{/* Warning */}
					<div className="flex w-fit items-start gap-3 rounded-md bg-red-500 p-2 text-white">
						<TriangleAlert className="size-6 shrink-0" />
						<div className="space-y-1">
							<p className="font-medium">{t.contatto.contatta}</p>
							<p className="text-sm">{t.contatto.orari}</p>
						</div>
					</div>

					{/* Metadata */}
					<p className="text-muted-foreground text-sm">
						{t.contatto.sbloccato_il}:{" "}
						{opened_at.toLocaleString("it", {
							day: "2-digit",
							month: "2-digit",
							year: "numeric",
							hour: "2-digit",
							minute: "2-digit",
						})}
					</p>
				</div>
			</CredenzaBody>
			<CredenzaFooter>
				<CredenzaClose asChild>
					<Button aria-label="Chiudi modal credenza" variant="outline">
						{t.chiudi}
					</Button>
				</CredenzaClose>
			</CredenzaFooter>
		</>
	);
};
