import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import EditIcon from "@mui/icons-material/Edit";
import {
	Box,
	Button,
	Dialog,
	DialogActions,
	DialogContent,
	DialogContentText,
	DialogTitle,
	IconButton,
	Link,
	Paper,
	Radio,
	Table,
	TableBody,
	TableCell,
	TableContainer,
	TableHead,
	TableRow,
	TextField,
	Typography,
} from "@mui/material";
import {
	useMutation,
	useQueryClient,
	useSuspenseQuery,
} from "@tanstack/react-query";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect, useState, type KeyboardEvent } from "react";
import PDFViewer from "../components/pdfViewer";
import { fetchPutKPI } from "../util/api";
import { kpiQueryOptions } from "../util/query";
import { redirect } from "@tanstack/react-router";

export const Route = createFileRoute("/extractedResult_/$pitchBook/$kpi")({
	component: ExtractedResultsPage,
	validateSearch: (search: Record<string, unknown>) => {
		return {
			from: typeof search.from === "string" ? search.from : undefined,
		};
	},
	loader: async ({ context: { queryClient }, params: { pitchBook } }) => {
		try {
			return await queryClient.ensureQueryData(kpiQueryOptions(pitchBook));
		} catch (err) {
			throw redirect({
				to: "/"
			});
		}
	},
});

function ExtractedResultsPage() {
	const params = Route.useParams() as { pitchBook: string; kpi: string };
	const { pitchBook, kpi } = params;
	const navigate = useNavigate();
	const queryClient = useQueryClient();
	const { from } = Route.useSearch();

	const { data: kpiData } = useSuspenseQuery(kpiQueryOptions(pitchBook));

	const kpiValues = kpiData[kpi.toUpperCase()] || [];
	const [selectedIndex, setSelectedIndex] = useState(0);
	const [currentPage, setCurrentPage] = useState(kpiValues[0]?.page || 1);
	const [showConfirmDialog, setShowConfirmDialog] = useState(false);
	const [hasChanges, setHasChanges] = useState(false);
	const [customValue, setCustomValue] = useState("");
	const [customPage, setCustomPage] = useState("");
	const [editingCustomPage, setEditingCustomPage] = useState(false);

	const originalValue = kpiValues[0]?.entity || "";
	const originalPage = kpiValues[0]?.page || 0;

	// Funktion, um gleiche Werte zusammenzufassen und die Seiten zu sammeln
	function groupKpiValues(values: Array<{ entity: string; page: number; [key: string]: any }>): Array<{ entity: string; pages: number[]; [key: string]: any }> {
		const map = new Map<string, { entity: string; pages: number[]; [key: string]: any }>();
		values.forEach((item: { entity: string; page: number; [key: string]: any }) => {
			const key = item.entity.toLowerCase();
			if (!map.has(key)) {
				map.set(key, { ...item, pages: [item.page] });
			} else {
				const existingEntry = map.get(key)!;
				if (!existingEntry.pages.includes(item.page)) {
					existingEntry.pages.push(item.page);
				}
			}
		});
		return Array.from(map.values());
	}

	const groupedKpiValues: Array<{ entity: string; pages: number[]; [key: string]: any }> = groupKpiValues(kpiValues);

	const selectedValue: string =
		selectedIndex === -1 ? customValue : groupedKpiValues[selectedIndex]?.entity || "";
	
	const selectedPage =
		selectedIndex === -1
			? (parseInt(customPage) > 0 ? parseInt(customPage) : 1)
			: groupedKpiValues[selectedIndex]?.pages[0] || 1;

	// Um zu prüfen, ob der Wert nur aus Leerzeichen besteht
	const isSelectedValueEmpty = selectedIndex === -1 ? customValue.trim() === "" : !selectedValue;

	useEffect(() => {
		const valueChanged = selectedValue !== originalValue;
		const pageChanged = selectedPage !== originalPage;
		setHasChanges(valueChanged || pageChanged);
	}, [selectedValue, selectedPage, originalValue, originalPage]);

	const { mutate: updateKPI } = useMutation({
		mutationFn: () => {
			const updatedData = { ...kpiData };
			let baseObject;
			if (selectedIndex >= 0) {
				// Das Originalobjekt mit allen Feldern für diesen Wert suchen
				const original = kpiValues.find(v => v.entity.toLowerCase() === groupedKpiValues[selectedIndex].entity.toLowerCase()) as { status?: string; source?: string } | undefined;
				baseObject = {
					label: kpi.toUpperCase(),
					entity: groupedKpiValues[selectedIndex].entity,
					page: groupedKpiValues[selectedIndex].pages[0],
					status: original?.status || "single-source",
					source: original?.source || "auto",
				};
			} else {
				baseObject = {
					label: kpi.toUpperCase(),
					entity: selectedValue,
					page: selectedPage,
					status: "single-source",
					source: "manual",
				};
			}
			updatedData[kpi.toUpperCase()] = [
				{
					...baseObject,
					entity: selectedValue,
					page: selectedPage,
				},
			];
			return fetchPutKPI(Number(pitchBook), updatedData);
		},
		onSuccess: () => {
			queryClient.invalidateQueries({
				queryKey: ["pitchBookKPI", pitchBook],
			});
			navigate({
				to: "/extractedResult/$pitchBook",
				params: { pitchBook },
				search: from ? { from } : undefined
			});
		},
		onError: (error) => {
			console.error("Error updating KPI:", error);
		},
	});

	const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
		const value = event.target.value;
		if (value === "custom") {
			setSelectedIndex(-1);
		} else {
			const index = Number.parseInt(value);
			setSelectedIndex(index);
			setCurrentPage(groupedKpiValues[index].pages[0]);
			setCustomValue("");
			setCustomPage("");
		}
	};

	const handleCustomValueChange = (
		event: React.ChangeEvent<HTMLInputElement>,
	) => {
		const value = event.target.value;
		setCustomValue(value);
		setSelectedIndex(-1);
	};

	const handleCustomPageChange = (
		event: React.ChangeEvent<HTMLInputElement>,
	) => {
		const value = event.target.value;
		// Allow empty string or positive numbers only (no 0)
		if (value === '' || (/^\d+$/.test(value) && parseInt(value) > 0)) {
			setCustomPage(value);
		}
	};

	const handleRowClick = (index: number) => {
		setCurrentPage(groupedKpiValues[index].pages[0]);
		setSelectedIndex(index);
		setCustomValue("");
		setCustomPage("");
	};

	const handleBackClick = () => {
		if (hasChanges) {
			setShowConfirmDialog(true);
		} else {
			navigate({
				to: "/extractedResult/$pitchBook",
				params: { pitchBook },
				search: from ? { from } : undefined
			});
		}
	};

	const handleConfirmDiscard = () => {
		setShowConfirmDialog(false);
		navigate({
			to: "/extractedResult/$pitchBook",
			params: { pitchBook },
			search: from ? { from } : undefined
		});
	};

	const handleCancelDiscard = () => {
		setShowConfirmDialog(false);
	};

	const handleAcceptReview = () => {
		updateKPI();
	};

	const startCustomPageEditing = () => {
		setEditingCustomPage(true);
	};

	const handleCustomPageKeyPress = (e: KeyboardEvent<HTMLInputElement>) => {
		if (e.key === "Enter" || e.key === "Escape") {
			setEditingCustomPage(false);
		}
	};

	return (
		<Box p={4}>
			<Box sx={{ display: "flex", alignItems: "center", mb: 3 }}>
				<IconButton onClick={handleBackClick} sx={{ mr: 2 }}>
					<ArrowBackIcon fontSize="large" sx={{ color: "#383838" }} />
				</IconButton>
				<Typography variant="h5" fontWeight="bold">
					Überprüfung der Kennzahl: {kpi}
				</Typography>
			</Box>

			<Box
				display="flex"
				gap={4}
				sx={{
					width: "100vw",
					maxWidth: "100%",
					height: "85vh",
					mt: 4,
				}}
			>
				<Paper
					elevation={2}
					sx={{
						width: "45%",
						maxHeight: "100%",
						height: "fit-content",
						borderRadius: 2,
						backgroundColor: "#eeeeee",
						padding: 2,
						overflow: "auto",
					}}
				>
					<TableContainer component={Paper}>
						<Table>
							<TableHead>
								<TableRow>
									<TableCell width="85%">
										<strong>Gefundene Werte</strong>
									</TableCell>
									<TableCell align="center" width="15%">
										<strong>Seiten</strong>
									</TableCell>
								</TableRow>
							</TableHead>
							<TableBody>
								{groupedKpiValues.map((item, index) => (
									<TableRow
										key={`${item.entity}_${item.pages.join('_')}_${index}`}
										sx={{
											"&:hover": { backgroundColor: "#f9f9f9" },
											cursor: "pointer",
										}}
										onClick={() => handleRowClick(index)}
									>
										<TableCell>
											<Box
												sx={{
													borderRadius: 1,
													padding: "4px 8px",
													display: "flex",
													alignItems: "center",
													width: "100%",
													cursor: "pointer",
													"&:hover": {
														borderColor: "#ccc",
													},
												}}
											>
												<Radio
													value={index.toString()}
													checked={selectedIndex === index}
													onChange={handleRadioChange}
													sx={{
														color: "#383838",
														"&.Mui-checked": { color: "#383838" },
														padding: "4px",
														marginRight: 1,
														"&:focus": {
															outline: "none",
														},
													}}
												/>
												<span>{item.entity}</span>
											</Box>
										</TableCell>
										<TableCell align="center">
											{item.pages.map((page: number, i: number) => (
												<Link
													key={page}
													component="button"
													onClick={(e: React.MouseEvent) => {
														e.stopPropagation();
														setCurrentPage(page);
													}}
													sx={{ cursor: "pointer", ml: i > 0 ? 1 : 0 }}
												>
													{page}
												</Link>
											))}
										</TableCell>
									</TableRow>
								))}

								<TableRow>
									<TableCell>
										<Box
											sx={{
												padding: "4px 8px",
												display: "flex",
												alignItems: "center",
												width: "100%",
												cursor: "pointer",
												"&:hover": {
													borderColor: "#ccc",
												},
											}}
											onClick={() => {
												setSelectedIndex(-1);
											}}
										>
											<Radio
												value="custom"
												checked={selectedIndex === -1 && customValue !== ""}
												onChange={handleRadioChange}
												sx={{
													color: "#383838",
													"&.Mui-checked": { color: "#383838" },
													padding: "4px",
													marginRight: 1,
													"&:focus": {
														outline: "none",
													},
												}}
											/>
											<Box sx={{ width: '100%' }}>
												<TextField
													placeholder="Einen abweichenden Wert eingeben..."
													value={customValue}
													onChange={handleCustomValueChange}
													variant="standard"
													fullWidth
													InputProps={{
														disableUnderline: true,
													}}
													sx={{
														"& .MuiInput-input": {
															padding: 0,
														},
													}}
													onClick={(e: React.MouseEvent) => {
														e.stopPropagation();
													}}
													error={selectedIndex === -1 && customValue !== "" && customValue.trim() === ""}
													helperText={selectedIndex === -1 && customValue !== "" && customValue.trim() === "" ? "Der Wert, der angegeben wurde, ist leer." : ""}
												/>
											</Box>
										</Box>
									</TableCell>
									<TableCell align="center">
										{editingCustomPage ? (
											<TextField
												value={customPage}
												onChange={handleCustomPageChange}
												onKeyDown={handleCustomPageKeyPress}
												onBlur={() => setEditingCustomPage(false)}
												autoFocus
												size="small"
												variant="standard"
												sx={{
													width: "60px",
													"& .MuiInput-input": {
														textAlign: "center"
													}
												}}
												inputProps={{
													min: 0,
													style: { textAlign: 'center' }
												}}
											/>
										) : (
											<Box
												sx={{
													display: "flex",
													alignItems: "center",
													justifyContent: "center",
													gap: 1,
													cursor: "pointer",
													minHeight: "24px",
													minWidth: "100px",
													margin: "0 auto",
												}}
												onClick={(e: React.MouseEvent) => {
													e.stopPropagation();
													startCustomPageEditing();
												}}
											>
												<span>{customPage || "..."}</span>
												<EditIcon
													fontSize="small"
													sx={{
														color: "black",
														opacity: 0.7,
														transition: "opacity 0.2s ease",
														ml: 1
													}}
													onClick={(e) => {
														e.stopPropagation();
														startCustomPageEditing();
													}}
												/>
											</Box>
										)}
									</TableCell>
								</TableRow>
							</TableBody>
						</Table>
					</TableContainer>
				</Paper>
				<Box
					display="flex"
					flexDirection="column"
					justifyContent="space-between"
					gap={3}
					sx={{ width: "55%", height: "95%" }}
				>
					<Paper
						elevation={2}
						sx={{
							width: "100%",
							height: "fit-content",
							maxHeight: "100%",
							borderRadius: 2,
							backgroundColor: "#eeeeee",
							display: "flex",
							flexDirection: "column",
							overflow: "auto",
							padding: 2,
						}}
					>
						<PDFViewer
							pitchBookId={pitchBook}
							currentPage={currentPage}
							onPageChange={setCurrentPage}
							highlight={groupedKpiValues
								.map((k) => k.pages.map((page: number) => ({ page, text: k.entity })))
								.reduce((acc, val) => acc.concat(val), [])}
							focusHighlight={{
								page: groupedKpiValues.at(selectedIndex)?.pages[0] || -1,
								text: groupedKpiValues.at(selectedIndex)?.entity || "",
							}}
						/>
					</Paper>
					<Box mt={2} display="flex" justifyContent="flex-end" gap={2}>
						<Button
							variant="contained"
							onClick={handleAcceptReview}
							disabled={isSelectedValueEmpty}
							sx={{
								backgroundColor: "#383838",
								"&:hover": { backgroundColor: "#2e2e2e" },
								"&.Mui-disabled": { backgroundColor: "#ccc" },
							}}
						>
							Überprüfung Annehmen
						</Button>
					</Box>
				</Box>
			</Box>

			<Dialog
				open={showConfirmDialog}
				onClose={handleCancelDiscard}
				maxWidth="sm"
				fullWidth
			>
				<DialogTitle sx={{ fontSize: "1.25rem", fontWeight: "bold" }}>
					Achtung
				</DialogTitle>
				<DialogContent>
					<DialogContentText sx={{ fontSize: "1rem" }}>
						Alle vorgenommenen Änderungen werden verworfen.
					</DialogContentText>
				</DialogContent>
				<DialogActions sx={{ p: 3, gap: 2 }}>
					<Button
						onClick={handleCancelDiscard}
						variant="outlined"
						sx={{
							color: "#666",
							borderColor: "#ddd",
							"&:hover": { backgroundColor: "#f5f5f5" },
						}}
					>
						Abbrechen
					</Button>
					<Button
						onClick={handleConfirmDiscard}
						variant="contained"
						sx={{
							backgroundColor: "#383838",
							"&:hover": { backgroundColor: "#2e2e2e" },
						}}
					>
						Bestätigen
					</Button>
				</DialogActions>
			</Dialog>
		</Box>
	);
}