import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { FadeLoader } from "react-spinners";
import { io } from "socket.io-client";
import CityMap from "../components/CityMap";
import Header from "../components/Header";
import Sidebar from "../components/Sidebar";
import API_URL from "../config";
import "../styles/dashboard.css";
import type { ErrorResponse } from "../types/error";
import type { AuthorizedUser } from "../types/login";
import type { Robot, RobotsResponse } from "../types/robot";

function Dashboard() {
    const [errorMessage, setErrorMessage] = useState<string>("");
    const [isLoading, setIsLoading] = useState<boolean>(true);
    const [isSimulationActive, setIsSimulationActive] =
        useState<boolean>(false);
    const [robots, setRobots] = useState<Robot[]>([]);

    const navigate = useNavigate();

    const userString = localStorage.getItem("user");
    const user: AuthorizedUser = userString ? JSON.parse(userString) : null;
    const token = localStorage.getItem("token-robot-tracker");

    async function handleLogout() {
        localStorage.removeItem("token-robot-tracker");
        localStorage.removeItem("user");
        // setIsSimulationActive(false);
        navigate("/login", { replace: true });
    }

    // Request robot data from backend on component mount
    useEffect(() => {
	// Additional safety check to protect this page from unauthorized access
        if (!token || token === "undefined" || token === "null") {
            navigate("/login");
            return;
        }

        async function fetchRobots() {
            try {
                setIsLoading(true);

                const response = await fetch(`${API_URL}/robots`, {
                    method: "GET",
                    headers: {
                        Authorization: `Bearer ${token}`,
                        "Content-Type": "application/json",
                    },
                });

                if (!response.ok) {
                    const errorData: ErrorResponse = await response.json();
                    throw new Error(
                        errorData.message ||
                            `Failed to load the robots: ${response.status}`
                    );
                }

                const data: RobotsResponse = await response.json();
                
                setRobots(data.robots);
                setIsSimulationActive(data.simulationRunning);
            } catch (error) {
                console.error("Failed to load the robots:", error);

                if (error instanceof Error) {
                    setErrorMessage(error.message);
                } else {
                    setErrorMessage("An unexpected error occurred.");
                }
            } finally {
                setIsLoading(false);
            }
        }

        fetchRobots();

        // Establish WebSocket connection to backend
        const socket = io(API_URL);

        // Listen for real-time robot updates
        socket.on("robots_update", ({ updatedRobots }) => {
            setRobots(updatedRobots);
        });

        // Cleanup when component unmounts
        return () => {
            socket.disconnect();
        };
    }, [token, navigate]);

    return isLoading ? (
        <FadeLoader />
    ) : (
        <div className="dashboard-page">
            <Header user={user} logout={handleLogout} />
            <CityMap robots={robots} />
            <Sidebar
                activeSimulation={isSimulationActive}
                errorMessage={errorMessage}
                robots={robots}
                token={token}
                setActiveSimulation={setIsSimulationActive}
                setErrorMessage={setErrorMessage}
                setRobots={setRobots}
            />
        </div>
    );
}

export default Dashboard;

