import type { ColumnDef } from "@tanstack/react-table";
import { EllipsisVertical, Trash2, Wrench } from "lucide-react";
import { DataTable } from "~/components/custom_ui/data-table";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import type {
	PinnedFiltro,
	SearchFiltro,
} from "~/components/custom_ui/dataTable-toolbar";
import { Button } from "~/components/ui/button";
import {
	DropdownMenu,
	DropdownMenuContent,
	DropdownMenuItem,
	DropdownMenuLabel,
	DropdownMenuPortal,
	DropdownMenuRadioGroup,
	DropdownMenuRadioItem,
	DropdownMenuSeparator,
	DropdownMenuSub,
	DropdownMenuSubContent,
	DropdownMenuSubTrigger,
	DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
import { formatCurrency } from "~/lib/utils";
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
import type { OrdiniWPagamenti } from "~/server/controllers/ordini.controller";
import { api } from "~/utils/api";

type PaymentsTableProps = {
	data: OrdiniWPagamenti["pagamenti"];
	isAdmin: boolean;
	isUserView?: boolean;
};

const StatusMapping = (status: PaymentStatusEnum | null) => {
	switch (status) {
		case PaymentStatusEnum.success:
			return "Successo";
		case PaymentStatusEnum.processing:
			return "In lavorazione";
		case PaymentStatusEnum.failed:
			return "Errore";
		default:
			return "Non completato";
	}
};
const EnumFromString = (value: string) => {
	switch (value) {
		case "Successo":
			return PaymentStatusEnum.success;
		case "In lavorazione":
			return PaymentStatusEnum.processing;
		case "Errore":
			return PaymentStatusEnum.failed;
		default:
			return null;
	}
};

export const PaymentsTable = ({
	data,
	isAdmin,
	isUserView = false,
}: PaymentsTableProps) => {
	const tabledata = data.map((row) => {
		return {
			actions: "Azioni",
			amount: row.amount_cent,
			id: row.id,
			paid_at: row.paid_at,
			raw_status: row.paymentstatus,
			status: StatusMapping(row.paymentstatus),
		};
	});

	const columns_titles = {
		actions: "Azioni",
		amount: "Importo",
		paid_at: "Pagato il",
		status: "Stato",
		username: "Utente",
	};
	const status_options = [
		{ label: "Inutilizzato", value: "Inutilizzato" },
		{ label: "Successo", value: "Successo" },
		{ label: "In lavorazione", value: "In lavorazione" },
		{ label: "Errore", value: "Errore" },
	];
	const utils = api.useUtils();
	const { mutate: update } = api.servizio.updatePagamento.useMutation({
		onSuccess: async () => {
			await utils.servizio.getAllPagamenti.invalidate();
			await utils.servizio.getOrdini.invalidate();
			await utils.servizio.getOrdineById.invalidate({
				ordineId: data[0]?.ordine_id,
			});
			if ((!isAdmin || isUserView) && data[0]) {
				await utils.servizio.getUserPagamenti.invalidate({
					userId: data[0].userid,
				});
			}
		},
	});
	const { mutate: remove } = api.servizio.removePagamento.useMutation({
		onSuccess: async () => {
			await utils.servizio.getAllPagamenti.invalidate();
			await utils.servizio.getOrdini.invalidate();
			await utils.servizio.getOrdineById.invalidate({
				ordineId: data[0]?.ordine_id,
			});
			if ((!isAdmin || isUserView) && data[0]) {
				await utils.servizio.getUserPagamenti.invalidate({
					userId: data[0].userid,
				});
			}
		},
	});

	type Column = (typeof tabledata)[number];

	const columns: ColumnDef<Column>[] = [
		{
			accessorKey: "paid_at",
			cell: ({ row }) => {
				const date = row.getValue("paid_at");
				return new Date(date as Date).toLocaleDateString();
			},
			enableHiding: false,
			header: ({ column }) => (
				<DataTableColumnHeader column={column} title={columns_titles.paid_at} />
			),
			sortingFn: "datetime",
		},
		{
			accessorKey: "status",

			filterFn: (row, id, value) => {
				return value.includes(row.getValue(id));
			},
			header: ({ column }) => (
				<DataTableColumnHeader column={column} title={columns_titles.status} />
			),
		},
		{
			accessorKey: "amount",
			cell: ({ row }) => {
				return <span>{formatCurrency(row.original.amount / 100)}</span>;
			},
			header: ({ column }) => (
				<DataTableColumnHeader column={column} title={columns_titles.amount} />
			),
		},
		{
			cell: ({ row }) => {
				const data = row.original;
				if (!isAdmin) return null;
				return (
					<DropdownMenu>
						<DropdownMenuTrigger asChild>
							<Button className="size-8 p-0" variant="ghost">
								<span className="sr-only">Open menu</span>
								<EllipsisVertical />
							</Button>
						</DropdownMenuTrigger>
						<DropdownMenuContent align="end">
							<DropdownMenuLabel>Azioni</DropdownMenuLabel>
							<DropdownMenuSub>
								<DropdownMenuSubTrigger>
									<Wrench />
									<span>Aggiorna status</span>
								</DropdownMenuSubTrigger>
								<DropdownMenuPortal>
									<DropdownMenuSubContent>
										<DropdownMenuRadioGroup
											onValueChange={(v) => {
												update({
													data: { paymentstatus: EnumFromString(v) },
													pagamentoId: data.id,
												});
											}}
											value={StatusMapping(data.raw_status)}
										>
											<DropdownMenuRadioItem value="Inutilizzato">
												Inutilizzato
											</DropdownMenuRadioItem>

											<DropdownMenuRadioItem value="Successo">
												Successo
											</DropdownMenuRadioItem>
											<DropdownMenuRadioItem value="In lavorazione">
												In lavorazione
											</DropdownMenuRadioItem>
											<DropdownMenuRadioItem value="Errore">
												Errore
											</DropdownMenuRadioItem>
										</DropdownMenuRadioGroup>
									</DropdownMenuSubContent>
								</DropdownMenuPortal>
							</DropdownMenuSub>
							<DropdownMenuSeparator />
							<DropdownMenuItem
								aria-label="Elimina Pagamento"
								className="flex items-center gap-3 hover:cursor-pointer"
								onClick={() =>
									confirm("Sei sicuro di voler eliminare il servizio?") &&
									remove({ pagamentoId: data.id })
								}
							>
								<Trash2 className="size-6" />
								Elimina Pagamento
							</DropdownMenuItem>
						</DropdownMenuContent>
					</DropdownMenu>
				);
			},
			enableHiding: false,
			id: "actions",
		},
	];

	const searchFiltro: SearchFiltro | undefined =
		isAdmin && !isUserView
			? {
					columnName: "username",
					placeholder: "Cerca utente...",
				}
			: undefined;

	const pinnedFiltri: PinnedFiltro[] = [
		{
			columnName: "status",
			options: status_options,
			title: "Status",
		},
	];

	return (
		<div className="w-full py-6">
			<DataTable
				columns={columns}
				columns_titles={columns_titles}
				data={tabledata}
				defaultColumnVisibility={{
					actions: true,
					amount: true,
					packid: true,
					paid_at: true,
					status: true,
					username: isAdmin && !isUserView,
				}}
				defaultSort={[{ desc: true, id: "paid_at" }]}
				pinnedFiltri={pinnedFiltri}
				searchColumn={searchFiltro}
			/>
		</div>
	);
};
