import { 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 { CircleFadingArrowUp, Trash } from "lucide-react";
import { Suspense, useMemo, useState } from "react";
import { toast } from "sonner";
import { Button } from "../../components/ui/button";
import { Spinner } from "../../components/ui/spinner";
import {
	Tooltip,
	TooltipContent,
	TooltipTrigger,
} from "../../components/ui/tooltip";
import { useSocketRoom } from "../../hooks/socket.io.hook";
import { api } from "../../lib/apiHelper";
import { authClient } from "../../lib/auth-client";
import { servers } from "../../lib/queries/servers";
import LstTable from "../../lib/tableStuff/LstTable";
import SearchableHeader from "../../lib/tableStuff/SearchableHeader";
import SkellyTable from "../../lib/tableStuff/SkellyTable";

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

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

		if (!allowedRole.includes(session.user.role as string)) {
			throw redirect({
				to: "/",
			});
		}

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

const ServerTable = () => {
	const { data, refetch } = useSuspenseQuery(servers());
	const columnHelper = createColumnHelper<any>();
	const okToUpdate = ["localhost", "usmcd1olp082"];
	const columns = [
		columnHelper.accessor("name", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="Name" searchable={true} />
			),
			filterFn: "includesString",
			cell: (i) => (
				<>
					<a
						href={`http://${i.row.original.server}:3000/lst/app`}
						target="_blank"
						rel="noopener"
					>
						{i.getValue()}
					</a>
				</>
			),
		}),
		columnHelper.accessor("greatPlainsPlantCode", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="GP Code" />
			),
			cell: (i) => <span>{i.getValue().toUpperCase()}</span>,
		}),
		columnHelper.accessor("server", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="server" />
			),
			cell: (i) => <span>{i.getValue().toUpperCase()}</span>,
		}),
		columnHelper.accessor("idAddress", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="IP Address" />
			),
			cell: (i) => <span>{i.getValue()}</span>,
		}),
	];

	if (okToUpdate.includes(window.location.hostname)) {
		columns.push(
			columnHelper.accessor("lastUpdated", {
				header: ({ column }) => (
					<SearchableHeader column={column} title="Last Update" />
				),
				cell: (i) => <span>{format(i.getValue(), "M/d/yyyy HH:mm")}</span>,
			}),
			columnHelper.accessor("buildNumber", {
				header: ({ column }) => (
					<SearchableHeader column={column} title="Build" />
				),
				cell: (i) => <span>{i.getValue()}</span>,
			}),
			columnHelper.accessor("update", {
				header: ({ column }) => (
					<SearchableHeader column={column} title="Update" 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 onToggle = async () => {
						toast.success(
							`${i.row.original.name} just started the upgrade monitor logs for errors.`,
						);
						setActiveToggle(activeToggle);

						try {
							const res = await api.post(
								`/admin/build/updateServer`,
								{
									server: i.row.original.server,
									destination: i.row.original.serverLoc,
									token: i.row.original.plantToken,
								},
								{ withCredentials: true, timeout: 5 * 60 * 1000 },
							);

							if (res.data.success) {
								toast.success(
									`${i.row.original.name} has completed its upgrade.`,
								);
								refetch();
								setActiveToggle(false);
							}
						} catch (error) {
							setActiveToggle(false);
							console.error(error);
						}
					};

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

	return <LstTable data={data} columns={columns} pageSize={50} />;
};

function RouteComponent() {
	const params = useMemo(
		() => ({
			submodule: "builds",
		}),
		[],
	);
	const { data: logs = [], clearRoom } = useSocketRoom<any>("logs", params);

	const columnHelper = createColumnHelper<any>();

	const logColumns = [
		columnHelper.accessor("timestamp", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="Time" searchable={false} />
			),
			filterFn: "includesString",
			cell: (i) => i.getValue(), //format(i.getValue(), "M/d/yyyy HH:mm") ,
		}),
		columnHelper.accessor("message", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="Message" />
			),
			cell: (i) => (
				<Tooltip>
					<TooltipTrigger>
						{i.getValue()?.length > 250 ? (
							<span>{i.getValue().slice(0, 250)}...</span>
						) : (
							<span>{i.getValue()}</span>
						)}
					</TooltipTrigger>
					<TooltipContent>{i.getValue()}</TooltipContent>
				</Tooltip>
			),
		}),
		columnHelper.accessor("clearLog", {
			header: ({ column }) => (
				<SearchableHeader column={column} title="Clear" />
			),
			cell: ({ row }) => {
				const x = row.original;
				return (
					<Button
						size="icon"
						variant={"destructive"}
						onClick={() => clearRoom((item) => item.timestamp === x.timestamp)}
					>
						<Trash />
					</Button>
				);
			},
		}),
	];
	const triggerBuild = async () => {
		try {
			const res = await api.post(
				`/admin/build/release`,

				{
					withCredentials: true,
				},
			);

			if (res.data.success) {
				toast.success(res.data.message);
			}

			if (!res.data.success) {
				toast.error(res.data.message);
			}
		} catch (err) {
			console.log(err);
			//toast.error(err?.message);
		}
	};
	//console.log(logs);
	return (
		<div className="flex flex-col gap-1 w-7xl">
			<div className="flex gap-1 justify-end">
				<Button onClick={triggerBuild}>Trigger Build</Button>
				<Button onClick={() => clearRoom()}>Clear Logs</Button>
			</div>
			<div className="flex gap-1 w-full">
				<div className="w-3/4">
					<Suspense fallback={<SkellyTable />}>
						<ServerTable />
					</Suspense>
				</div>
				<div className="w-1/2">
					<LstTable data={logs} columns={logColumns} />
				</div>
			</div>
		</div>
	);
}
