import { useParams } from "react-router-dom";
import { getUserData } from "../../../../../functions/getUserData";
import { useVersionContext } from "../../../../builder/version/versionContext";
import { useSceneContext } from "../../../sceneContext";
import { useSocketStore } from "../../../../../store/builder/store";

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

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

// 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, wallStore, floorStore, zoneStore, aisleStore } = useSceneContext();
    const { undo2D, peekUndo2D } = undoRedo2DStore();
    const { addWall, removeWall, updateWall } = wallStore();
    const { addFloor, removeFloor, updateFloor } = floorStore();
    const { addZone, removeZone, updateZone } = zoneStore();
    const { addAisle, removeAisle, updateAisle } = aisleStore();
    const { selectedVersionStore } = useVersionContext();
    const { selectedVersion } = selectedVersionStore();
    const { userId, organization } = getUserData();
    const { projectId } = useParams();
    const { socket } = 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) => {
        addWall(wallData);
        if (projectId) {
            // API

            // upsertWallApi(projectId, selectedVersion?.versionId || '', wallData);

            // SOCKET

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

            socket.emit('v1:model-Wall:add', data);
        }
    };

    const removeWallToBackend = (wallUuid: string) => {
        removeWall(wallUuid);
        if (projectId) {
            // API

            // deleteWallApi(projectId, selectedVersion?.versionId || '', wallUuid);

            // SOCKET

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

            socket.emit('v1:model-Wall:delete', data);
        }
    };

    const updateWallToBackend = (wallUuid: string, updatedData: Wall) => {
        updateWall(wallUuid, updatedData);
        if (projectId) {
            // API

            // upsertWallApi(projectId, selectedVersion?.versionId || '', updatedData);

            // SOCKET

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

            socket.emit('v1:model-Wall:add', data);
        }
    };

    const createFloorToBackend = (floorData: Floor) => {
        addFloor(floorData);
        if (projectId) {
            // API

            // upsertFloorApi(projectId, selectedVersion?.versionId || '', floorData);

            // SOCKET

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

            socket.emit('v1:model-Floor:add', data);
        }
    };

    const removeFloorToBackend = (floorUuid: string) => {
        removeFloor(floorUuid);
        if (projectId) {
            // API

            // deleteFloorApi(projectId, selectedVersion?.versionId || '', floorUuid);

            // SOCKET

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

            socket.emit('v1:model-Floor:delete', data);
        }
    };

    const updateFloorToBackend = (floorUuid: string, updatedData: Floor) => {
        updateFloor(floorUuid, updatedData);
        if (projectId) {
            // API

            // upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedData);

            // SOCKET

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

            socket.emit('v1:model-Floor:add', data);
        }
    };

    const createZoneToBackend = (zoneData: Zone) => {
        addZone(zoneData);
        if (projectId) {
            // API

            // upsertZoneApi(projectId, selectedVersion?.versionId || '', zoneData);

            // SOCKET

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

            socket.emit('v1:zone:add', data);
        }
    };

    const removeZoneToBackend = (zoneUuid: string) => {
        removeZone(zoneUuid);
        if (projectId) {
            // API

            // deleteZoneApi(projectId, selectedVersion?.versionId || '', zoneUuid);

            // SOCKET

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

            socket.emit('v1:zone:delete', data);
        }
    };

    const updateZoneToBackend = (zoneUuid: string, updatedData: Zone) => {
        updateZone(zoneUuid, updatedData);
        if (projectId) {
            // API

            // upsertZoneApi(projectId, selectedVersion?.versionId || '', updatedData);

            // SOCKET

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

            socket.emit('v1:zone:add', data);
        }
    };

    const createAisleToBackend = (aisleData: Aisle) => {
        addAisle(aisleData);
        if (projectId) {
            // API

            // upsertAisleApi(projectId, selectedVersion?.versionId || '', aisleData);

            // SOCKET

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

            socket.emit('v1:model-aisle:add', data);
        }
    };

    const removeAisleToBackend = (aisleUuid: string) => {
        removeAisle(aisleUuid);
        if (projectId) {
            // API

            // deleteAisleApi(projectId, selectedVersion?.versionId || '', aisleUuid);

            // SOCKET

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

            socket.emit('v1:model-aisle:delete', data);
        }
    };

    const updateAisleToBackend = (aisleUuid: string, updatedData: Aisle) => {
        updateAisle(aisleUuid, updatedData);
        if (projectId) {
            // API

            // upsertAisleApi(projectId, selectedVersion?.versionId || '', updatedData);

            // SOCKET

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

            socket.emit('v1:model-aisle:add', data);
        }
    };

    return { handleUndo };
}

export default use2DUndoHandler;