import { useParams } from "react-router-dom";
import { getUserData } from "../../../../../functions/getUserData";
import { useSceneContext } from "../../../sceneContext";
import { useSocketStore } from "../../../../../store/socket/useSocketStore";
import useWallResponseHandler from "../../../../collaboration/responseHandler/useWallResponseHandler";

import { upsertWallApi } from "../../../../../services/factoryBuilder/wall/upsertWallApi";
import { deleteWallApi } from "../../../../../services/factoryBuilder/wall/deleteWallApi";

import { upsertZoneApi } from "../../../../../services/factoryBuilder/zone/upsertZoneApi";
import { deleteZoneApi } from "../../../../../services/factoryBuilder/zone/deleteZoneApi";

import { upsertFloorApi } from "../../../../../services/factoryBuilder/floor/upsertFloorApi";
import { deleteFloorApi } from "../../../../../services/factoryBuilder/floor/deleteFloorApi";

import { upsertAisleApi } from "../../../../../services/factoryBuilder/aisle/upsertAisleApi";
import { deleteAisleApi } from "../../../../../services/factoryBuilder/aisle/deleteAisleApi";

function use2DUndoHandler() {
    const { undoRedo2DStore, floorStore, zoneStore, aisleStore, versionStore } = useSceneContext();
    const { undo2D, peekUndo2D } = undoRedo2DStore();
    const { addWallToScene, removeWallFromScene, updateWallInScene } = useWallResponseHandler();
    const { addFloor, removeFloor, updateFloor } = floorStore();
    const { addZone, removeZone, updateZone } = zoneStore();
    const { addAisle, removeAisle, updateAisle } = aisleStore();
    const { selectedVersion } = versionStore();
    const { userId, organization } = getUserData();
    const { projectId } = useParams();
    const { builderSocket } = useSocketStore();

    const handleUndo = () => {
        const unDoData = peekUndo2D();
        if (!unDoData) return;

        if (unDoData.type === "Draw") {
            const { actions } = unDoData;

            actions.forEach((action) => {
                const { actionType } = action;

                if ("point" in action) {
                    const point = action.point;

                    if (actionType === "Line-Create") {
                        handleRemove(point);
                    } else if (actionType === "Line-Update") {
                        handleUpdate(point);
                    } else if (actionType === "Line-Delete") {
                        handleCreate(point);
                    }
                } else if ("points" in action) {
                    const points = action.points;

                    if (actionType === "Lines-Create") {
                        points.forEach(handleRemove);
                    } else if (actionType === "Lines-Update") {
                        points.forEach(handleUpdate);
                    } else if (actionType === "Lines-Delete") {
                        points.forEach(handleCreate);
                    }
                }
            });
        } else if (unDoData.type === "UI") {
            // Handle UI actions if needed
        }

        undo2D();
    };

    const handleCreate = (point: UndoRedo2DDataTypeSchema) => {
        switch (point.type) {
            case "Wall":
                createWallToBackend(point.lineData);
                break;
            case "Floor":
                createFloorToBackend(point.lineData);
                break;
            case "Zone":
                createZoneToBackend(point.lineData);
                break;
            case "Aisle":
                createAisleToBackend(point.lineData);
                break;
        }
    };

    const handleRemove = (point: UndoRedo2DDataTypeSchema) => {
        switch (point.type) {
            case "Wall":
                removeWallToBackend(point.lineData.wallUuid);
                break;
            case "Floor":
                removeFloorToBackend(point.lineData.floorUuid);
                break;
            case "Zone":
                removeZoneToBackend(point.lineData.zoneUuid);
                break;
            case "Aisle":
                removeAisleToBackend(point.lineData.aisleUuid);
                break;
        }
    };

    const handleUpdate = (point: UndoRedo2DDataTypeSchema) => {
        switch (point.type) {
            case "Wall":
                updateWallToBackend(point.lineData.wallUuid, point.lineData);
                break;
            case "Floor":
                updateFloorToBackend(point.lineData.floorUuid, point.lineData);
                break;
            case "Zone":
                updateZoneToBackend(point.lineData.zoneUuid, point.lineData);
                break;
            case "Aisle":
                updateAisleToBackend(point.lineData.aisleUuid, point.lineData);
                break;
        }
    };

    const createWallToBackend = (wallData: Wall) => {
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                upsertWallApi(projectId, selectedVersion?.versionId || "", wallData)
                    .then((data) => {
                        if (!data.message || !data.data) {
                            echo.error(`Error adding wall`);
                            return;
                        }
                        if (data.message === "Wall Created Successfully") {
                            addWallToScene(wallData, () => {
                                echo.log(`Added wall: ${wallData.wallUuid}`);
                            });
                        } else {
                            echo.error(`Error adding wall: ${wallData.wallUuid}`);
                        }
                    })
                    .catch(() => {
                        echo.error(`Error adding wall: ${wallData.wallUuid}`);
                    });
            } else {
                // SOCKET

                const data = {
                    wallData: wallData,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId: userId,
                    organization: organization,
                };

                builderSocket.emit("v1:model-Wall:add", data);
                console.log('data: ', data);
            }
        }
    };

    const removeWallToBackend = (wallUuid: string) => {
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                deleteWallApi(projectId, selectedVersion?.versionId || "", wallUuid)
                    .then((data) => {
                        if (!data.message || !data.data) {
                            echo.error(`Error removing wall`);
                            return;
                        }
                        if (data.message === "Wall Deleted Successfully") {
                            removeWallFromScene(wallUuid, () => {
                                echo.log(`Removed wall: ${wallUuid}`);
                            });
                        } else {
                            echo.error(`Error removing wall: ${wallUuid}`);
                        }
                    })
                    .catch(() => {
                        echo.error(`Error removing wall: ${wallUuid}`);
                    });
            } else {
                // SOCKET

                const data = {
                    wallUuid: wallUuid,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId: userId,
                    organization: organization,
                };

                builderSocket.emit("v1:model-Wall:delete", data);
            }
        }
    };

    const updateWallToBackend = (wallUuid: string, updatedData: Wall) => {
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                upsertWallApi(projectId, selectedVersion?.versionId || "", updatedData)
                    .then((data) => {
                        if (!data.message || !data.data) {
                            echo.error(`Error updating wall`);
                            return;
                        }
                        if (data.message === "Wall Updated Successfully") {
                            updateWallInScene(updatedData, () => {
                                echo.log(`Updated wall: ${updatedData.wallUuid}`);
                            });
                        }
                    })
                    .catch(() => {
                        echo.error(`Error updating wall: ${updatedData.wallUuid}`);
                    });
            } else {
                // SOCKET

                const data = {
                    wallData: updatedData,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId: userId,
                    organization: organization,
                };

                builderSocket.emit("v1:model-Wall:add", data);
            }
        }
    };

    const createFloorToBackend = (floorData: Floor) => {
        addFloor(floorData);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                upsertFloorApi(projectId, selectedVersion?.versionId || "", floorData);
            } else {
                // SOCKET

                const data = {
                    floorData: floorData,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId: userId,
                    organization: organization,
                };

                builderSocket.emit("v1:model-Floor:add", data);
            }
        }
    };

    const removeFloorToBackend = (floorUuid: string) => {
        removeFloor(floorUuid);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                deleteFloorApi(projectId, selectedVersion?.versionId || "", floorUuid);
            } else {
                // SOCKET

                const data = {
                    floorUuid: floorUuid,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId: userId,
                    organization: organization,
                };

                builderSocket.emit("v1:model-Floor:delete", data);
            }
        }
    };

    const updateFloorToBackend = (floorUuid: string, updatedData: Floor) => {
        updateFloor(floorUuid, updatedData);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                upsertFloorApi(projectId, selectedVersion?.versionId || "", updatedData);
            } else {
                // SOCKET

                const data = {
                    floorData: updatedData,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId: userId,
                    organization: organization,
                };

                builderSocket.emit("v1:model-Floor:add", data);
            }
        }
    };

    const createZoneToBackend = (zoneData: Zone) => {
        addZone(zoneData);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                upsertZoneApi(projectId, selectedVersion?.versionId || "", zoneData);
            } else {
                // SOCKET

                const data = {
                    zoneData: zoneData,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId: userId,
                    organization: organization,
                };

                builderSocket.emit("v1:zone:add", data);
            }
        }
    };

    const removeZoneToBackend = (zoneUuid: string) => {
        removeZone(zoneUuid);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                deleteZoneApi(projectId, selectedVersion?.versionId || "", zoneUuid);
            } else {
                // SOCKET

                const data = {
                    zoneUuid,
                    projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId,
                    organization,
                };

                builderSocket.emit("v1:zone:delete", data);
            }
        }
    };

    const updateZoneToBackend = (zoneUuid: string, updatedData: Zone) => {
        updateZone(zoneUuid, updatedData);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                upsertZoneApi(projectId, selectedVersion?.versionId || "", updatedData);
            } else {
                // SOCKET

                const data = {
                    zoneData: updatedData,
                    projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId,
                    organization,
                };

                builderSocket.emit("v1:zone:add", data);
            }
        }
    };

    const createAisleToBackend = (aisleData: Aisle) => {
        addAisle(aisleData);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                upsertAisleApi(aisleData.aisleUuid, aisleData.points, aisleData.type, projectId, selectedVersion?.versionId || "");
            } else {
                // SOCKET

                const data = {
                    ...aisleData,
                    projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId,
                    organization,
                };

                builderSocket.emit("v1:model-aisle:add", data);
            }
        }
    };

    const removeAisleToBackend = (aisleUuid: string) => {
        removeAisle(aisleUuid);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                deleteAisleApi(projectId, selectedVersion?.versionId || "", aisleUuid);
            } else {
                // SOCKET

                const data = {
                    aisleUuid,
                    projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId,
                    organization,
                };

                builderSocket.emit("v1:model-aisle:delete", data);
            }
        }
    };

    const updateAisleToBackend = (aisleUuid: string, updatedData: Aisle) => {
        updateAisle(aisleUuid, updatedData);
        if (projectId) {
            if (!builderSocket?.connected) {
                // API

                upsertAisleApi(updatedData.aisleUuid, updatedData.points, updatedData.type, projectId, selectedVersion?.versionId || "");
            } else {
                // SOCKET

                const data = {
                    ...updatedData,
                    projectId,
                    versionId: selectedVersion?.versionId || "",
                    userId,
                    organization,
                };

                builderSocket.emit("v1:model-aisle:add", data);
            }
        }
    };

    return { handleUndo };
}

export default use2DUndoHandler;
