import { useEffect, useRef } from 'react';
import { useActiveLayer, useDfxUpload, useSocketStore, useToggleView } from '../../../store/builder/store';
import { LineBasicMaterial, Line } from 'three';
import { TransformControls } from '@react-three/drei';
import { getWallPointsFromBlueprint } from './functions/getWallPointsFromBlueprint';
import { useParams } from 'react-router-dom';
import { getUserData } from '../../../functions/getUserData';
import { useVersionContext } from '../version/versionContext';
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
import { useSceneContext } from '../../scene/sceneContext';

/**
 * DxfFile component handles the rendering and manipulation of DXf file data in a 3D scene.
 * It processes the DXF data to create points and lines representing walls and allows
 * transformation controls for interactive editing.
 */
const DxfFile = () => {
    // State management hooks
    const { dfxuploaded, dfxWallGenerate, setObjValue, objValue, setDfxUploaded } = useDfxUpload();
    const { toggleView } = useToggleView();
    const { socket } = useSocketStore();
    const { selectedVersionStore } = useVersionContext();
    const { selectedVersion } = selectedVersionStore();
    const { projectId } = useParams();
    const { userId, organization } = getUserData();
    const { activeLayer } = useActiveLayer();
    const { wallThickness, wallHeight, insideMaterial, outsideMaterial, } = useBuilderStore();
    // Refs for storing line objects
    const lineRefs = useRef<Line[]>([]);
    const { wallStore } = useSceneContext();
    const { addWall, } = wallStore();
    const { walls } = wallStore();

    /**
     * Effect hook that runs when DXF wall generation is triggered.
     * Loads initial points and lines from the DXF data and updates the scene.
     */
    useEffect(() => {

        if (dfxWallGenerate) {
            dfxWallGenerate.map((wall: Wall) => {
                const data = {
                    wallData: wall,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || '',
                    userId: userId,
                    organization: organization
                }
                addWall(wall);
                socket.emit('v1:model-Wall:add', data);
                // API

                // if (projectId) {
                //     upsertWallApi(projectId, selectedVersion?.versionId || '', wall);
                // }
            })
        }
    }, [dfxWallGenerate]);

    /**
     * Handles transformation changes for individual lines.
     * Updates the object value state with new position and recalculates wall points.
     * @param index - Index of the line being transformed
     */
    const handleTransformChange = (index: number) => {
        const line = lineRefs.current[index];
        if (!line) return;

        // Get current position of the line
        const position = line.position;

        // Update state with new position
        setObjValue({ x: position.x, y: position.y, z: position.z });

        // Recalculate wall points based on new position
        getWallPointsFromBlueprint({
            objValue: { x: position.x, y: position.y, z: position.z },
            setDxfWallGenerate: () => { },
            wallThickness, wallHeight, outsideMaterial, insideMaterial, activeLayer, addWall, walls
        });
    };
    useEffect(() => {
        if (!toggleView) {
            setDfxUploaded([])
        }
    }, [toggleView])
    return (
        <>
            {/* Render DXF lines with transform controls when DXF data is available and view is toggled */}
            {dfxuploaded &&
                dfxuploaded.length > 0 &&
                toggleView &&
                dfxuploaded?.map((geometry: any, index: number) => {
                    // Create a new line object for each geometry in the DXF data
                    const line = new Line(geometry, new LineBasicMaterial({ color: 'red' }));
                    line.rotation.set(-Math.PI / 2, 0, 0);

                    // Store line reference
                    lineRefs.current[index] = line;

                    return (
                        <TransformControls
                            key={index}
                            object={line}
                            showY={false}
                            onMouseUp={() => handleTransformChange(index)}
                        >
                            {/* Render the line with current position from state */}
                            <primitive object={line} position={[objValue.x, objValue.y, objValue.z]} />
                        </TransformControls>
                    );
                })}
        </>
    );
};

export default DxfFile;