import {
	Check,
	ChevronsUpDown,
	CircleCheck,
	ClipboardPaste,
	ExternalLink,
	FolderKanban,
	Pen,
	Plus,
	ShieldUser,
	Trash2,
	Wrench,
} from "lucide-react";
import Link from "next/link";
import { useRef, useState } from "react";
import toast from "react-hot-toast";
import { z } from "zod/v4";
import { ExtIcon } from "~/components/area-riservata/allegati";
import { Confirm } from "~/components/confirm";
import {
	AnimatedButton,
	type AnimatedButtonRef,
} from "~/components/custom_ui/animated-button";
import {
	Credenza,
	CredenzaBody,
	CredenzaClose,
	CredenzaContent,
	CredenzaDescription,
	CredenzaFooter,
	CredenzaHeader,
	CredenzaTitle,
	CredenzaTrigger,
} from "~/components/custom_ui/credenza";
import { LoadingPage } from "~/components/loading";
import { Button, buttonVariants } from "~/components/ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
} from "~/components/ui/card";
import {
	Command,
	CommandEmpty,
	CommandGroup,
	CommandInput,
	CommandItem,
	CommandList,
} from "~/components/ui/command";
import { Label } from "~/components/ui/label";
import {
	Popover,
	PopoverContent,
	PopoverTrigger,
} from "~/components/ui/popover";
import { Separator } from "~/components/ui/separator";
import { Switch } from "~/components/ui/switch";
import { UploadModal } from "~/components/upload_modal";
import { cn, formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import type { AnnunciId } from "~/schemas/public/Annunci";
import type { ServizioAnnunciUpdate } from "~/schemas/public/ServizioAnnunci";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import type { FileMetadataWithAdmin } from "~/server/services/storage.service";
import { api } from "~/utils/api";

export const AnnuncioActions = () => {
	const { servizioId, userId, isAdmin } = useServizio();
	const { data, annuncioId } = useServizioAnnuncio();

	const utils = api.useUtils();
	const { mutate } = 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.getCompatibileAnnunci.invalidate({
				servizioId,
			});
			toast.success("Annuncio rimosso");
		},
	});

	if ((!isAdmin && data.open_contatti_at == null) || isAdmin) {
		return (
			<div className="flex w-full max-w-fit flex-wrap justify-start gap-3 sm:justify-end">
				{isAdmin && data.user_confirmed_at != null && <AdminLavoraConferma />}
				{isAdmin && data.accettato_conferma_at != null && (
					<>
						<AdminContratto />
						{data.gestionale_id && (
							<Link
								aria-label="Open Gestionale"
								href={`https://win-jk822fggr6b:480/id/${data.gestionale_id}`}
								target="_blank"
							>
								<Button>
									<FolderKanban className="size-5" /> Gestionale
								</Button>
							</Link>
						)}
					</>
				)}
				{isAdmin && (
					<Popover>
						<PopoverTrigger asChild>
							<Button>
								<ShieldUser />
								<span>Admin</span>
							</Button>
						</PopoverTrigger>
						<PopoverContent
							align="end"
							className="flex w-fit flex-col items-center gap-2"
						>
							<Link
								href={`/area-riservata/admin/edit-annuncio/${annuncioId}`}
								target="_blank"
							>
								<Button
									aria-label="Edit Annuncio"
									className="w-full"
									size="sm"
									variant="secondary"
								>
									<Wrench />
									<span>Modifica Annuncio</span>
								</Button>
							</Link>

							<Confirm
								description="Sei sicuro di voler eliminare l'annuncio?"
								onConfirm={() => {
									mutate({
										annuncioId,
										servizioId,
									});
								}}
								title="Elimina annuncio"
							>
								<Button
									aria-label="Delete Annuncio"
									className="w-full"
									size="sm"
									variant="destructive"
								>
									<Trash2 />
									<span>Elimina Annuncio</span>
								</Button>
							</Confirm>
						</PopoverContent>
					</Popover>
				)}
			</div>
		);
	}
	return null;
};

const ContrattoImportSchema = z.object({
	contratto_decorrenza: z.string().nullable(),
	contratto_scadenza: z.string().nullable(),
	contratto_tipo: z
		.enum([
			"Transitorio",
			"Agevolato",
			"4 + 4",
			"30 Giorni",
			"Transi.Age",
			"Foresteria",
			"Commerciale",
		])
		.nullable(),
	gestionale_id: z.number().nullable(),
});

interface ContrattoImportObj
	extends Omit<
		z.infer<typeof ContrattoImportSchema>,
		"contratto_decorrenza" | "contratto_scadenza"
	> {
	contratto_decorrenza: Date | null;
	contratto_scadenza: Date | null;
}

const parseContrattoImport = (ingest: string) => {
	let parsedJson: unknown;
	try {
		parsedJson = JSON.parse(ingest);
	} catch {
		toast.error(
			'Stringa non valida, clicca "copia stringa" nel gestionale e poi questo pulsante',
		);
		return undefined;
	}
	const parsed = ContrattoImportSchema.safeParse(parsedJson);
	if (parsed.success) {
		return {
			...parsed.data,
			contratto_decorrenza: parsed.data.contratto_decorrenza
				? new Date(parsed.data.contratto_decorrenza)
				: null,
			contratto_scadenza: parsed.data.contratto_scadenza
				? new Date(parsed.data.contratto_scadenza)
				: null,
		};
	}
	console.error("Invalid format:", parsed.error);
	return undefined;
};

const ContrattoImport = ({
	handleUpdate,
}: {
	handleUpdate: (upd: ServizioAnnunciUpdate) => void;
}) => {
	const { data } = useServizioAnnuncio();
	const [contratto, setContratto] = useState<ContrattoImportObj | undefined>({
		contratto_decorrenza: data.contratto_decorrenza
			? new Date(data.contratto_decorrenza)
			: null,
		contratto_scadenza: data.contratto_scadenza
			? new Date(data.contratto_scadenza)
			: null,
		contratto_tipo: data.contratto_tipo as ContrattoImportObj["contratto_tipo"],
		gestionale_id: data.gestionale_id,
	});
	const handleSave = () => {
		handleUpdate({
			...contratto,
		});
	};
	return (
		<Card>
			<CardHeader>
				<CardTitle>Dati Contratto</CardTitle>
				<CardDescription className="sr-only">desc</CardDescription>
			</CardHeader>
			<CardContent className="space-y-4">
				<div className="flex items-center gap-3">
					<Button
						aria-label="Import Contratto"
						onClick={async () => {
							const clipboardText = await navigator.clipboard.readText();

							setContratto(parseContrattoImport(clipboardText));
						}}
						variant="info"
					>
						<ClipboardPaste className="size-4" />
						Clicca qui per importare la stringa dal gestionale
					</Button>
					<Button
						aria-label="Reset Contratto"
						onClick={async () => {
							setContratto({
								contratto_decorrenza: null,
								contratto_scadenza: null,
								contratto_tipo: null,
								gestionale_id: null,
							});
						}}
						variant="destructive"
					>
						<Trash2 className="size-4" />
						Reset
					</Button>
				</div>
				{contratto ? (
					<div className="flex flex-col gap-2">
						<p>
							<span className="font-semibold">ID Gestionale: </span>
							{contratto.gestionale_id}{" "}
							<Button
								aria-label="Edit Gestionale ID"
								className="h-6 px-1.5 [&_svg]:size-4"
								onClick={() => {
									const newValue = prompt(
										"Modifica l'ID gestionale del contratto:",
										contratto.gestionale_id?.toString() || "",
									);
									if (newValue !== null) {
										setContratto((prev) =>
											prev
												? { ...prev, gestionale_id: parseInt(newValue) }
												: undefined,
										);
									}
								}}
								size="sm"
							>
								<Pen />
							</Button>
						</p>
						<p>
							<span className="font-semibold">Decorrenza: </span>
							{contratto.contratto_decorrenza &&
								new Date(contratto.contratto_decorrenza).toLocaleDateString(
									"it-IT",
								)}{" "}
							<Button
								aria-label="Edit Decorrenza"
								className="h-6 px-1.5 [&_svg]:size-4"
								onClick={() => {
									const newValue = prompt(
										"Modifica la decorrenza del contratto (DD/MM/YYYY):",
										contratto.contratto_decorrenza
											? new Date(
													contratto.contratto_decorrenza,
												).toLocaleDateString("it-IT")
											: "",
									);
									if (newValue !== null) {
										setContratto((prev) =>
											prev
												? {
														...prev,
														contratto_decorrenza: new Date(newValue),
													}
												: undefined,
										);
									}
								}}
								size="sm"
							>
								<Pen />
							</Button>
						</p>
						<p>
							<span className="font-semibold">Scadenza: </span>
							{contratto.contratto_scadenza &&
								new Date(contratto.contratto_scadenza).toLocaleDateString(
									"it-IT",
								)}{" "}
							<Button
								aria-label="Edit Scadenza"
								className="h-6 px-1.5 [&_svg]:size-4"
								onClick={() => {
									const newValue = prompt(
										"Modifica la scadenza del contratto (DD/MM/YYYY):",
										contratto.contratto_scadenza
											? new Date(
													contratto.contratto_scadenza,
												).toLocaleDateString("it-IT")
											: "",
									);
									if (newValue !== null) {
										setContratto((prev) =>
											prev
												? {
														...prev,
														contratto_scadenza: new Date(newValue),
													}
												: undefined,
										);
									}
								}}
								size="sm"
							>
								<Pen />
							</Button>
						</p>
						<p>
							<span className="font-semibold">Tipo di contratto: </span>
							{contratto.contratto_tipo}{" "}
							<Button
								aria-label="Edit Tipo di contratto"
								className="h-6 px-1.5 [&_svg]:size-4"
								onClick={() => {
									const newValue = prompt(
										"Modifica il tipo di contratto:",
										contratto.contratto_tipo || "",
									);
									if (
										newValue !== null &&
										ContrattoImportSchema.shape.contratto_tipo.safeParse(
											newValue,
										).success
									) {
										setContratto((prev) =>
											prev
												? {
														...prev,
														contratto_tipo:
															newValue as ContrattoImportObj["contratto_tipo"],
													}
												: undefined,
										);
									}
								}}
								size="sm"
							>
								<Pen />
							</Button>
						</p>
					</div>
				) : (
					<p>Inserisci la stringa dal gestionale e elabora</p>
				)}
			</CardContent>
			<CardFooter>
				<Button
					aria-label="Save Contratto"
					onClick={() => {
						handleSave();
					}}
					variant="success"
				>
					Salva
				</Button>
			</CardFooter>
		</Card>
	);
};

const AdminContratto = () => {
	const { userId, servizioId } = useServizio();
	const { data, annuncioId } = useServizioAnnuncio();

	const [open, setOpen] = useState(false);

	const utils = api.useUtils();

	const { mutate: updateServizio } =
		api.servizio.updateServizioAnnunci.useMutation({
			onError: (error) => {
				toast.error(error.message);
			},
			onSuccess: async () => {
				await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
				await utils.servizio.getServizio.invalidate({
					servizioId,
				});

				toast.success("Dati salvati con successo");
			},
		});

	const handleUpdate = (upd: ServizioAnnunciUpdate) => {
		updateServizio({
			annuncioId,
			data: {
				...upd,
			},
			servizioId,
		});
	};

	return (
		<Credenza onOpenChange={setOpen} open={open}>
			<CredenzaTrigger asChild>
				<Button
					aria-label="Open Contratto Section"
					className="w-fit"
					variant={data.doc_contratto_added ? "success" : "secondary"}
				>
					{data.doc_contratto_added ? (
						<CircleCheck className="size-6" />
					) : (
						<Wrench className="size-6" />
					)}
					Contratto
				</Button>
			</CredenzaTrigger>
			<CredenzaContent className="max-h-[90vh] max-w-4xl px-3 sm:max-w-5xl">
				<CredenzaHeader>
					<CredenzaTitle>Sezione Contratto</CredenzaTitle>
					<CredenzaDescription className="sr-only">
						Contratto modal
					</CredenzaDescription>
				</CredenzaHeader>
				<CredenzaBody className="max-h-[80vh] overflow-auto pb-5">
					<div className="flex flex-col gap-8">
						<ContrattoSection handleUpdate={handleUpdate} />
						<Separator />
						<ContrattoImport handleUpdate={handleUpdate} />
						<Separator />
						<RicevutaSection handleUpdate={handleUpdate} />
					</div>
				</CredenzaBody>

				<CredenzaFooter>
					<CredenzaClose asChild>
						<Button aria-label="Close Credenza" variant="outline">
							Chiudi
						</Button>
					</CredenzaClose>
				</CredenzaFooter>
			</CredenzaContent>
		</Credenza>
	);
};

const ContrattoSection = ({
	handleUpdate,
}: {
	handleUpdate: (upd: ServizioAnnunciUpdate) => void;
}) => {
	const { userId } = useServizio();
	const { data } = useServizioAnnuncio();
	const [selectedDoc, setSelectedDoc] = useState<string | null>(
		data.doc_contratto_ref,
	);

	const utils = api.useUtils();

	const { data: files, isLoading } = api.storage.getAll.useQuery();

	const { mutate: setUserStorage } =
		api.storage.addUserStorageEntry.useMutation({
			onSuccess: async () => {
				await utils.storage.retrieveUserFileData.invalidate({
					userId,
				});
				await utils.storage.getAll.invalidate();
			},
		});

	const handleSave = () => {
		handleUpdate({
			doc_contratto_added: selectedDoc != null,
			doc_contratto_ref: selectedDoc,
		});
		if (selectedDoc) {
			setUserStorage({
				storageId: selectedDoc,
				userId,
			});
		}
	};

	if (isLoading) return <LoadingPage />;
	if (files === undefined) {
		return <p>Errore nel caricamento dei documenti</p>;
	}
	return (
		<Card>
			<CardHeader>
				<CardTitle>Documento del Contratto</CardTitle>
				<CardDescription>contratto di locazione</CardDescription>
			</CardHeader>
			<CardContent className="space-y-4">
				{selectedDoc && (
					<div className="flex flex-wrap items-center gap-3">
						<DocInfo storageId={selectedDoc}>
							<Button
								aria-label="Reset Contratto"
								className="flex items-center gap-3"
								onClick={() => {
									handleUpdate({
										doc_contratto_added: false,
										doc_contratto_ref: null,
									});
									setSelectedDoc(null);
								}}
								variant="destructive"
							>
								<Trash2 className="size-6" />
							</Button>
						</DocInfo>
					</div>
				)}
				<DocCombo
					current={selectedDoc}
					files={files}
					onSelect={(f) => {
						setSelectedDoc(f.id);
					}}
				/>
				<UploadModal isAdmin userId={userId} />
			</CardContent>
			<CardFooter>
				<Button
					aria-label="Save Contratto"
					onClick={() => {
						handleSave();
					}}
					variant="success"
				>
					Salva
				</Button>
			</CardFooter>
		</Card>
	);
};

const RicevutaSection = ({
	handleUpdate,
}: {
	handleUpdate: (upd: ServizioAnnunciUpdate) => void;
}) => {
	const { userId } = useServizio();
	const { data } = useServizioAnnuncio();
	const [selectedDoc, setSelectedDoc] = useState<string | null>(
		data.doc_registrazione_ref,
	);

	const utils = api.useUtils();

	const { data: files, isLoading } = api.storage.getAll.useQuery();

	const { mutate: setUserStorage } =
		api.storage.addUserStorageEntry.useMutation({
			onSuccess: async () => {
				await utils.storage.retrieveUserFileData.invalidate({
					userId,
				});
				await utils.storage.getAll.invalidate();
			},
		});

	const handleSave = () => {
		handleUpdate({
			doc_registrazione_added: selectedDoc != null,
			doc_registrazione_ref: selectedDoc,
		});
		if (selectedDoc) {
			setUserStorage({
				storageId: selectedDoc,
				userId,
			});
		}
	};

	if (isLoading) return <LoadingPage />;
	if (files === undefined) {
		return <p>Errore nel caricamento dei documenti</p>;
	}
	return (
		<Card>
			<CardHeader>
				<CardTitle>Ricevuta di Registrazione</CardTitle>
				<CardDescription className="sr-only">desc</CardDescription>
			</CardHeader>
			<CardContent className="space-y-4">
				{selectedDoc && (
					<div className="flex flex-wrap items-center gap-3">
						<DocInfo storageId={selectedDoc}>
							<Button
								aria-label="Reset Ricevuta"
								className="flex items-center gap-3"
								onClick={() => {
									handleUpdate({
										doc_registrazione_added: false,
										doc_registrazione_ref: null,
									});
									setSelectedDoc(null);
								}}
								variant="destructive"
							>
								<Trash2 className="size-6" />
							</Button>
						</DocInfo>
					</div>
				)}
				<DocCombo
					current={selectedDoc}
					files={files}
					onSelect={(f) => {
						setSelectedDoc(f.id);
					}}
				/>
				<UploadModal isAdmin userId={userId} />
			</CardContent>
			<CardFooter>
				<Button
					aria-label="Save Ricevuta"
					onClick={() => {
						handleSave();
					}}
					variant="success"
				>
					Salva
				</Button>
			</CardFooter>
		</Card>
	);
};

const AdminLavoraConferma = () => {
	const { userId, servizioId } = useServizio();
	const { data, annuncioId } = useServizioAnnuncio();

	const [open, setOpen] = useState(false);

	const utils = api.useUtils();

	const { mutate: updateServizio } =
		api.servizio.updateServizioAnnunci.useMutation({
			onError: (error) => {
				toast.error(error.message);
			},
			onSuccess: async () => {
				await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
				await utils.servizio.getServizio.invalidate({
					servizioId,
				});

				toast.success("Dati salvati con successo");
			},
		});

	const handleUpdate = (upd: ServizioAnnunciUpdate) => {
		updateServizio({
			annuncioId,
			data: {
				...upd,
			},
			servizioId,
		});
	};

	return (
		<Credenza onOpenChange={setOpen} open={open}>
			<CredenzaTrigger asChild>
				<Button
					aria-label="Open Lavora Conferma Section"
					className="w-fit"
					variant={data.hasConfermaAdmin ? "success" : "secondary"}
				>
					{data.hasConfermaAdmin ? (
						<CircleCheck className="size-6" />
					) : (
						<Wrench className="size-6" />
					)}
					Conferma
				</Button>
			</CredenzaTrigger>
			<CredenzaContent className="max-h-[90vh] w-full px-3 sm:max-w-4xl">
				<CredenzaHeader>
					<CredenzaTitle>Lavorazione conferma</CredenzaTitle>
					<CredenzaDescription className="sr-only">
						Consegna status modal
					</CredenzaDescription>
				</CredenzaHeader>
				<CredenzaBody className="max-h-[80vh] w-full overflow-y-auto pb-5">
					<div className="flex flex-col gap-8">
						<DocSection handleUpdate={handleUpdate} />
						<Caparra handleUpdate={handleUpdate} />
						<SendConferma handleUpdate={handleUpdate} />
					</div>
				</CredenzaBody>

				<CredenzaFooter>
					<CredenzaClose asChild>
						<Button aria-label="Close Credenza" variant="outline">
							Chiudi
						</Button>
					</CredenzaClose>
				</CredenzaFooter>
			</CredenzaContent>
		</Credenza>
	);
};

const DocSection = ({
	handleUpdate,
}: {
	handleUpdate: (upd: ServizioAnnunciUpdate) => void;
}) => {
	const { userId } = useServizio();
	const { data } = useServizioAnnuncio();

	const utils = api.useUtils();

	const { data: files, isLoading } = api.storage.getAll.useQuery();

	const { mutate: setUserStorage } =
		api.storage.addUserStorageEntry.useMutation({
			onSuccess: async () => {
				await utils.storage.retrieveUserFileData.invalidate({
					userId,
				});
				await utils.storage.getAll.invalidate();
			},
		});

	if (isLoading) return <LoadingPage />;
	if (files === undefined) {
		return <p>Errore nel caricamento dei documenti</p>;
	}
	return (
		<Card>
			<CardHeader>
				<CardTitle>Documento di Conferma</CardTitle>
				<CardDescription>
					documento che l&apos;utente vedra alla conferma
				</CardDescription>
			</CardHeader>
			<CardContent className="space-y-4">
				{data.doc_conferma_ref && (
					<div className="flex flex-wrap items-start gap-3">
						<DocInfo storageId={data.doc_conferma_ref}>
							<Button
								aria-label="Reset Conferma"
								className="flex items-center gap-3"
								onClick={() => {
									handleUpdate({
										doc_conferma_added: false,
										doc_conferma_ref: null,
									});
								}}
								variant="destructive"
							>
								<Trash2 />
							</Button>
						</DocInfo>
					</div>
				)}
				<div className="flex flex-wrap items-center gap-3">
					<DocCombo
						current={data.doc_conferma_ref}
						files={files}
						onSelect={(f) => {
							handleUpdate({
								doc_conferma_added: true,
								doc_conferma_ref: f.id,
							});

							setUserStorage({
								storageId: f.id,
								userId,
							});
						}}
					/>
					<UploadModal isAdmin userId={userId} />
				</div>
			</CardContent>
		</Card>
	);
};

const DocInfo = ({
	storageId,
	children,
}: {
	storageId: string;
	children: React.ReactNode;
}) => {
	const { data: file_info } = api.storage.getFileInfos.useQuery({
		storageId,
	});
	if (!file_info) return null;
	return (
		<div className="flex w-full flex-col gap-2">
			<Label htmlFor="selected-file">File Selezionato: </Label>
			<div className="flex w-full items-center gap-2 sm:max-w-[30rem]">
				<div className="flex w-full flex-1">
					<Link
						aria-label="Open Selected File"
						className={cn(
							buttonVariants({
								variant: "outline",
							}),
							"flex w-fit grow items-center gap-2",
						)}
						href={`/area-riservata/allegato-view/${storageId}`}
						id="selected-file"
						target="_blank"
					>
						<ExtIcon mimeType={file_info.mimeType} />
						<span className="max-w-40 truncate sm:max-w-80">
							{file_info.originalName}
						</span>
						<ExternalLink className="size-4" />
					</Link>
				</div>
				{children}
			</div>
		</div>
	);
};

const DocCombo = ({
	files,
	onSelect,
	current,
}: {
	files: FileMetadataWithAdmin[];
	onSelect: (file: FileMetadataWithAdmin) => void;
	current: string | null;
}) => {
	const [open, setOpen] = useState(false);

	return (
		<Popover onOpenChange={setOpen} open={open}>
			<PopoverTrigger asChild>
				<Button
					aria-expanded={open}
					aria-label="Select Existing File"
					className="w-auto justify-between"
					role="combobox"
					variant="outline"
				>
					Seleziona file esistente...
					<ChevronsUpDown className="ml-2 size-4 shrink-0 opacity-50" />
				</Button>
			</PopoverTrigger>
			<PopoverContent className="w-auto p-0">
				<Command>
					<CommandInput placeholder="Cerca Documento..." />
					<CommandList>
						<CommandEmpty>Nessun file.</CommandEmpty>
						<CommandGroup>
							{files.map((file) => (
								<CommandItem
									key={file.id}
									onSelect={(currentValue) => {
										if (currentValue !== current) {
											// biome-ignore lint/style/noNonNullAssertion: <exists>
											onSelect(files.find((f) => f.id === currentValue)!);
										}
										setOpen(false);
									}}
									value={file.id}
								>
									<span className="flex items-center gap-2">
										<ExtIcon mimeType={file.mimeType} />
										<span className="block font-medium">
											{file.originalName}
										</span>
										{current === file.id && (
											<Check className="size-4 text-accent-foreground" />
										)}
									</span>
								</CommandItem>
							))}
						</CommandGroup>
					</CommandList>
				</Command>
			</PopoverContent>
		</Popover>
	);
};

const CaparraSchema = z.object({
	caparra_causale: z.string().nullable(),
	caparra_iban: z.string().nullable(),
	caparra_importo: z.string().nullable(),
	caparra_intestazione: z.string().nullable(),
});

type CaparraObj = z.infer<typeof CaparraSchema>;

const parseCaparra = (ingest: string) => {
	let parsedJson: unknown;
	try {
		parsedJson = JSON.parse(ingest);
	} catch {
		toast.error(
			'Stringa non valida, clicca "copia stringa" nel gestionale e poi questo pulsante',
		);
		return undefined;
	}
	const parsed = CaparraSchema.safeParse(parsedJson);
	if (parsed.success) {
		return parsed.data;
	}
	console.error("Invalid caparra format:", parsed.error);
	return undefined;
};

const Caparra = ({
	handleUpdate,
}: {
	handleUpdate: (upd: ServizioAnnunciUpdate) => void;
}) => {
	const { data } = useServizioAnnuncio();
	const [caparra, setCaparra] = useState<CaparraObj | undefined>({
		caparra_causale: data.caparra_causale,
		caparra_iban: data.caparra_iban,
		caparra_importo: data.caparra_importo,
		caparra_intestazione: data.caparra_intestazione,
	});
	const handleSave = () => {
		handleUpdate({
			...caparra,
		});
	};
	return (
		<Card>
			<CardHeader>
				<CardTitle>Dati Pagamento Caparra</CardTitle>
				<CardDescription>
					dati per il pagamento della caparra, da mostrare all&apos;utente
				</CardDescription>
			</CardHeader>
			<CardContent className="space-y-4">
				<div className="flex flex-wrap items-center gap-3">
					<Button
						aria-label="Import Caparra"
						onClick={async () => {
							const clipboardText = await navigator.clipboard.readText();

							setCaparra(parseCaparra(clipboardText));
						}}
						variant="info"
					>
						<ClipboardPaste className="size-4" />
						Dal gestionale
					</Button>
					<Button
						aria-label="Reset Caparra"
						onClick={async () => {
							setCaparra({
								caparra_causale: null,
								caparra_iban: null,
								caparra_importo: null,
								caparra_intestazione: null,
							});
						}}
						variant="destructive"
					>
						<Trash2 className="size-4" />
					</Button>
				</div>
				{caparra ? (
					<div className="flex flex-col gap-2">
						<p>
							<span className="font-semibold">Intestazione: </span>
							{caparra.caparra_intestazione}{" "}
							<Button
								aria-label="Edit Intestazione"
								className="h-6 px-1.5 [&_svg]:size-4"
								onClick={() => {
									const newValue = prompt(
										"Modifica l'intestazione della caparra:",
										caparra.caparra_intestazione || "",
									);
									if (newValue !== null) {
										setCaparra((prev) =>
											prev
												? { ...prev, caparra_intestazione: newValue }
												: undefined,
										);
									}
								}}
								size="sm"
							>
								<Pen />
							</Button>
						</p>
						<p>
							<span className="font-semibold">IBAN: </span>
							{caparra.caparra_iban}{" "}
							<Button
								aria-label="Edit IBAN"
								className="h-6 px-1.5 [&_svg]:size-4"
								onClick={() => {
									const newValue = prompt(
										"Modifica l'IBAN della caparra:",
										caparra.caparra_iban || "",
									);
									if (newValue !== null) {
										setCaparra((prev) =>
											prev ? { ...prev, caparra_iban: newValue } : undefined,
										);
									}
								}}
								size="sm"
							>
								<Pen />
							</Button>
						</p>
						<p>
							<span className="font-semibold">Importo: </span>
							{caparra.caparra_importo}{" "}
							<Button
								aria-label="Edit Importo"
								className="h-6 px-1.5 [&_svg]:size-4"
								onClick={() => {
									const newValue = prompt(
										"Modifica l'importo della caparra:",
										caparra.caparra_importo || "",
									);
									if (newValue !== null) {
										setCaparra((prev) =>
											prev ? { ...prev, caparra_importo: newValue } : undefined,
										);
									}
								}}
								size="sm"
							>
								<Pen />
							</Button>
						</p>
						<p>
							<span className="font-semibold">Causale: </span>
							{caparra.caparra_causale}{" "}
							<Button
								aria-label="Edit Causale"
								className="h-6 px-1.5 [&_svg]:size-4"
								onClick={() => {
									const newValue = prompt(
										"Modifica la causale della caparra:",
										caparra.caparra_causale || "",
									);
									if (newValue !== null) {
										setCaparra((prev) =>
											prev ? { ...prev, caparra_causale: newValue } : undefined,
										);
									}
								}}
								size="sm"
							>
								<Pen />
							</Button>
						</p>
					</div>
				) : (
					<p>Inserisci la stringa dal gestionale e elabora</p>
				)}
			</CardContent>
			<CardFooter>
				<Button
					aria-label="Save Caparra"
					onClick={() => {
						handleSave();
					}}
					variant="success"
				>
					Salva
				</Button>
			</CardFooter>
		</Card>
	);
};

const SendConferma = ({
	handleUpdate,
}: {
	handleUpdate: (upd: ServizioAnnunciUpdate) => void;
}) => {
	const { servizio } = useServizio();
	const { data } = useServizioAnnuncio();
	const { t } = useTranslation();
	const [check, setCheck] = useState(data.hasConfermaAdmin);

	return (
		<Card>
			<CardHeader>
				<CardTitle>Lavorazione Conferma</CardTitle>
				<CardDescription>
					controlla i parametri di ricerca prima!
				</CardDescription>
			</CardHeader>
			<CardContent className="space-y-4">
				<div className="flex flex-col gap-2">
					<p>Tipologia servizio: {servizio.tipologia}</p>
					{(() => {
						if (servizio.tipologia === TipologiaPosizioneEnum.Transitorio) {
							return (
								<>
									<p>
										Permanenza (da preferenze):{" "}
										{servizio.permanenza
											? t.preferenze.permanenza[servizio.permanenza]
											: "non inserita"}
									</p>
									<p>
										Permanenza (da descrizione): &quot;
										{(() => {
											const match = data.desc_it?.match(/Permanenza:.*$/m);
											return match ? match[0] : "";
										})()}
										&quot;
									</p>
								</>
							);
						}
						return (
							<>
								<p>Budget (da preferenze): {formatCurrency(servizio.budget)}</p>
								<p>
									Canone Mensile (da descrizione):{" "}
									{formatCurrency(data.prezzo / 100)}
								</p>
							</>
						);
					})()}
				</div>
				<div className="flex items-center gap-3">
					<Switch
						aria-label="Conferma Lavorata"
						checked={check}
						id="conferma"
						onCheckedChange={(c) => {
							setCheck(c);
						}}
					/>
					<Label htmlFor="conferma">Conferma lavorata</Label>
				</div>
			</CardContent>
			<CardFooter>
				<Button
					aria-label="Save Conferma Status"
					onClick={() => {
						handleUpdate({
							hasConfermaAdmin: check,
						});
					}}
					variant="success"
				>
					Salva
				</Button>
			</CardFooter>
		</Card>
	);
};

export const AddButton = ({ annuncioId }: { annuncioId: AnnunciId }) => {
	const { servizioId, userId } = useServizio();
	const utils = api.useUtils();
	const { mutate } = api.servizio.addServizioAnnunci.useMutation({
		onError: (error) => {
			console.error(error);
			toast.error("Errore durante l'aggiunta dell'annuncio");
		},
		onSuccess: async () => {
			await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
			await utils.servizio.getAnnunciAvailableToAdd.invalidate({
				servizioId,
			});
			await utils.servizio.AnnuncioServizioTipologiaMatch.invalidate({
				userId,
			});
			await utils.servizio.getCompatibileAnnunci.invalidate({
				servizioId,
			});

			toast.success("Annuncio aggiunto alla ricerca");
		},
	});

	const buttonRef = useRef<AnimatedButtonRef>(null);
	return (
		<AnimatedButton
			className="group flex w-full gap-2"
			onClick={async () => {
				buttonRef.current?.sparkle();
				//wait for the animation to finish
				await new Promise((resolve) => setTimeout(resolve, 1000));
				mutate({ annunci: [annuncioId], servizioId });
			}}
			ref={buttonRef}
			sparklesClassName="fill-yellow-500 stroke-transparent"
			sparklesIcon="thumbs-up"
			sparklesNumber={15}
			sparklesRadius={60}
			sparklesScale={[1, 1.5]}
			variant="info"
		>
			<Plus className="size-5" />
			<span>Aggiungi agli annunci da contattare</span>
		</AnimatedButton>
	);
};
