import React, { useEffect, useMemo } from 'react';
import { Vector3 } from 'three';
import { Html } from '@react-three/drei';
import { useSceneContext } from '../../../scene/sceneContext';
import { useToggleView, useToolMode } from '../../../../store/builder/store';
import Line from '../../line/line';
import Point from '../../point/point';
import FloorInstance from './Instance/floorInstance';
import Floor2DInstance from './Instance/floor2DInstance';
import useModuleStore from '../../../../store/useModuleStore';
import { useBuilderStore } from '../../../../store/builder/useBuilderStore';

function FloorInstances() {
    const { floorStore } = useSceneContext();
    const { floors } = floorStore();
    const { setSelectedFloor, selectedFloor } = useBuilderStore();
    const { toolMode } = useToolMode();
    const { toggleView } = useToggleView();
    const { activeModule } = useModuleStore();

    useEffect(() => {
        // console.log('floors: ', floors);
    }, [floors])

    useEffect(() => {
        if (!toggleView && activeModule === 'builder') {
            if (toolMode !== 'cursor') {
                if (selectedFloor) setSelectedFloor(null);
            }
        } else {
            if (selectedFloor) setSelectedFloor(null);
        }
    }, [toggleView, toolMode, activeModule, selectedFloor]);

    const allPoints = useMemo(() => {
        const points: Point[] = [];
        const seenUuids = new Set<string>();

        floors.forEach(floor => {
            floor.points.forEach(point => {
                if (!seenUuids.has(point.pointUuid)) {
                    seenUuids.add(point.pointUuid);
                    points.push(point);
                }
            });
        });

        return points;
    }, [floors]);

    const allLines = useMemo(() => {
        const lines: { start: Point; end: Point; key: string }[] = [];
        const seenUuids = new Set<string>();

        floors.forEach((floor) => {
            const points = floor.points;
            if (points.length < 2) return;

            for (let i = 0; i < points.length; i++) {
                const current = points[i];
                const next = points[(i + 1) % points.length];
                const lineKey = `${current.pointUuid}-${next.pointUuid}`;
                if (current.pointUuid !== next.pointUuid && !seenUuids.has(lineKey)) {
                    seenUuids.add(lineKey);
                    lines.push({
                        start: current,
                        end: next,
                        key: lineKey
                    });
                }
            }
        });

        return lines;
    }, [floors]);

    return (
        <>

            {!toggleView && floors.length > 0 && (
                <mesh name='Floors-Group'>
                    {floors.map((floor) => (
                        <FloorInstance key={floor.floorUuid} floor={floor} />
                    ))}
                </mesh>
            )}

            {toggleView && floors.length > 0 && (
                <mesh name='Floors-2D-Group'>
                    {floors.map((floor) => (
                        <Floor2DInstance key={floor.floorUuid} floor={floor} />
                    ))}
                </mesh>
            )}

            {toggleView && (
                <>
                    <group name='Floor-Points-Group'>
                        {allPoints.map((point) => (
                            <Point key={point.pointUuid} point={point} />
                        ))}
                    </group>

                    <group name='Floor-Lines-Group'>

                        {allLines.map(({ start, end, key }) => (
                            <Line key={key} points={[start, end]} />
                        ))}

                        {allLines.map((line) => {
                            const { start, end, key } = line;
                            const textPosition = new Vector3().addVectors(new Vector3(...start.position), new Vector3(...end.position)).divideScalar(2);
                            const distance = new Vector3(...start.position).distanceTo(new Vector3(...end.position));

                            return (
                                <React.Fragment key={key}>
                                    {toggleView &&
                                        <Html
                                            key={`${start.pointUuid}_${end.pointUuid}`}
                                            userData={line}
                                            position={[textPosition.x, 1, textPosition.z]}
                                            wrapperClass="distance-text-wrapper"
                                            className="distance-text"
                                            zIndexRange={[1, 0]}
                                            prepend
                                            sprite
                                        >
                                            <div
                                                key={key}
                                                className={`distance ${key}`}
                                            >
                                                {distance.toFixed(2)} m
                                            </div>
                                        </Html>
                                    }
                                </React.Fragment>
                            )
                        })}

                    </group>

                </>
            )}
        </>
    )
}

export default FloorInstances;