import {
    useState,
    type Dispatch,
    type MouseEvent,
    type SetStateAction,
} from "react";
import type { ErrorResponse } from "../types/error";
import type { Robot, SimulationResponse } from "../types/robot";

type ExpandedRobotsState = Record<number, boolean>;

type Props = {
    apiUrl: string;
    robots: Robot[];
    token: string | null;
    setErrorMessage: Dispatch<SetStateAction<string>>;
};

function RobotList({ apiUrl, robots, token, setErrorMessage }: Props) {
    const [expandedRobots, setExpandedRobots] = useState<ExpandedRobotsState>(
        {}
    );

    function toggleRobotHistory(robotId: number) {
        setExpandedRobots((prev) => ({
            ...prev,
            [robotId]: !prev[robotId],
        }));
    }

    // Move or stop individual robot
    async function controlSingleRobot(
        event: MouseEvent<HTMLButtonElement>,
        robotId: number,
        robotStatus: Robot["status"]
    ) {
        const isRobotMoving = robotStatus === "moving";
        const button = event.currentTarget;
        button.disabled = true; // prevent spamming

        try {
            // Make button clickable again after 1 second
            setTimeout(() => {
                button.disabled = false;
            }, 1000);

            const response = await fetch(
                `${apiUrl}/robots/${robotId}/${
                    isRobotMoving ? "stop" : "move"
                }`,
                {
                    method: "POST",
                    headers: {
                        Authorization: `Bearer ${token}`,
                        "Content-Type": "application/json",
                    },
                }
            );

            if (!response.ok) {
                const errorData: ErrorResponse = await response.json();
                throw new Error(
                    errorData.message ||
                        `Failed to ${
                            isRobotMoving ? "stop" : "start"
                        } robot ID ${robotId}.`
                );
            }

            const data: SimulationResponse = await response.json();
            console.log(data.message);
        } catch (error) {
            console.error(
                `Error ${
                    isRobotMoving ? "stopping" : "starting"
                } robot ID ${robotId}: `,
                error
            );

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

    return (
        <ul className="sidebar-robot-list">
            {robots?.map((robot) => {
                const isExpanded = expandedRobots[robot?.id];

                return (
                    <li key={robot?.id}>
                        <p className="robot-name">{robot?.name}</p>

                        {/* Move/stop individual robot  */}
                        <button
                            className={`btn btn-single-robot btn-${
                                robot?.status === "idle" ? "start" : "stop"
                            }`}
                            onClick={(event) =>
                                controlSingleRobot(
                                    event,
                                    robot?.id,
                                    robot?.status
                                )
                            }
                        >
                            {robot?.status === "idle" ? "MOVE" : "STOP"}
                        </button>

                        {/* Movement status  */}
                        <p>
                            Status:{" "}
                            <span className={`robot-status-${robot?.status}`}>
                                {robot?.status}
                            </span>
                        </p>

                        {/* Current position */}
                        <p className="robot-coordinates-label">Position:</p>
                        <ul className="robot-coordinates">
                            <li>Lat: {robot?.lat}</li>
                            <li>Lon: {robot?.lon}</li>
                        </ul>

                        {/* Expand position log */}
                        <button
                            className="btn btn-robot-history-toggle"
                            onClick={() => toggleRobotHistory(robot?.id)}
                            aria-expanded={isExpanded}
                        >
                            Position history
                            <span
                                className={`arrow ${isExpanded ? "open" : ""}`}
                            >
                                ▾
                            </span>
                        </button>

                        {/* Position log/history */}
                        <div
                            className={`robot-history ${
                                isExpanded ? "expanded" : ""
                            }`}
                        >
                            <ul>
                                {robot?.robot_positions?.length ? (
                                    robot?.robot_positions?.map(
                                        (pos, index) => (
                                            <li key={index}>
                                                {`Lat: ${pos?.lat}, Lon: ${pos?.lon}`}
                                            </li>
                                        )
                                    )
                                ) : (
                                    <li className="robot-history-empty">
                                        No previous positions.
                                    </li>
                                )}
                            </ul>
                        </div>
                    </li>
                );
            })}
        </ul>
    );
}

export default RobotList;

