import type { ColumnDef, Table } from "@tanstack/react-table";
import {
	add,
	format,
	formatDuration,
	intervalToDuration,
	isBefore,
} from "date-fns";
import { it } from "date-fns/locale";

import {
	CircleCheck,
	CircleCheckBig,
	ClockFading,
	ExternalLink,
	Logs,
	SearchX,
	UserCog,
} from "lucide-react";
import Link from "next/link";
import { useRef } from "react";
import toast from "react-hot-toast";
import { NotePopover } from "~/components/notePopover";
import { AnnuncioCardRichieste } from "~/components/servizio/annuncio_card";
import { OrdersModal } from "~/components/servizio/servizio_actions";
import { WhatsAppIcon2 } from "~/components/svgs";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import {
	ContextMenu,
	ContextMenuContent,
	ContextMenuItem,
	ContextMenuLabel,
	ContextMenuSub,
	ContextMenuSubContent,
	ContextMenuSubTrigger,
	ContextMenuTrigger,
} from "~/components/ui/context-menu";
import { DataTable } from "~/components/ui/data-table";
import { DataTableColumnHeader } from "~/components/ui/dataTable-header";
import type {
	PinnedFiltro,
	SearchFiltro,
} from "~/components/ui/dataTable-toolbar";
import {
	Sheet,
	SheetContent,
	SheetDescription,
	SheetHeader,
	SheetTitle,
	SheetTrigger,
} from "~/components/ui/sheet";
import {
	Tooltip,
	TooltipContent,
	TooltipTrigger,
} from "~/components/ui/tooltip";
import { UserAvatar } from "~/components/user_avatar";
import { MutationPageRestore } from "~/lib/tableUtils";
import { cn } from "~/lib/utils";
import OrderTypeEnum from "~/schemas/public/OrderTypeEnum";
import StatusConfermaEnum from "~/schemas/public/StatusConfermaEnum";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import type { RichiesteData } from "~/server/controllers/servizio.controller";
import { api } from "~/utils/api";
import { DEFAULT_SERVIZIO_DURATION_DAYS } from "~/utils/config";

type RichiesteTableProps = {
	data: RichiesteData[];
};

export const RichiesteTable = ({ data }: RichiesteTableProps) => {
	const tabledata = data;
	const columns_titles = {
		id: "ID Ordine",
		username: "Utente",
		note: "Note",
		decorrenza: "Decorrenza",
		status: "Status",
		tipologia: "Tipo",
		annunci: "Annunci",
		ordini: "Ordini",
		interruzione_expires_at: "Scad. interr.",
		actions: "Azioni",
	};
	const statusOptions = [
		{ label: "Attesa di attivazione", value: "attesa_attivazione" },
		{ label: "Acconto pagato", value: "acconto_pagato" },
		{ label: "Saldo pagato", value: "saldo_pagato" },
		{ label: "Conferma in corso", value: "conferma" },
	];

	const type_options = [
		{ label: "Transitorio", value: TipologiaPosizioneEnum.Transitorio },
		{ label: "Stabile", value: TipologiaPosizioneEnum.Stabile },
	];

	type Column = (typeof tabledata)[number];
	const tableRef = useRef<Table<Column> | null>(null);
	const utils = api.useUtils();

	const { onMutate, onSettled } = MutationPageRestore(tableRef);
	const { mutate, isPending } = api.users.editUser.useMutation({
		onMutate,
		onSettled,
		onSuccess: async () => {
			toast.success("Note aggiornate con successo");
			await utils.users.invalidate();
			await utils.servizio.invalidate();
		},
		onError: (error) => {
			toast.error(error.message);
		},
	});
	const searchFiltro: SearchFiltro = {
		columnName: "username",
		placeholder: "Cerca...",
	};

	const columns: ColumnDef<Column>[] = [
		{
			accessorKey: "id",
			cell: () => null,
			enableHiding: false,
			header: () => null,
		},

		{
			accessorKey: "username",
			cell: ({ row }) => {
				const data = row.original;
				return (
					<ContextMenu>
						<ContextMenuTrigger asChild>
							<Link
								className="flex items-center gap-2"
								href={`/area-riservata/admin/user-view/ricerca/${data.user_id}`}
							>
								<UserAvatar
									className="size-8"
									userId={data.user_id}
									username={data.username}
								/>
								<span className="font-semibold text-sm">{data.username}</span>
							</Link>
						</ContextMenuTrigger>
						<ContextMenuContent>
							<ContextMenuLabel className="flex h-8 items-center gap-2">
								<UserAvatar
									className="size-5"
									style={{ height: "1.25rem", width: "1.25rem" }}
									userId={data.user_id}
									username={data.username}
								/>
								<span className="font-semibold text-sm">{data.username}</span>
							</ContextMenuLabel>

							<ContextMenuItem>
								<Link
									aria-label="Visualizza Profilo"
									className="flex w-full items-center gap-2"
									href={`/area-riservata/admin/user-view/edit-user/${data.user_id}`}
								>
									<UserCog className="text-muted-foreground" /> Profilo
								</Link>
							</ContextMenuItem>
							{data.extra_telefono_numero ? (
								<ContextMenuSub>
									<ContextMenuSubTrigger className="flex w-full items-center gap-2">
										<WhatsAppIcon2 className="size-4 fill-muted-foreground stroke-0" />
										WhatsApp
									</ContextMenuSubTrigger>
									<ContextMenuSubContent>
										<ContextMenuItem>
											<Link
												className="flex w-full items-center gap-2"
												href={`https://wa.me/${data.telefono}`}
												target="_blank"
											>
												<WhatsAppIcon2 className="size-4 fill-muted-foreground stroke-0" />
												WhatsApp ({data.nome})
											</Link>
										</ContextMenuItem>
										<ContextMenuItem>
											<Link
												className="flex w-full items-center gap-2"
												href={`https://wa.me/${data.extra_telefono_numero}`}
												target="_blank"
											>
												<WhatsAppIcon2 className="size-4 fill-muted-foreground stroke-0" />
												WhatsApp ({data.extra_telefono_titolo})
											</Link>
										</ContextMenuItem>
									</ContextMenuSubContent>
								</ContextMenuSub>
							) : (
								<ContextMenuItem>
									<Link
										className="flex w-full items-center gap-2"
										href={`https://wa.me/${data.telefono}`}
										target="_blank"
									>
										<WhatsAppIcon2 className="size-4 fill-muted-foreground stroke-0" />
										WhatsApp
									</Link>
								</ContextMenuItem>
							)}
						</ContextMenuContent>
					</ContextMenu>
				);
			},
			enableHiding: false,
			header: ({ column }) => (
				<DataTableColumnHeader
					column={column}
					title={columns_titles.username}
				/>
			),
		},
		{
			accessorKey: "note",
			cell: ({ row }) => {
				const note = row.original.note;
				return (
					<NotePopover
						isPending={isPending}
						mutate={mutate}
						note={note}
						userId={row.original.user_id}
					/>
				);
			},
			header: ({ column }) => (
				<DataTableColumnHeader column={column} title={columns_titles.note} />
			),
			enableSorting: false,
		},
		{
			accessorKey: "decorrenza",
			cell: ({ row }) => {
				let decorrenzaColor = "";
				let decorrenzaTooltip = "";
				if (!row.original.isOkAcconto || !row.original.decorrenza) {
					decorrenzaColor = "text-muted-foreground";
					decorrenzaTooltip = "Attesa di attivazione";
				} else if (row.original.isInterrotto) {
					decorrenzaColor = "text-destructive";
					decorrenzaTooltip = "Servizio interrotto";
				} else if (row.original.isOkAcconto && !row.original.isOkSaldo) {
					decorrenzaColor = "text-warning";
					decorrenzaTooltip = "Attesa di saldo";
				}

				return (
					<Tooltip>
						<TooltipTrigger className={decorrenzaColor}>
							{row.original.decorrenza
								? format(row.original.decorrenza, "dd/MM")
								: "---"}
						</TooltipTrigger>
						<TooltipContent>
							<p>{decorrenzaTooltip}</p>
						</TooltipContent>
					</Tooltip>
				);
			},
			enableHiding: false,
			header: ({ column }) => (
				<DataTableColumnHeader
					column={column}
					title={columns_titles.decorrenza}
				/>
			),

			sortingFn: "datetime",
		},
		{
			accessorKey: "tipologia",
			cell: ({ row }) => {
				const { tipologia } = row.original;
				return (
					<Badge
						className={cn(
							"px-1.5",
							tipologia === TipologiaPosizioneEnum.Transitorio
								? "border-transitorio bg-transitorio/15"
								: "border-stabile bg-stabile/15",
						)}
						variant="outline"
					>
						{tipologia.toString()}
					</Badge>
				);
			},
			filterFn: (row, id, value) => {
				return value.includes(row.getValue(id));
			},
			header: ({ column }) => (
				<DataTableColumnHeader
					column={column}
					title={columns_titles.tipologia}
				/>
			),
		},

		{
			accessorKey: "status",
			cell: ({ row }) => {
				let badgeClass = "";
				let contents: React.ReactNode;

				const resolveStatus = () => {
					if (row.original.isInterrotto) {
						badgeClass =
							"border-destructive bg-destructive/10 text-destructive";
						contents = (
							<>
								<SearchX className="stroke-red-500 dark:stroke-red-400" />
								Interrotto
							</>
						);
						return;
					}
					if (!row.original.onboardOk) {
						badgeClass = "border-pink-500 bg-pink-500/10 text-pink-600";
						contents = (
							<>
								<ClockFading className="stroke-pink-500 dark:stroke-pink-400" />
								Onboarding
							</>
						);
						return;
					}
					if (!row.original.isOkAcconto || !row.original.decorrenza) {
						const acconti = row.original.ordini_servizio.filter(
							(o) => o.type === OrderTypeEnum.Acconto,
						);

						const activeAcconto = acconti.find((a) => a.isActive);

						//hasActiveAcconto
						if (activeAcconto) {
							badgeClass = "border-yellow-500 bg-yellow-500/10 text-yellow-600";
							contents = (
								<>
									<ClockFading className="stroke-yellow-500 dark:stroke-yellow-400" />
									Attesa attivazione
								</>
							);
						} else {
							badgeClass = "border-yellow-500 bg-yellow-500/10 text-yellow-600";
							contents = (
								<>
									<ClockFading className="stroke-yellow-500 dark:stroke-yellow-400" />
									Attesa pag. acconto
								</>
							);
						}
						return;
					}
					if (
						isBefore(
							add(row.original.decorrenza, {
								days: DEFAULT_SERVIZIO_DURATION_DAYS,
							}),
							new Date(),
						) &&
						!row.original.isOkSaldo
					) {
						badgeClass = "border-red-500 bg-red-500/10 text-red-500";
						contents = (
							<>
								<SearchX className="stroke-red-500 dark:stroke-red-400" />
								Scaduto
							</>
						);
						return;
					}

					const contrattoInserito = row.original.annunci_servizio.filter(
						(a) => a.doc_contratto_added,
					);
					if (contrattoInserito.length > 0) {
						if (row.original.isOkSaldo) {
							if (row.original.isOkConsulenza) {
								badgeClass = "border-blue-500 bg-blue-500/10 text-blue-500";
								contents = (
									<>
										<CircleCheckBig className="stroke-blue-500 dark:stroke-blue-400" />
										Confermato
									</>
								);
								return;
							}
							if (
								//hasConsulanzaDaPagare
								row.original.ordini_servizio.some(
									(o) => o.type === OrderTypeEnum.Consulenza && !o.isActive,
								)
							) {
								badgeClass =
									"border-yellow-500 bg-yellow-500/10 text-yellow-600";
								contents = (
									<>
										<ClockFading className="stroke-yellow-500 dark:stroke-yellow-400" />
										Consulenza da pagare
									</>
								);
								return;
							}
							badgeClass = "border-yellow-500 bg-yellow-500/10 text-yellow-600";
							contents = (
								<>
									<ClockFading className="stroke-yellow-500 dark:stroke-yellow-400" />
									Consulenza da inserire
								</>
							);
							return;
						}
					}

					const annuncioCaparraVersata = row.original.annunci_servizio.filter(
						(a) => a.status_conferma === StatusConfermaEnum["Caparra versata"],
					);
					if (annuncioCaparraVersata.length > 0) {
						if (row.original.isOkSaldo) {
							badgeClass = "border-blue-500 bg-blue-500/10 text-blue-500";
							contents = (
								<>
									<CircleCheckBig className="stroke-blue-500 dark:stroke-blue-400" />
									Confermato
								</>
							);
						} else {
							badgeClass = "border-yellow-500 bg-yellow-500/10 text-yellow-600";
							contents = (
								<>
									<ClockFading className="stroke-yellow-500 dark:stroke-yellow-400" />
									Attesa saldo
								</>
							);
						}

						return;
					}
					const annuncioConfermato = row.original.annunci_servizio.filter(
						(a) =>
							a.status_conferma === StatusConfermaEnum["Conferma accettata"],
					);
					if (annuncioConfermato.length > 0) {
						badgeClass = "border-yellow-500 bg-yellow-500/10 text-yellow-600";
						contents = (
							<>
								<ClockFading className="stroke-yellow-500 dark:stroke-yellow-400" />
								Attesa di caparra
							</>
						);

						return;
					}

					const annuncioAttesaConferma = row.original.annunci_servizio.filter(
						(a) => a.status_conferma === StatusConfermaEnum["Inviato conferma"],
					);
					if (annuncioAttesaConferma.length > 0) {
						badgeClass = "border-blue-500 bg-blue-500/10 text-blue-500";
						contents = (
							<>
								<CircleCheckBig className="stroke-blue-500 dark:stroke-blue-400" />
								Attesa accett. conferma
							</>
						);
						return;
					}

					badgeClass = "border-green-500 bg-green-500/10 text-green-500";
					contents = (
						<>
							<CircleCheck className="stroke-green-500 dark:stroke-green-400" />
							Attivo
						</>
					);
				};
				resolveStatus();
				return (
					<Badge
						className={cn(
							"flex items-center px-1.5 text-muted-foreground [&>svg]:size-4",
							badgeClass,
						)}
						variant="outline"
					>
						{contents}
					</Badge>
				);
			},

			filterFn: (row, id, value) => {
				return value.includes(row.getValue(id));
			},
			header: ({ column }) => (
				<DataTableColumnHeader column={column} title={columns_titles.status} />
			),
		},
		{
			accessorKey: "interruzione_expires_at",
			cell: ({ row }) => {
				if (row.original.isInterrotto) return "---";
				if (!row.original.decorrenza) return "---";
				const expiresAt = add(row.original.decorrenza, {
					days: row.original.interruzioneDays,
				});
				const timeLeft = intervalToDuration({
					start: new Date(),
					end: expiresAt,
				});
				const daysLeft = timeLeft.days || 0;
				let badgeColor = "";
				if (daysLeft > 5) {
					badgeColor = "border-green-500 bg-green-500/10 text-green-500";
				} else if (daysLeft > 0) {
					badgeColor = "border-yellow-500 bg-yellow-500/10 text-yellow-500";
				} else {
					badgeColor = "border-red-500 bg-red-500/10 text-red-500";
				}
				return (
					<Tooltip>
						<TooltipTrigger>
							<Badge className={cn("px-1.5", badgeColor)} variant="outline">
								{format(expiresAt, "dd/MM")}
							</Badge>
						</TooltipTrigger>
						<TooltipContent>
							{daysLeft > 0 ? (
								<p>
									{formatDuration(timeLeft, { locale: it, format: ["days"] })}{" "}
									rimanenti
								</p>
							) : (
								<p>Interruzione scaduta</p>
							)}
						</TooltipContent>
					</Tooltip>
				);
			},
			enableSorting: false,
			header: ({ column }) => (
				<DataTableColumnHeader
					column={column}
					title={columns_titles.interruzione_expires_at}
				/>
			),
		},
		{
			accessorKey: "annunci_servizio",
			cell: ({ row }) => {
				const annunci = row.original.annunci_servizio;
				return (
					<Sheet>
						<SheetTrigger asChild>
							<Button
								className="data-[state=open]:border-primary data-[state=open]:bg-primary/10"
								size="sm"
								variant="outline"
							>
								{annunci.length}
							</Button>
						</SheetTrigger>
						<SheetContent className="w-4/5 sm:max-w-3xl">
							<SheetHeader>
								<SheetTitle>Annunci Inseriti</SheetTitle>
								<SheetDescription className="sr-only">Desc</SheetDescription>
							</SheetHeader>
							<div className="flex flex-col gap-4 divide-y overflow-y-auto">
								{annunci.map((a) => (
									<AnnuncioCardRichieste
										data={a}
										key={a.annunci_id}
										tableRef={tableRef}
									/>
								))}
							</div>
						</SheetContent>
					</Sheet>
				);
			},
			header: ({ column }) => (
				<DataTableColumnHeader column={column} title={columns_titles.annunci} />
			),
			enableSorting: false,
		},
		{
			accessorKey: "ordini",
			cell: ({ row }) => {
				//paidOrdiniCount
				const paidOrders = row.original.ordini_servizio.filter(
					(o) => o.isActive,
				).length;
				//unpaidOrdiniCount
				const unpaidOrders = row.original.ordini_servizio.length - paidOrders;
				return (
					<OrdersModal isAdmin={true} ordini={row.original.ordini_servizio}>
						<div className="relative inline-flex">
							<Button className="flex-1" size="sm" variant="outline">
								<Logs />
							</Button>
							{unpaidOrders > 0 && (
								<span className="absolute -top-1.5 -right-1.5 flex size-3.5 items-center justify-center rounded-full bg-red-600 text-white text-xs">
									{unpaidOrders}
								</span>
							)}
							{paidOrders > 0 && (
								<span className="absolute -top-1.5 -left-1.5 flex size-3.5 items-center justify-center rounded-full bg-green-600 text-white text-xs">
									{paidOrders}
								</span>
							)}
						</div>
					</OrdersModal>
				);
			},

			header: ({ column }) => (
				<DataTableColumnHeader column={column} title={columns_titles.ordini} />
			),
			enableSorting: false,
		},
		{
			cell: ({ row }) => {
				return (
					<Link
						href={`/area-riservata/admin/user-view/servizio/${row.original.user_id}/${row.original.servizio_id}`}
						target="_blank"
					>
						<Button aria-label="Apri servizio" size="sm" variant="outline">
							<ExternalLink className="size-5" />
						</Button>
					</Link>
				);
			},
			enableHiding: false,
			id: "actions",
		},
	];

	const pinnedFiltri: PinnedFiltro[] = [
		{
			columnName: "status",

			options: statusOptions,
			title: "Stato Ordine",
		},
		{
			columnName: "tipologia",
			options: type_options,
			title: "Tipo Ordine",
		},
	];

	return (
		<div className="mx-auto w-full">
			<DataTable
				columns={columns}
				columns_titles={columns_titles}
				data={tabledata}
				defaultSort={[{ desc: true, id: "decorrenza" }]}
				onTableInit={(t) => (tableRef.current = t)}
				pinnedFiltri={pinnedFiltri}
				searchColumn={searchFiltro}
			/>
		</div>
	);
};
