import * as THREE from 'three';
import * as Constants from '../../../../types/world/worldConstants';
import { useRef, useMemo } from 'react';

function ReferencePoint({ point }: { readonly point: Point }) {
    const materialRef = useRef<THREE.ShaderMaterial>(null);

    const boxScale: [number, number, number] = Constants.pointConfig.boxScale;
    const colors = {
        defaultInnerColor: Constants.pointConfig.defaultInnerColor,
        defaultOuterColor: Constants.pointConfig.helperColor,
        defaultDeleteColor: Constants.pointConfig.deleteColor,
    };

    const uniforms = useMemo(() => ({
        uOuterColor: { value: new THREE.Color(colors.defaultOuterColor) },
        uInnerColor: { value: new THREE.Color(colors.defaultInnerColor) },
    }), [colors.defaultInnerColor, colors.defaultOuterColor, colors.defaultDeleteColor]);

    if (!point) {
        return null;
    }

    const pointName = point.pointType === 'Wall' ? 'Wall-Point' :
        point.pointType === 'Floor' ? 'Floor-Point' :
            point.pointType === 'Aisle' ? 'Aisle-Point' :
                point.pointType === 'Zone' ? 'Zone-Point' : 'Point';

    return (
        <mesh
            position={new THREE.Vector3(...point.position)}
            name={pointName}
            uuid={point.pointUuid}
            userData={point}
        >
            <boxGeometry args={boxScale} />
            <shaderMaterial
                ref={materialRef}
                uniforms={uniforms}
                vertexShader={`
                    varying vec2 vUv;
                
                    void main() {
                        vUv = uv;
                        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                    }
                `}
                fragmentShader={`
                    varying vec2 vUv;
                    uniform vec3 uOuterColor;
                    uniform vec3 uInnerColor;
                
                    void main() {
                        // Define the size of the white square as a proportion of the face
                        float borderThickness = 0.2; // Adjust this value for border thickness
                        if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && 
                            vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
                            gl_FragColor = vec4(uInnerColor, 1.0); // Inner square
                        } else {
                            gl_FragColor = vec4(uOuterColor, 1.0); // Border
                        }
                    }
                `}
            />
        </mesh>
    );
}

export default ReferencePoint;