import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import HourglassEmptyIcon from "@mui/icons-material/HourglassEmpty";
import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf";
import {
	Box,
	Chip,
	CircularProgress,
	LinearProgress,
	Paper,
	Table,
	TableBody,
	TableCell,
	TableContainer,
	TableHead,
	TableRow,
	Typography,
} from "@mui/material";
import { useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import { useCallback, useEffect, useState } from "react";
import { socket } from "../socket";
import { fetchPitchBooksById } from "../util/api";
import { pitchBooksQueryOptions } from "../util/query";
import { formatDate } from "../util/date"

interface PitchBook {
	id: number;
	filename: string;
	created_at: string;
	kpi?:
		| string
		| {
				[key: string]: {
					label: string;
					entity: string;
					page: number;
					status: string;
					source: string;
				}[];
		  };
	status?: "processing" | "completed";
}

export function PitchBooksTable() {
	const [loadingPitchBooks, setLoadingPitchBooks] = useState<
		{
			id: number;
			progress: number;
			filename?: string;
			created_at?: string;
			buffer: number;
			intervalId?: number;
		}[]
	>([]);
	const navigate = useNavigate();
	const { data: pitchBooks, isLoading } = useSuspenseQuery(
		pitchBooksQueryOptions(),
	);

	const handleRowClick = (pitchBookId: number) => {
		navigate({
			to: "/extractedResult/$pitchBook",
			params: { pitchBook: pitchBookId.toString() },
			search: { from: "overview" },
		});
	};

	const onConnection = useCallback(() => {
		console.log("connected");
	}, []);

	const queryClient = useQueryClient();

	const onProgress = useCallback(
		(progress: { id: number; progress: number }) => {
			if (progress.progress === 100) {
				setLoadingPitchBooks((prev) => {
					const intervalId = prev.find(
						(item) => item.id === progress.id,
					)?.intervalId;
					intervalId && clearInterval(intervalId);

					return [...prev.filter((item) => item.id !== progress.id)];
				});
				queryClient.invalidateQueries({
					queryKey: pitchBooksQueryOptions().queryKey,
				});
			} else {
				setLoadingPitchBooks((prev) => {
					const oldItem = prev.find((item) => item.id === progress.id);
					let intervalId = oldItem?.intervalId;
					if (!oldItem) {
						intervalId = setInterval(() => {
							setLoadingPitchBooks((prev) => {
								const oldItem = prev.find((item) => item.id === progress.id);
								if (!oldItem) return prev;

								return [
									...prev.filter((e) => e.id !== progress.id),
									{
										id: progress.id,
										progress: oldItem?.progress ?? progress.progress,
										filename: oldItem?.filename,
										buffer: oldItem ? oldItem.buffer + 0.5 : 0,
										intervalId: oldItem.intervalId,
										created_at: oldItem?.created_at,
									},
								];
							});
						}, 400);

						fetchPitchBooksById(progress.id)
							.then((res) => {
								setLoadingPitchBooks((prev) => [
									...prev.filter((item) => item.id !== progress.id),
									{
										id: progress.id,
										progress: progress.progress,
										filename: res.filename,
										buffer: 0,
										intervalId,
										created_at: res.created_at,
									},
								]);
							})
							.catch((err) => {
								console.error(err);
							});
					}
					return [
						...prev.filter((item) => item.id !== progress.id),
						{
							id: progress.id,
							progress: progress.progress,
							filename: oldItem?.filename,
							created_at: oldItem?.created_at,
							buffer: 0,
							intervalId,
						},
					];
				});
			}
		},
		[queryClient],
	);

	useEffect(() => {
		socket.on("connect", onConnection);
		socket.on("progress", onProgress);
		return () => {
			socket.off("connect", onConnection);
			socket.off("progress", onProgress);
		};
	}, [onConnection, onProgress]);

	const getKPIValue = (pitchBook: PitchBook, fieldName: string): string => {
		if (!pitchBook.kpi || typeof pitchBook.kpi === "string") {
			try {
				const parsedKPI = JSON.parse(pitchBook.kpi as string);
				// Convert array to object format if needed
				const kpiObj = Array.isArray(parsedKPI)
					? parsedKPI.reduce((acc, item) => {
							if (!acc[item.label]) acc[item.label] = [];
							acc[item.label].push(item);
							return acc;
						}, {})
					: parsedKPI;

				return kpiObj[fieldName]?.[0]?.entity || "N/A";
			} catch {
				return "N/A";
			}
		}

		return pitchBook.kpi[fieldName]?.[0]?.entity || "N/A";
	};

	const getStatus = (pitchBook: PitchBook) => {
		if (
			pitchBook.kpi &&
			((typeof pitchBook.kpi === "string" && pitchBook.kpi !== "{}") ||
				(typeof pitchBook.kpi === "object" &&
					Object.keys(pitchBook.kpi).length > 0))
		) {
			return "completed";
		}
		return "processing";
	};

	if (isLoading) {
		return (
			<Box
				display="flex"
				justifyContent="center"
				alignItems="center"
				height="400px"
			>
				<CircularProgress sx={{ color: "#383838" }} />
			</Box>
		);
	}

	return (
		<TableContainer
			component={Paper}
			sx={{
				width: "85%",
				maxWidth: 1200,
				boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
			}}
		>
			<Table>
				<TableHead>
					<TableRow sx={{ backgroundColor: "#f5f5f5" }}>
						<TableCell sx={{ width: "60px" }} />
						<TableCell sx={{ fontWeight: "bold" }}>Fondsname</TableCell>
						<TableCell sx={{ fontWeight: "bold" }}>Fondsmanager</TableCell>
						<TableCell sx={{ fontWeight: "bold" }}>Hochgeladen am</TableCell>
						<TableCell sx={{ fontWeight: "bold" }}>Dateiname</TableCell>
						<TableCell sx={{ fontWeight: "bold", width: "120px" }}>
							Status
						</TableCell>
					</TableRow>
				</TableHead>
				<TableBody>
				{loadingPitchBooks
					.sort((a, b) => a.id - b.id)
					.map((pitchBook) => (
						<TableRow key={pitchBook.id}>
							<TableCell>
								<Box
									sx={{
										width: 40,
										height: 50,
										backgroundColor: "#f0f0f0",
										borderRadius: 1,
										display: "flex",
										alignItems: "center",
										justifyContent: "center",
										border: "1px solid #e0e0e0",
									}}
								>
									<PictureAsPdfIcon fontSize="small" sx={{ color: "#666" }} />
								</Box>
							</TableCell>
							<TableCell colSpan={2}>
								<LinearProgress
									variant="buffer"
									value={pitchBook.progress}
									valueBuffer={
										pitchBook.buffer
											? pitchBook.progress + pitchBook.buffer
											: pitchBook.progress
									}
								/>
							</TableCell>
							<TableCell>
								<Typography
									variant="body2"
									color="text.secondary"
									fontSize="0.875rem"
								>
									{pitchBook.created_at && formatDate(pitchBook.created_at)}
								</Typography>
							</TableCell>
							<TableCell>
								<Typography
									variant="body2"
									color="text.secondary"
									fontSize="0.875rem"
								>
									{pitchBook.filename}
								</Typography>
							</TableCell>
							<TableCell>
								<Chip
									icon={<HourglassEmptyIcon />}
									label="In Bearbeitung"
									size="small"
									sx={{
										backgroundColor: "#fff3e0",
										color: "#e65100",
										"& .MuiChip-icon": {
											color: "#e65100",
										},
									}}
								/>
							</TableCell>
						</TableRow>
					))}
					{pitchBooks
						.filter(
							(pitchbook: PitchBook) =>
								!loadingPitchBooks.some((e) => e.id === pitchbook.id),
						)
						.sort(
							(a: PitchBook, b: PitchBook) =>
								new Date(b.created_at).getTime() -
								new Date(a.created_at).getTime(),
						)
						.map((pitchBook: PitchBook) => {
							const status = getStatus(pitchBook);
							const fundName =
								getKPIValue(pitchBook, "FONDSNAME") ||
								getKPIValue(pitchBook, "FUND_NAME") ||
								getKPIValue(pitchBook, "NAME");

							const manager =
								getKPIValue(pitchBook, "FONDSMANAGER") ||
								getKPIValue(pitchBook, "MANAGER") ||
								getKPIValue(pitchBook, "PORTFOLIO_MANAGER");

							return (
								<TableRow
									key={pitchBook.id}
									onClick={() => handleRowClick(pitchBook.id)}
									sx={{
										cursor: "pointer",
										"&:hover": {
											backgroundColor: "#f9f9f9",
										},
									}}
								>
									<TableCell>
										<Box
											sx={{
												width: 40,
												height: 50,
												backgroundColor: "#f0f0f0",
												borderRadius: 1,
												display: "flex",
												alignItems: "center",
												justifyContent: "center",
												border: "1px solid #e0e0e0",
											}}
										>
											<PictureAsPdfIcon
												fontSize="small"
												sx={{ color: "#666" }}
											/>
										</Box>
									</TableCell>
									<TableCell>
										<Typography variant="body2" fontWeight="medium">
											{fundName}
										</Typography>
									</TableCell>
									<TableCell>{manager}</TableCell>
                  <TableCell>{formatDate(pitchBook.created_at)}</TableCell>
									<TableCell>
										<Typography
											variant="body2"
											color="text.secondary"
											fontSize="0.875rem"
										>
											{pitchBook.filename}
										</Typography>
									</TableCell>
									<TableCell>
										{status === "completed" ? (
											<Chip
												icon={<CheckCircleIcon />}
												label="Extraktion Abgeschlossen"
												size="small"
												sx={{
													backgroundColor: "#e8f5e9",
													color: "#2e7d32",
													"& .MuiChip-icon": {
														color: "#2e7d32",
													},
												}}
											/>
										) : (
											<Chip
												icon={<HourglassEmptyIcon />}
												label="In Bearbeitung"
												size="small"
												sx={{
													backgroundColor: "#fff3e0",
													color: "#e65100",
													"& .MuiChip-icon": {
														color: "#e65100",
													},
												}}
											/>
										)}
									</TableCell>
								</TableRow>
							);
						})}
				</TableBody>
			</Table>
			{pitchBooks.length === 0 && (
				<Box p={4} textAlign="center">
					<Typography color="text.secondary">
						Keine Pitch Books vorhanden
					</Typography>
				</Box>
			)}
		</TableContainer>
	);
}
