import { useParams } from "react-router-dom";
import { useSceneContext } from "../../../../modules/scene/sceneContext";
import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
import { LayeringBottomIcon, LayeringTopIcon } from "../../../icons/ExportCommonIcons";
import { useSocketStore } from "../../../../store/builder/store";
import InputRange from "../../../ui/inputs/InputRange";

import { getUserData } from "../../../../functions/getUserData";
import { upsertWallApi } from "../../../../services/factoryBuilder/wall/upsertWallApi";
import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsertFloorApi";

const SelectedDecalProperties = () => {
    const { selectedDecal, setSelectedDecal } = useBuilderStore();
    const { wallStore, floorStore, versionStore } = useSceneContext();
    const { updateDecal: updateDecalInWall } = wallStore();
    const { updateDecal: updateDecalInFloor } = floorStore();
    const { userId, organization } = getUserData();
    const { selectedVersion } = versionStore();
    const { projectId } = useParams();
    const { socket } = useSocketStore();

    const updateBackend = (updatedData: Wall | Floor) => {
        if ('wallUuid' in updatedData) {
            if (projectId && updatedData) {
                if (!socket?.connected) {
                    // API

                    upsertWallApi(projectId, selectedVersion?.versionId || '', updatedData);
                } else {

                    // SOCKET 

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

                    socket.emit('v1:model-Wall:add', data);
                }
            }
        } else if ('floorUuid' in updatedData) {
            if (projectId && updatedData) {
                if (!socket?.connected) {
                    // API

                    upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedData);
                } else {

                    // SOCKET

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

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

    const handleRotationChange = (value: number) => {
        if (!selectedDecal) return;
        const updatedDecal = { ...selectedDecal.decalData, decalRotation: value };
        setSelectedDecal({ ...selectedDecal, decalData: updatedDecal });

        if ('wallUuid' in selectedDecal.decalData.decalType) {
            const updatedWall = updateDecalInWall(updatedDecal.decalUuid, updatedDecal);
            if (updatedWall) updateBackend(updatedWall);
        } else if ('floorUuid' in selectedDecal.decalData.decalType) {
            const updatedFloor = updateDecalInFloor(updatedDecal.decalUuid, updatedDecal);
            if (updatedFloor) updateBackend(updatedFloor);
        }
    }

    const handleScaleChange = (value: number) => {
        if (!selectedDecal) return;
        const updatedDecal = { ...selectedDecal.decalData, decalScale: value };
        setSelectedDecal({ ...selectedDecal, decalData: updatedDecal });

        if ('wallUuid' in selectedDecal.decalData.decalType) {
            const updatedWall = updateDecalInWall(updatedDecal.decalUuid, updatedDecal);
            if (updatedWall) updateBackend(updatedWall);
        } else if ('floorUuid' in selectedDecal.decalData.decalType) {
            const updatedFloor = updateDecalInFloor(updatedDecal.decalUuid, updatedDecal);
            if (updatedFloor) updateBackend(updatedFloor);
        }
    }

    const handleOpacityChange = (value: number) => {
        if (!selectedDecal) return;
        const updatedDecal = { ...selectedDecal.decalData, decalOpacity: value };
        setSelectedDecal({ ...selectedDecal, decalData: updatedDecal });

        if ('wallUuid' in selectedDecal.decalData.decalType) {
            const updatedWall = updateDecalInWall(updatedDecal.decalUuid, updatedDecal);
            if (updatedWall) updateBackend(updatedWall);
        } else if ('floorUuid' in selectedDecal.decalData.decalType) {
            const updatedFloor = updateDecalInFloor(updatedDecal.decalUuid, updatedDecal);
            if (updatedFloor) updateBackend(updatedFloor);
        }
    }

    const handleLayerChange = (direction: "up" | "down") => {
        if (!selectedDecal) return;

        const position: [number, number, number] = [...(selectedDecal.decalData.decalPosition || [0, 0, 0]),];

        if (direction === "up") {
            position[2] = Math.abs(position[2]);
        } else {
            position[2] = -Math.abs(position[2]);
        }

        const updatedDecal: Decal = { ...selectedDecal.decalData, decalPosition: position, };

        setSelectedDecal({ ...selectedDecal, decalData: updatedDecal });

        if ("wallUuid" in selectedDecal.decalData.decalType) {
            const updatedWall = updateDecalInWall(updatedDecal.decalUuid, updatedDecal);
            if (updatedWall) updateBackend(updatedWall);
        } else if ("floorUuid" in selectedDecal.decalData.decalType) {
            const updatedFloor = updateDecalInFloor(updatedDecal.decalUuid, updatedDecal);
            if (updatedFloor) updateBackend(updatedFloor);
        }
    };

    if (!selectedDecal) return null;

    return (
        <div className="decal-transformation-container">
            <div className="header">Decal Properties</div>
            <section>
                <InputRange
                    label="Rotation"
                    value={selectedDecal.decalData.decalRotation || 0}
                    min={0}
                    max={360}
                    step={1}
                    onChange={(value: number) => handleRotationChange(value)}
                />

                <InputRange
                    label="Scale"
                    value={selectedDecal.decalData.decalScale || 1}
                    min={0.1}
                    max={2}
                    step={0.1}
                    onChange={(value: number) => handleScaleChange(value)}
                />
            </section>

            <section>
                <InputRange
                    label="Opacity"
                    value={selectedDecal.decalData.decalOpacity || 1}
                    min={0.1}
                    step={0.1}
                    max={1}
                    onChange={(value: number) => handleOpacityChange(value)}
                />

                <div className="transformation-wrapper opacity">
                    <div className="transformation-header">Layering</div>

                    <div className="layers-list">
                        <button
                            className="layer-move-btn"
                            onClick={() => handleLayerChange("down")}
                        >
                            <LayeringBottomIcon />
                        </button>
                        <button
                            className="layer-move-btn"
                            onClick={() => handleLayerChange("up")}
                        >
                            <LayeringTopIcon />
                        </button>
                    </div>
                </div>
            </section>
        </div>
    );
};

export default SelectedDecalProperties;
