import type { Table } from "@tanstack/react-table";
import { format } from "date-fns";
import { NotebookPen, Toolbox } from "lucide-react";
import Image from "next/image";
import { type RefObject, useState } from "react";
import toast from "react-hot-toast";
import LoadingButton from "~/components/custom_ui/loading-button";
import {
	AdminActions,
	AnnuncioConfermaPopover,
	AnnuncioContatti,
	UserActions,
} from "~/components/servizio/annuncio_actions";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { Textarea } from "~/components/ui/textarea";
import { useMediaQuery } from "~/hooks/use-media-query";
import { handleConsegna } from "~/lib/annuncio_details";
import { getStorageUrl } from "~/lib/storage_utils";
import { MutationPageRestore } from "~/lib/tableUtils";
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 { ServizioServizioId } from "~/schemas/public/Servizio";
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
import type {
	RichiesteData,
	ServizioAnnuncioData,
} from "~/server/controllers/servizio.controller";
import { api } from "~/utils/api";
import { Button } from "../ui/button";
import {
	Collapsible,
	CollapsibleContent,
	CollapsibleTrigger,
} from "../ui/collapsible";
import { AnnuncioDettaglio, TipoBadge } from "./annuncio_dettaglio";

export const AnnuncioCard = ({ className }: { className?: string }) => {
	const { isAdmin } = useServizio();
	const { data } = useServizioAnnuncio();

	return (
		<AnnuncioCardContent
			className={className}
			data={data}
			interactions={
				isAdmin ? (
					<div className="flex flex-col gap-2">
						<Collapsible className="space-y-2">
							<CollapsibleTrigger asChild>
								<Button size="sm" variant="outline">
									<Toolbox />
									<span>Azioni Utente</span>
								</Button>
							</CollapsibleTrigger>
							<CollapsibleContent className="rounded-md border border-card bg-card p-2">
								<UserActions />
							</CollapsibleContent>
						</Collapsible>

						<AdminActions />
					</div>
				) : (
					<UserActions />
				)
			}
			isAdmin={isAdmin}
		/>
	);
};

const AnnuncioCardContent = ({
	interactions,
	className,
	data,
	isAdmin,
}: {
	interactions?: React.ReactNode;
	className?: string;
	data: ServizioAnnuncioData;
	isAdmin: boolean;
}) => {
	return (
		<Card
			className={cn(
				"w-full max-w-7xl gap-2 rounded-md border-none bg-muted py-3",
				className,
			)}
		>
			<CardHeader className="flex flex-row flex-wrap items-center justify-between space-y-0 px-3 pb-2">
				<CardTitle className="text-2xl">Annuncio {data.codice}</CardTitle>
			</CardHeader>
			<CardContent className="px-3">
				<div
					className={cn(
						"grid grid-cols-1 gap-4",
						isAdmin && "sm:grid-cols-[2fr_1fr]",
					)}
				>
					<div
						className={cn("@container flex w-full flex-col gap-4")}
						id="container"
					>
						<AnnuncioDisplay data={data} />

						<div className="flex w-full flex-col gap-4">{interactions}</div>
					</div>
					{isAdmin && (
						<AnnuncioNote
							annuncioId={data.id}
							note={data.note}
							servizioId={data.servizio_id}
						/>
					)}
				</div>
			</CardContent>
		</Card>
	);
};
export const AnnuncioCardRichieste = ({
	tableRef,
	data,
}: {
	tableRef: RefObject<Table<RichiesteData> | null>;
	data: ServizioAnnuncioData;
}) => {
	const [newNote, setNewNote] = useState<string | null>(data.note);
	const utils = api.useUtils();
	const { onMutate, onSettled } = MutationPageRestore(tableRef);
	const { mutate, isPending } = api.servizio.updateServizioAnnunci.useMutation({
		onMutate,
		onSettled,
		onSuccess: async () => {
			toast.success("Note aggiornate");
			await utils.servizio.invalidate();
		},
		onError: () => {
			toast.error("Errore nell'aggiornamento note");
		},
	});
	const isDesktop = useMediaQuery("(min-width: 40rem)");
	return (
		<Card className="w-full max-w-7xl gap-2 rounded-md border-none bg-muted py-3">
			<CardHeader className="flex flex-row flex-wrap items-center justify-between space-y-0 px-3 pb-2">
				<CardTitle className="text-2xl">Annuncio {data.codice}</CardTitle>
			</CardHeader>
			<CardContent className="px-3">
				<div className="grid grid-cols-1 gap-4 sm:grid-cols-[2fr_1fr]">
					<div
						className={cn("@container flex w-full flex-col gap-4")}
						id="container"
					>
						<AnnuncioDisplay data={data} />

						<div className="flex w-full flex-col gap-4">
							<div>
								<p>
									Visto contatti:{" "}
									{data.open_contatti_at
										? format(data.open_contatti_at, "dd/MM/yyyy HH:mm")
										: "Non ancora visto"}
								</p>
							</div>
						</div>
						<div className="flex flex-wrap gap-4">
							<div>
								<AnnuncioContatti data={data} />
							</div>
							<div>
								<AnnuncioConfermaPopover
									annuncioId={data.id}
									servizioId={data.servizio_id}
									status_conferma={data.status_conferma}
								/>
							</div>
						</div>
					</div>

					<Collapsible
						className={cn("space-y-2", isDesktop && "relative -top-10")}
						open={isDesktop || undefined}
					>
						<CollapsibleTrigger asChild>
							<Button
								className={cn(isDesktop && "cursor-default")}
								size="sm"
								variant={isDesktop ? "flat" : "outline"}
							>
								<NotebookPen />
								<span>Annotazioni</span>
							</Button>
						</CollapsibleTrigger>
						<CollapsibleContent className="">
							<div className="flex w-full flex-col gap-2">
								<Textarea
									className="min-h-64"
									id={`note-${data.id}`}
									onChange={(e) => setNewNote(e.target.value)}
									placeholder=""
									value={newNote || ""}
								/>
								<LoadingButton
									disabled={newNote === data.note}
									loading={isPending}
									onClick={() => {
										mutate({
											annuncioId: data.id,
											servizioId: data.servizio_id,
											data: { note: newNote },
										});
									}}
									type="button"
									variant="success"
								>
									Salva
								</LoadingButton>
							</div>
						</CollapsibleContent>
					</Collapsible>
				</div>
			</CardContent>
		</Card>
	);
};

const AnnuncioNote = ({
	servizioId,
	annuncioId,
	note,
}: {
	servizioId: ServizioServizioId;
	annuncioId: AnnunciId;
	note: string | null;
}) => {
	const [newNote, setNewNote] = useState<string | null>(note);
	const utils = api.useUtils();
	const { mutate, isPending } = api.servizio.updateServizioAnnunci.useMutation({
		onSuccess: async () => {
			toast.success("Note aggiornate");
			await utils.servizio.invalidate();
		},
		onError: () => {
			toast.error("Errore nell'aggiornamento note");
		},
	});
	const isDesktop = useMediaQuery("(min-width: 40rem)");

	return (
		<Collapsible
			className={cn("space-y-2", isDesktop && "relative -top-10")}
			open={isDesktop || undefined}
		>
			<CollapsibleTrigger asChild>
				<Button
					className={cn(isDesktop && "cursor-default")}
					size="sm"
					variant={isDesktop ? "flat" : "outline"}
				>
					<NotebookPen />
					<span>Annotazioni</span>
				</Button>
			</CollapsibleTrigger>
			<CollapsibleContent className="">
				<div className="flex w-full flex-col gap-2">
					<Textarea
						className="min-h-64"
						id={`note-${annuncioId}`}
						onChange={(e) => setNewNote(e.target.value)}
						placeholder=""
						value={newNote || ""}
					/>
					<LoadingButton
						disabled={newNote === note}
						loading={isPending}
						onClick={() => {
							mutate({
								annuncioId,
								servizioId,
								data: { note: newNote },
							});
						}}
						type="button"
						variant="success"
					>
						Salva
					</LoadingButton>
				</div>
			</CollapsibleContent>
		</Collapsible>
	);
};

export const AnnuncioDisplay = ({
	data,
	className,
}: {
	data: AnnuncioRicerca;
	className?: string;
}) => {
	const { t } = useTranslation();

	return (
		<div
			className={cn(
				"grid @md:grid-cols-[12rem_1fr] grid-cols-[7rem_1fr] @sm:gap-x-4 gap-x-1 gap-y-2 rounded-md bg-card md:max-w-5xl lg:gap-x-4 xl:gap-x-6",
				className,
			)}
		>
			<div className="row-span-1 md:row-span-3">
				<Image
					alt={data.codice}
					className="size-24 rounded-md bg-[#e6e9ec] object-cover md:size-48"
					height={1080}
					priority
					src={
						(data?.images[0] &&
							getStorageUrl({
								storageId: data.images[0].img,
								params: {
									cacheKey: data.media_updated_at?.toISOString(),
									media: "image",
								},
							})) ||
						"/fallback-image.png"
					}
					width={1920}
				/>
			</div>

			<div className="col-span-1 flex w-full max-w-xl flex-wrap gap-5 pt-2 md:col-span-1 md:mt-4 md:pr-8">
				<span className="text-wrap">{data.titolo_it}</span>
			</div>

			<div className="col-span-2 flex w-full max-w-xl items-center justify-between gap-2 pr-3 md:col-span-1 md:pr-8">
				<TipoBadge mini tipo={data.tipo} />
				<span className="max-w-auto truncate">
					{handleConsegna({
						aggiornamento: t.card.in_aggiornamento,
						consegna: data.consegna,
						consegna_da: t.card.consegna_da,
						mesi: t.parametri.mesi,
						subito: t.card.consegna_subito,
					})}
				</span>
				<span className="font-semibold">
					{formatCurrency(data.prezzo / 1e2)}
				</span>
			</div>
			<div className="col-span-2 w-full max-w-xl md:col-span-1 md:pr-8">
				<AnnuncioDettaglio data={data} />
			</div>
		</div>
	);
};
