import DragIndicatorIcon from "@mui/icons-material/DragIndicator";
import { Box, CircularProgress, Tooltip, Typography } from "@mui/material";
import { useNavigate } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import type { Kennzahl } from "../types/kpi";
import { getDisplayType } from "../types/kpi";
import { fetchKennzahlen as fetchK } from "../util/api";
import { API_HOST } from "../util/api";

type ConfigTableProps = {
	from?: string;
};

export function ConfigTable({ from }: ConfigTableProps) {
	const navigate = useNavigate();
	const [kennzahlen, setKennzahlen] = useState<Kennzahl[]>([]);
	const [draggedItem, setDraggedItem] = useState<Kennzahl | null>(null);
	const [isUpdatingPositions, setIsUpdatingPositions] = useState(false);
	const [loading, setLoading] = useState(true);

	useEffect(() => {
		const fetchKennzahlen = async () => {
			while (true) {
				try {
					console.log("Fetching kennzahlen from API...");
					const data = await fetchK();
					console.log("Fetched kennzahlen:", data);
					const sortedData = data.sort(
						(a: Kennzahl, b: Kennzahl) => a.position - b.position,
					);
					setKennzahlen(sortedData);
					setLoading(false);
					break;
				} catch (err) {
					console.error("Error fetching kennzahlen:", err);
					await new Promise((resolve) => setTimeout(resolve, 2000));
				}
			}
		};

		fetchKennzahlen();
	}, []);

	const handleToggleActive = async (id: number) => {
		const kennzahl = kennzahlen.find((k) => k.id === id);
		if (!kennzahl) return;

		try {
			const response = await fetch(
				`${API_HOST}/api/kpi_setting/${id}`,
				{
					method: "PUT",
					headers: {
						"Content-Type": "application/json",
					},
					body: JSON.stringify({
						active: !kennzahl.active,
					}),
				},
			);

			if (!response.ok) {
				throw new Error(`HTTP error! status: ${response.status}`);
			}

			const updatedKennzahl = await response.json();
			setKennzahlen((prev) =>
				prev.map((item) => (item.id === id ? updatedKennzahl : item)),
			);
		} catch (err) {
			console.error("Error toggling active status:", err);
			setKennzahlen((prev) =>
				prev.map((item) => (item.id === id ? kennzahl : item)),
			);
		}
	};

	const updatePositionsInBackend = async (reorderedKennzahlen: Kennzahl[]) => {
		setIsUpdatingPositions(true);
		try {
			const positionUpdates = reorderedKennzahlen.map((kennzahl, index) => ({
				id: kennzahl.id,
				position: index + 1,
			}));

			const response = await fetch(
				`${API_HOST}/api/kpi_setting/update-kpi-positions`,
				{
					method: "PUT",
					headers: {
						"Content-Type": "application/json",
					},
					body: JSON.stringify(positionUpdates),
				},
			);

			if (!response.ok) {
				throw new Error(`HTTP error! status: ${response.status}`);
			}

			const updatedKennzahlen = await response.json();
			setKennzahlen(updatedKennzahlen);
		} catch (err) {
			console.error("Error updating positions:", err);
			window.location.reload();
		} finally {
			setIsUpdatingPositions(false);
		}
	};

	const handleDragStart = (
		e: React.DragEvent<HTMLTableRowElement>,
		item: Kennzahl,
	) => {
		setDraggedItem(item);
		e.dataTransfer.effectAllowed = "move";
	};

	const handleDragOver = (e: React.DragEvent<HTMLTableRowElement>) => {
		e.preventDefault();
		e.dataTransfer.dropEffect = "move";
	};

	const handleDrop = async (
		e: React.DragEvent<HTMLTableRowElement>,
		targetItem: Kennzahl,
	) => {
		e.preventDefault();
		if (!draggedItem || draggedItem.id === targetItem.id) return;

		const draggedIndex = kennzahlen.findIndex(
			(item) => item.id === draggedItem.id,
		);
		const targetIndex = kennzahlen.findIndex(
			(item) => item.id === targetItem.id,
		);

		const newKennzahlen = [...kennzahlen];
		const [removed] = newKennzahlen.splice(draggedIndex, 1);
		newKennzahlen.splice(targetIndex, 0, removed);

		setKennzahlen(newKennzahlen);
		setDraggedItem(null);
		await updatePositionsInBackend(newKennzahlen);
	};

	const handleDragEnd = () => {
		setDraggedItem(null);
	};

	const handleRowClick = (kennzahl: Kennzahl, e: React.MouseEvent) => {
		if (draggedItem || isUpdatingPositions) {
			return;
		}

		const target = e.target as HTMLElement;
		if (
			target.tagName === "INPUT" &&
			(target as HTMLInputElement).type === "checkbox"
		) {
			return;
		}

		if (target.closest(".drag-handle")) {
			return;
		}

		navigate({
			to: `/config-detail/$kpiId`,
			params: { kpiId: kennzahl.id.toString() },
			search: from ? { from } : undefined,
		});
	};

	if (loading) {
		return (
			<Box
				height="100vh"
				display="flex"
				justifyContent="center"
				alignItems="center"
				flexDirection="column"
				mt={8}
			>
				<CircularProgress sx={{ color: "#383838", mb: 2 }} />
				<Typography>Lade Kennzahlen-Konfiguration...</Typography>
			</Box>
		);
	}

	return (
		<Box
			sx={{
				width: "70%",
				maxWidth: 800,
				borderRadius: 2,
				boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
				backgroundColor: "white",
				overflow: "hidden",
				opacity: isUpdatingPositions ? 0.7 : 1,
				pointerEvents: isUpdatingPositions ? "none" : "auto",
			}}
		>
			<table
				style={{
					width: "100%",
					borderCollapse: "collapse",
				}}
			>
				<thead>
					<tr style={{ backgroundColor: "#f5f5f5" }}>
						<th
							style={{
								padding: "16px 12px",
								textAlign: "left",
								fontWeight: "bold",
								width: "60px",
								borderBottom: "1px solid #e0e0e0",
							}}
						/>
						<th
							style={{
								padding: "16px 12px",
								textAlign: "left",
								fontWeight: "bold",
								width: "80px",
								borderBottom: "1px solid #e0e0e0",
							}}
						>
							Aktiv
						</th>
						<th
							style={{
								padding: "16px 12px",
								textAlign: "left",
								fontWeight: "bold",
								borderBottom: "1px solid #e0e0e0",
							}}
						>
							Name
						</th>
						<th
							style={{
								padding: "16px 12px",
								textAlign: "left",
								fontWeight: "bold",
								width: "160px",
								borderBottom: "1px solid #e0e0e0",
							}}
						>
							Format
						</th>
					</tr>
				</thead>
				<tbody>
					{kennzahlen.map((kennzahl) => (
						<tr
							key={kennzahl.id}
							draggable={!isUpdatingPositions}
							onDragStart={(e) => handleDragStart(e, kennzahl)}
							onDragOver={handleDragOver}
							onDrop={(e) => handleDrop(e, kennzahl)}
							onDragEnd={handleDragEnd}
							onClick={(e) => handleRowClick(kennzahl, e)}
							style={{
								borderBottom: "1px solid #e0e0e0",
								cursor: isUpdatingPositions ? "default" : "pointer",
								backgroundColor:
									draggedItem?.id === kennzahl.id ? "#f0f0f0" : "white",
								opacity: draggedItem?.id === kennzahl.id ? 0.5 : 1,
							}}
							onMouseEnter={(e) => {
								if (!draggedItem && !isUpdatingPositions) {
									e.currentTarget.style.backgroundColor = "#f9f9f9";
								}
							}}
							onMouseLeave={(e) => {
								if (!draggedItem && !isUpdatingPositions) {
									e.currentTarget.style.backgroundColor = "white";
								}
							}}
						>
							<td style={{ padding: "12px", textAlign: "center" }}>
								<div className="drag-handle">
									<Tooltip
										title={
											<>
												<b>Neuanordnung der Kennzahlen</b>
												<br />
												Hier können Sie die Kennzahlen nach Belieben per Drag
												and Drop neu anordnen.
											</>
										}
										placement="left"
										arrow
									>
										<DragIndicatorIcon
											sx={{
												color: isUpdatingPositions ? "#ccc" : "#999",
												cursor: isUpdatingPositions ? "default" : "grab",
												"&:active": {
													cursor: isUpdatingPositions ? "default" : "grabbing",
												},
											}}
										/>
									</Tooltip>
								</div>
							</td>
							<td style={{ padding: "12px" }}>
								<input
									type="checkbox"
									checked={kennzahl.active}
									onChange={() => handleToggleActive(kennzahl.id)}
									disabled={isUpdatingPositions}
									style={{
										width: "18px",
										height: "18px",
										cursor: isUpdatingPositions ? "default" : "pointer",
										accentColor: "#383838",
									}}
									onClick={(e) => e.stopPropagation()}
								/>
							</td>
							<td
								style={{
									padding: "12px",
									fontSize: "14px",
									color: "#333",
								}}
							>
								<span title={`Click to view details (ID: ${kennzahl.id})`}>
									{kennzahl.name}
								</span>
							</td>
							<td style={{ padding: "12px" }}>
								<span
									style={{
										color: "#333",
										padding: "4px 12px",
										borderRadius: "16px",
										fontSize: "12px",
										fontWeight: "500",
										border: "1px solid #ddd",
										backgroundColor: "#f8f9fa",
									}}
								>
									{getDisplayType(kennzahl.type)}
								</span>
							</td>
						</tr>
					))}
				</tbody>
			</table>
		</Box>
	);
}
