import { format } from "date-fns";
import { CircleCheck, ClipboardPaste, Pen, Trash2, Wrench } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import toast from "react-hot-toast";
import z from "zod";
import { formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
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 { Button } from "../ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
} from "../ui/card";

import { Label } from "../ui/label";
import { Switch } from "../ui/switch";
import { UploadModal } from "../upload_modal";
import { DocCombo, DocInfo } from "./shared";

export const AdminLavoraConferma = () => {
	const { servizio } = useServizio();
	const { data } = useServizioAnnuncio();

	return (
		<Credenza>
			<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-6xl">
				<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-4">
						<DocSection />
						<Caparra />
						{servizio.tipologia === TipologiaPosizioneEnum.Transitorio && (
							<MotivazioneSection />
						)}
						<SendConferma />
					</div>
				</CredenzaBody>

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

const DocSection = () => {
	const { userId } = useServizio();
	const { data, updateServizioAnnunci } = useServizioAnnuncio();

	const utils = api.useUtils();
	// const { mutate: updateServizio } = api.servizio.UpdateConfermaDoc.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 { 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={async () => {
									await updateServizioAnnunci({
										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={async (f) => {
							await updateServizioAnnunci({
								doc_conferma_added: true,
								doc_conferma_ref: f.id,
							});

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

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 = () => {
	const { data, updateServizioAnnunci } = 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 = async () => {
		await updateServizioAnnunci({
			caparra_causale: caparra?.caparra_causale || null,
			caparra_iban: caparra?.caparra_iban || null,
			caparra_importo: caparra?.caparra_importo || null,
			caparra_intestazione: caparra?.caparra_intestazione || null,
		});
	};
	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={async () => {
						await handleSave();
					}}
					variant="success"
				>
					Salva
				</Button>
			</CardFooter>
		</Card>
	);
};

const MotivazioneSection = () => {
	const { servizioId } = useServizio();
	const { t } = useTranslation();

	const { data: servizio } = api.servizio.getServizio.useQuery({ servizioId });
	if (!servizio) return null;
	return (
		<Card>
			<CardHeader>
				<CardTitle>Motivazione di transitorietà</CardTitle>
				<CardDescription>
					Informazioni relative alla motivazione di transitorietà inserite
					dall&apos;utente
				</CardDescription>
			</CardHeader>
			<CardContent className="space-y-4">
				<div className="flex flex-col gap-2">
					<p>
						<span className="font-semibold">Motivazione specificata: </span>
						{servizio.motivazione_transitorio ? (
							<span>
								{
									t.preferenze.motivazioni_mappings.find(
										(m) => m.id === servizio.motivazione_transitorio,
									)?.title
								}
							</span>
						) : (
							<span className="text-red-500 italic">Non inserita</span>
						)}
					</p>
					<p>
						<span className="font-semibold">
							Data scadenza motivazione inserita:{" "}
						</span>
						{servizio.scadenza_motivazione_transitoria ? (
							format(servizio.scadenza_motivazione_transitoria, "dd/MM/yyyy")
						) : (
							<span className="text-red-500 italic">Non inserita</span>
						)}
					</p>
					<p>
						<span className="font-semibold">Documento caricato: </span>
						{servizio.doc_motivazione_ref ? (
							<FileLink userStorageId={servizio.doc_motivazione_ref} />
						) : (
							<span className="text-red-500 italic">Non caricato</span>
						)}
					</p>
				</div>
			</CardContent>
		</Card>
	);
};

const FileLink = ({
	userStorageId,
}: {
	userStorageId: UsersStorageUserStorageId;
}) => {
	const { data: storageId } =
		api.storage.getStorageIdFromUserStorageId.useQuery({
			userStorageId,
		});
	if (!storageId) return null;
	return (
		<Link
			className="underline hover:text-primary"
			href={`/area-riservata/allegato-view/${storageId}`}
			rel="noreferrer"
			target="_blank"
		>
			Vedi documento
		</Link>
	);
};

const SendConferma = () => {
	const { servizio } = useServizio();
	const { data } = useServizioAnnuncio();
	const { t } = useTranslation();
	const [check, setCheck] = useState(data.hasConfermaAdmin);
	const utils = api.useUtils();
	const { mutate: handleUpdate } =
		api.servizio.adminUpdateConfermaStatus.useMutation({
			onSuccess: async () => {
				await utils.servizio.getAllServizioAnnunci.invalidate();
				await utils.servizio.getServizio.invalidate({
					servizioId: servizio.servizio_id,
				});
				toast.success("Status aggiornato con successo");
			},
			onError: (error) => {
				toast.error(`Errore durante l'aggiornamento: ${error.message}`);
			},
		});

	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 specificata dall'utente:{" "}
										{servizio.permanenza
											? t.preferenze.permanenza[servizio.permanenza]
											: "non inserita"}
									</p>
									<p>
										Permanenza in descrizione: {(() => {
											const match = data.desc_it?.match(/Permanenza:.*$/m);
											return match
												? `"${match[0]}"`
												: "errore: testo non trovato in descrizione";
										})()}
									</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({
							servizioId: servizio.servizio_id,
							annuncioId: data.id,
							status: check,
						});
					}}
					variant="success"
				>
					Salva
				</Button>
			</CardFooter>
		</Card>
	);
};
