import { useMutation, useSuspenseQuery } from "@tanstack/react-query";
import { createFileRoute, redirect } from "@tanstack/react-router";
import { createColumnHelper } from "@tanstack/react-table";
import { format } from "date-fns-tz";
import { Trash } from "lucide-react";
import { Suspense, useState } from "react";
import { toast } from "sonner";
import { Button } from "../../components/ui/button";
import { Spinner } from "../../components/ui/spinner";
import { api } from "../../lib/apiHelper";
import { authClient } from "../../lib/auth-client";
import { getScanUsers } from "../../lib/queries/getScanUsers";
import EditableCellInput from "../../lib/tableStuff/EditableCellInput";
import LstTable from "../../lib/tableStuff/LstTable";
import SearchableHeader from "../../lib/tableStuff/SearchableHeader";
import SkellyTable from "../../lib/tableStuff/SkellyTable";
import NewScanUser from "./-components/NewScanUser";

export const Route = createFileRoute("/admin/scanUsers")({
	beforeLoad: async ({ location }) => {
		const { data: session } = await authClient.getSession();
		//const allowedRole = ["systemAdmin", "admin", "manager"];

		const canAccess = await authClient.admin.hasPermission({
			permissions: {
				mobile: ["create"],
			},
		});

		if (!session?.user) {
			throw redirect({
				to: "/",
				search: {
					redirect: location.href,
				},
			});
		}

		//if (!allowedRole.includes(session.user.role as string)) {

		if (!canAccess) {
			throw redirect({
				to: "/",
			});
		}

		return { user: session.user };
	},
	component: RouteComponent,
});

const updateSettings = async (
	id: string,
	data: Record<string, string | number | boolean | null>,
) => {
	//console.log(id, data);
	try {
		const res = await api.patch(`/mobile/auth/user/${id}`, data, {
			withCredentials: true,
			timeout: 15000,
			validateStatus: () => true,
		});
		toast.success(`User was just updated`);
		return res;
	} catch (err) {
		toast.error("Error in updating the user");
		return err;
	}
};

const ScanUserTable = () => {
	const { data, refetch } = useSuspenseQuery(getScanUsers());
	const columnHelper = createColumnHelper<any>();

	const updateSetting = useMutation({
		mutationFn: ({
			id,
			field,
			value,
		}: {
			id: string;
			field: string;
			value: string | number | boolean | null;
		}) => updateSettings(id, { [field]: value }),

		onSuccess: () => {
			// refetch or update cache
			refetch();
		},
	});

	const columns = [
		columnHelper.accessor("name", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="Name" searchable={true} />
			),
			filterFn: "includesString",
			cell: (i) => i.getValue(),
		}),
		columnHelper.accessor("scannerId", {
			header: ({ column }) => (
				<SearchableHeader
					column={column}
					title="Scanner ID"
					searchable={false}
				/>
			),
			filterFn: "includesString",
			cell: (i) => i.getValue(),
		}),
		columnHelper.accessor("pinNumber", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="Pin Number" />
			),

			filterFn: "includesString",
			cell: ({ row, getValue }) => (
				<div className="flex flex-row gap-2">
					<div>
						<EditableCellInput
							value={getValue()}
							id={row.original.id}
							field="pinNumber"
							onSubmit={({ id, field, value }) => {
								updateSetting.mutate({ id, field, value });
							}}
						/>
					</div>

					<div className="">
						<Button
							type="button"
							onClick={async () => {
								const { data } = await api.get("/mobile/pin/new");
								updateSetting.mutate({
									id: row.original.id,
									field: "pinNumber",
									value: data.data[0].pin,
								});
							}}
						>
							New Pin
						</Button>
					</div>
				</div>
			),
		}),
		columnHelper.accessor("lastScan", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="Last Scan" />
			),
			cell: (i) => <span>{format(i.getValue(), "M/d/yyyy HH:mm")}</span>,
		}),
		columnHelper.accessor("excludedCommand", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="Command id's Not Allowed" />
			),
			cell: (i) => {
				const commands = i.getValue().join();
				return (
					<span>{commands === "" ? "All commands allowed" : commands}</span>
				);
			},
		}),
		columnHelper.accessor("deleteUser", {
			header: ({ column }) => (
				<SearchableHeader
					column={column}
					title="Delete User"
					searchable={false}
				/>
			),
			filterFn: "includesString",
			cell: (i) => {
				// biome-ignore lint: just removing the lint for now to get this going will maybe fix later
				const [activeToggle, setActiveToggle] = useState(false);

				const onTrigger = async () => {
					setActiveToggle(true);

					try {
						const res = await api.delete(
							`/mobile/auth/user/${i.row.original.id}`,

							{
								withCredentials: true,
								timeout: 5000,
								validateStatus: () => true,
							},
						);

						if (res.data.success) {
							toast.success(`${i.row.original.name} was deleted.`);
							refetch();
							setActiveToggle(false);
						}

						if (!res.data.success) {
							toast.error(
								`${i.row.original.name} encountered an error when trying to delete: ${res.data.message}`,
							);
							refetch();
							setActiveToggle(false);
						}
					} catch (error) {
						setActiveToggle(false);
						console.error(error);
					}
				};

				return (
					<div>
						<div className="flex items-center space-x-2">
							<Button
								variant="destructive"
								disabled={activeToggle}
								onClick={onTrigger}
							>
								{activeToggle ? (
									<span>
										<Spinner />
									</span>
								) : (
									<span>
										<Trash />
									</span>
								)}
							</Button>
						</div>
					</div>
				);
			},
		}),
	];

	return (
		<div>
			<div className="flex justify-end m-2">
				<Suspense
					fallback={
						<div>
							<p>Loading...</p>
						</div>
					}
				>
					<NewScanUser refetch={refetch} />
				</Suspense>
			</div>
			<div>
				<LstTable data={data} columns={columns} pageSize={50} />
			</div>
		</div>
	);
};

// const NewUserForm = ()=>{
// 	const { data, refetch } = useSuspenseQuery(getScanUsers());
// }
function RouteComponent() {
	//const { data: session } = useSession();
	return (
		<Suspense fallback={<SkellyTable />}>
			<ScanUserTable />
		</Suspense>
	);
}
