import { CircleCheck, ExternalLink, Trash2 } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import { useState } from "react";
import toast from "react-hot-toast";
import { getStorageUrl } from "~/lib/storage_utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useSession } from "~/providers/SessionProvider";
import type { UsersId } from "~/schemas/public/Users";
import type { UsersStorageUserStorageId } from "~/schemas/public/UsersStorage";
import type { CompleteUserData } from "~/server/services/user.service";
import { api } from "~/utils/api";
import { Confirm } from "../confirm";
import { LoadingPage } from "../loading";
import { LoadingSpinner } from "../spinner";
import { Button } from "../ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
} from "../ui/card";
import { UploadModal } from "../upload_modal";

export const DocumentiPersonali = ({
	userData,
}: {
	userData: CompleteUserData;
}) => {
	const utils = api.useUtils();
	const { locale } = useTranslation();
	const { mutate, isPending } = api.users.editUserAnagrafica.useMutation({
		onSuccess: async () => {
			await utils.users.getClientProfilo.invalidate({
				userId: userData.id,
			});
		},
		onError: (err) => {
			toast.error(`Errore aggiornamento servizio: ${err.message}`);
		},
	});
	const handleUpload = (
		field: "doc_personale_fronte_ref" | "doc_personale_retro_ref",
		id: UsersStorageUserStorageId,
	) => {
		mutate({
			userId: userData.id,
			data: { [field]: id },
		});
	};

	const { user } = useSession();
	if (!user) return null;
	if (isPending) return <LoadingPage />;

	return (
		<Card>
			<CardHeader>
				<CardTitle>
					{locale === "it" ? "Documenti personali" : "Personal Documents"}
				</CardTitle>
				<CardDescription>
					<p>
						{locale === "it"
							? "I tuoi documenti sono necessari per usufruire del servizio."
							: "Your documents are required to use the service."}
					</p>
					<p>
						{locale === "it"
							? "Nel caso di un unico documento (es: scansione fronte e retro del documento) caricarlo 2 volte."
							: "In case of a single document (e.g., front and back scan of the document), upload it twice."}
					</p>
				</CardDescription>
			</CardHeader>
			<CardContent>
				<div className="flex flex-col gap-4">
					<DocumentiUploadSection
						document={userData.doc_personale_fronte}
						isAdmin={user.isAdmin}
						isPending={isPending}
						onRemove={() =>
							mutate({
								userId: userData.id,
								data: { doc_personale_fronte_ref: null },
							})
						}
						onUpload={(id) => handleUpload("doc_personale_fronte_ref", id)}
						title="Documento d'identità - Fronte"
						userId={userData.id}
					/>

					<DocumentiUploadSection
						document={userData.doc_personale_retro}
						isAdmin={user.isAdmin}
						isPending={isPending}
						onRemove={() =>
							mutate({
								userId: userData.id,
								data: { doc_personale_retro_ref: null },
							})
						}
						onUpload={(id) => handleUpload("doc_personale_retro_ref", id)}
						title="Documento d'identità - Retro"
						userId={userData.id}
					/>
				</div>
			</CardContent>
			<CardFooter>
				<p className="text-muted-foreground text-sm">
					{locale === "it"
						? "I tuoi dati saranno conservati solamente per la durata del servizio, in conformità con la nostra "
						: "Your data will be stored only for the duration of the service, in accordance with our "}
					<Link className="underline" href="/privacy-policy" target="_blank">
						{locale === "it" ? "Informativa sulla Privacy" : "Privacy Policy"}
					</Link>
				</p>
			</CardFooter>
		</Card>
	);
};

export const DocumentiUploadSection = ({
	title,
	document,
	onUpload,
	onRemove,
	isAdmin,
	userId,
	isPending,
	caricatoNote,
}: {
	title: string;
	document: {
		storageId: string;
		ref: UsersStorageUserStorageId | null;
	} | null;
	onUpload: (id: UsersStorageUserStorageId) => void;
	onRemove?: () => void;
	isAdmin: boolean;
	userId: UsersId;
	isPending: boolean;
	caricatoNote?: boolean;
}) => {
	const { locale } = useTranslation();
	const [imageError, setImageError] = useState(false);
	if (document?.storageId) {
		return (
			<div className="flex flex-col gap-2">
				<h4 className="font-medium">{title}</h4>
				{caricatoNote && (
					<div className="flex items-center gap-2 text-green-500">
						<CircleCheck className="size-5" />
						<span>
							{locale === "it" ? "Documento caricato" : "Document uploaded"}
						</span>
					</div>
				)}
				<div className="flex items-center gap-4">
					{isPending ? (
						<LoadingSpinner className="size-24 stroke-neutral-300" />
					) : !imageError ? (
						<Image
							alt={title}
							className="size-24 rounded-md border object-cover"
							height={96}
							onError={() => setImageError(true)}
							src={getStorageUrl({
								storageId: document.storageId,
							})}
							width={96}
						/>
					) : (
						<div className="flex size-24 items-center justify-center overflow-clip rounded-md border bg-muted">
							<iframe
								className="size-full"
								src={getStorageUrl({ storageId: document.storageId })}
								title="doc"
							>
								<p>
									{locale === "it"
										? "Il tuo browser non supporta gli iframe."
										: "Your browser does not support iframes."}
								</p>
							</iframe>
						</div>
					)}
					<div className="flex flex-col justify-center gap-2">
						<Link
							href={`/area-riservata/allegato-view/${document.storageId}`}
							target="_blank"
						>
							<Button size="sm" variant="outline">
								<span>{locale === "it" ? "Visualizza" : "View"}</span>
								<ExternalLink className="size-4" />
							</Button>
						</Link>
						{onRemove && (
							<Confirm
								description={
									locale === "it"
										? "Sei sicuro di voler eliminare il documento?"
										: "Are you sure you want to delete the document?"
								}
								onConfirm={onRemove}
								title={
									locale === "it" ? "Elimina Documento" : "Delete Document"
								}
							>
								<Button
									aria-label={
										locale === "it" ? "Elimina documento" : "Delete document"
									}
									disabled={isPending}
									size="sm"
									variant="destructive"
								>
									<span>{locale === "it" ? "Rimuovi" : "Remove"}</span>
									<Trash2 className="size-4" />
								</Button>
							</Confirm>
						)}
					</div>
				</div>
			</div>
		);
	}

	return (
		<div className="flex flex-col gap-2">
			<h4 className="font-medium">{title}</h4>
			<UploadModal
				cb_onUpload={({ userStorageIds }) => {
					const id = userStorageIds[0];
					if (id) onUpload(id);
				}}
				isAdmin={isAdmin}
				maxFiles={1}
				userId={userId}
			/>
		</div>
	);
};
