import { useCallback, useEffect, useState, useMemo } from "react";
import { useProjectId, useEnv } from "@/lib/state";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from "@/components/ui/resizable";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { useToast } from "@/hooks/use-toast";
import { Check, Ellipsis, LoaderCircle, LogsIcon, X, RefreshCw, Power } from "lucide-react";
import { XTerm } from "@/components/XTerm";

export function Logs() {
	const { toast } = useToast();
	const projectId = useProjectId();
	const env = useEnv();

	const [selectedServiceForLogs, setSelectedServiceForLogs] = useState<string | null>(null);
	const [selectedWorkerIdForLogs, setSelectedWorkerIdForLogs] = useState<string | null>(null);

	const [logs, setLogs] = useState<string>("");

	useEffect(() => {
		console.log("selectedServiceForLogs", selectedServiceForLogs);
		if (!selectedServiceForLogs || !selectedWorkerIdForLogs || !projectId) {
			setLogs("");
			return;
		}

		setLogs(""); // Clear logs for the new selection

		const eventSource = new EventSource(
			`/api/project/${projectId}/logs/${selectedServiceForLogs}/${selectedWorkerIdForLogs}`,
		);

		eventSource.onmessage = (event) => {
			try {
				const data = JSON.parse(event.data);
				if (data.logs) {
					setLogs((prevLogs) => prevLogs + data.logs + "\n");
				}
			} catch (e) {
				console.error("Failed to parse log data:", e);
			}
		};

		eventSource.onerror = () => {
			toast({
				variant: "destructive",
				title: "Log stream error",
				description: "Connection to the log stream has been closed.",
			});
			eventSource.close();
		};

		return () => {
			eventSource.close();
		};
	}, [selectedServiceForLogs, selectedWorkerIdForLogs, projectId, toast]);

	const sortedServices = useMemo(
		() => (env?.services ? [...env.services].sort((a, b) => a.name.localeCompare(b.name)) : []),
		[env?.services],
	);

	useEffect(() => {
		if (sortedServices.length > 0 && sortedServices[0].workers && sortedServices[0].workers.length > 0) {
			if (!selectedServiceForLogs && !selectedWorkerIdForLogs) {
				handleViewLogsClick(sortedServices[0].name, sortedServices[0].workers[0].id);
			}
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [sortedServices]);

	const handleViewLogsClick = (serviceName: string, workerId: string) => {
		setSelectedServiceForLogs(serviceName);
		setSelectedWorkerIdForLogs(workerId);
	};

	const handleReloadWorkerClick = useCallback(
		(serviceName: string, workerId: string) => {
			if (!projectId) return;
			toast({
				title: "Worker reload initiated",
				description: `Worker ${serviceName} / ${workerId} is reloading.`,
			});
			fetch(`/api/project/${projectId}/reload/${serviceName}/${workerId}`, {
				method: "POST",
			})
				.then((resp) => {
					if (!resp.ok) {
						throw new Error(`Failed to reload worker: ${resp.statusText}`);
					}
					toast({
						title: "Worker reloaded",
						description: `Successfully reloaded worker ${serviceName} / ${workerId}`,
					});
				})
				.catch((e) => {
					console.error(e);
					toast({
						variant: "destructive",
						title: "Failed to reload worker",
						description: `Failed to reload worker ${serviceName} / ${workerId} in service`,
					});
				});
		},
		[projectId, toast],
	);

	const handleQuitWorkerClick = useCallback(
		(serviceName: string, workerId: string) => {
			if (!projectId) return;
			if (!window.confirm(`Are you sure you want to terminate worker ${workerId} for service ${serviceName}?`)) {
				return;
			}
			toast({
				title: "Worker ${serviceName} / ${workerId} is being terminated.",
			});
			fetch(`/api/project/${projectId}/quitquitquit/${serviceName}/${workerId}`, {
				method: "POST",
			})
				.then((resp) => {
					if (!resp.ok) {
						toast({
							title: `Failed to terminate worker ${serviceName} / ${workerId}`,
							variant: "destructive",
						});
					} else {
						toast({
							title: `Successfully terminated worker ${serviceName} / ${workerId}`,
						});
					}
				})
				.catch((e) => {
					console.error(e);
					toast({
						title: `Failed to terminate worker ${serviceName} / ${workerId}`,
						variant: "destructive",
					});
				});
		},
		[projectId, toast],
	);

	const defaultExpandedServiceNames = useMemo(() => sortedServices.map((s) => s.name), [sortedServices]);
	const defaultExpandedFirstWorkerId = useMemo(() => {
		if (sortedServices.length > 0 && sortedServices[0].workers && sortedServices[0].workers.length > 0) {
			return sortedServices[0].workers[0].id;
		}
		return undefined;
	}, [sortedServices]);

	return (
		<ResizablePanelGroup direction="horizontal" className="h-full w-full">
			<ResizablePanel defaultSize={15}>
				<div className="flex flex-col h-full p-2 gap-2 overflow-y-auto">
					{sortedServices.length > 0 ? (
						<Accordion type="multiple" className="w-full" defaultValue={defaultExpandedServiceNames}>
							{sortedServices.map((service, serviceIndex) => (
								<AccordionItem value={service.name} key={service.name}>
									<AccordionTrigger className="py-1">{service.name}</AccordionTrigger>
									<AccordionContent className="pl-2">
										{service.workers && service.workers.length > 0 ? (
											<Accordion
												type="single"
												collapsible
												className="w-full"
												defaultValue={
													serviceIndex === 0 ? defaultExpandedFirstWorkerId : undefined
												}
											>
												{service.workers.map((worker) => (
													<AccordionItem value={worker.id} key={worker.id}>
														<AccordionTrigger className="py-1">
															{worker.id}
														</AccordionTrigger>
														<AccordionContent className="pl-2">
															<TooltipProvider>
																<div className="text-sm flex flex-col gap-1 items-start">
																	<Button
																		onClick={() =>
																			handleViewLogsClick(service.name, worker.id)
																		}
																		size="sm"
																		variant="link"
																		className="!px-0"
																	>
																		<LogsIcon className="w-4 h-4" />
																		View Logs
																	</Button>
																	<Button
																		onClick={() =>
																			handleReloadWorkerClick(
																				service.name,
																				worker.id,
																			)
																		}
																		size="sm"
																		variant="link"
																		className="!px-0"
																	>
																		<RefreshCw className="w-4 h-4" />
																		Reload Worker
																	</Button>
																	<Button
																		onClick={() =>
																			handleQuitWorkerClick(
																				service.name,
																				worker.id,
																			)
																		}
																		size="sm"
																		variant="link"
																		className="!px-0"
																	>
																		<Power className="w-4 h-4" />
																		Quit Worker
																	</Button>
																	{!worker.commit && (
																		<p className="flex items-center">
																			<FailureIcon />
																			Clone Repository
																		</p>
																	)}
																	<p>
																		Commit:
																		{worker.commit && (
																			<Tooltip>
																				<TooltipTrigger asChild>
																					<span className="inline-block">
																						<Badge
																							variant="outline"
																							className="ml-1 font-mono"
																						>
																							{worker.commit.hash.substring(
																								0,
																								8,
																							)}
																						</Badge>
																					</span>
																				</TooltipTrigger>
																				<TooltipContent
																					side="right"
																					className="flex flex-col gap-1"
																				>
																					<p>{worker.commit.message}</p>
																					<p>{worker.commit.hash}</p>
																				</TooltipContent>
																			</Tooltip>
																		)}
																	</p>
																	{worker.commands && worker.commands.length > 0 && (
																		<div>
																			Commands:
																			<ul className="list-none pl-0 font-['JetBrains_Mono']">
																				{worker.commands.map((cmd, index) => (
																					<li
																						key={index}
																						className="rounded flex items-start"
																					>
																						<span className="inline-block w-6 flex-shrink-0">
																							<CommandStateIcon
																								state={cmd.state}
																							/>
																						</span>
																						<span className="font-mono break-all">
																							{cmd.command}
																						</span>
																					</li>
																				))}
																			</ul>
																		</div>
																	)}
																	{(!worker.commands ||
																		worker.commands.length === 0) && (
																		<p className="text-xs text-gray-500">
																			No commands for this worker.
																		</p>
																	)}
																</div>
															</TooltipProvider>
														</AccordionContent>
													</AccordionItem>
												))}
											</Accordion>
										) : (
											<p className="text-sm text-gray-500 p-2">
												No workers found for this service.
											</p>
										)}
									</AccordionContent>
								</AccordionItem>
							))}
						</Accordion>
					) : (
						<div className="text-center text-gray-500 mt-4">No services available.</div>
					)}
				</div>
			</ResizablePanel>
			<ResizableHandle withHandle />
			<ResizablePanel defaultSize={85}>
				<div className="flex flex-col h-full">
					{selectedServiceForLogs && selectedWorkerIdForLogs ? (
						<>
							<div className="p-2 border-b text-sm text-muted-foreground">
								Logs for: {selectedServiceForLogs} / {selectedWorkerIdForLogs}
							</div>
							<div className="flex-1 h-full p-4 bg-muted overflow-auto">
								<XTerm logs={logs} />
							</div>
						</>
					) : (
						<div className="flex-1 flex items-center justify-center h-full p-4 bg-muted text-sm text-gray-500">
							Click 'View Logs' on a worker to display logs here.
						</div>
					)}
				</div>
			</ResizablePanel>
		</ResizablePanelGroup>
	);
}

function WaitingIcon(): JSX.Element {
	return <Ellipsis className="w-4 h-4 mr-2 inline-block align-middle" />;
}
function RunningIcon(): JSX.Element {
	return <LoaderCircle className="animate-spin w-4 h-4 mr-2 inline-block align-middle" />;
}

function SuccessIcon(): JSX.Element {
	return <Check className="w-4 h-4 mr-2 inline-block align-middle" />;
}

function FailureIcon(): JSX.Element {
	return <X className="w-4 h-4 mr-2 inline-block align-middle" />;
}

function CommandStateIcon({ state }: { state: string | undefined }): JSX.Element | null {
	switch (state?.toLowerCase()) {
		case "running":
			return <RunningIcon />;
		case "success":
			return <SuccessIcon />;
		case "failure":
			return <FailureIcon />;
		case "waiting":
			return <WaitingIcon />;
		default:
			return null;
	}
}
