import { useRef, useMemo } from 'react'
import { useFrame, useThree } from '@react-three/fiber'
import { ShaderMaterial, Vector3, DoubleSide } from 'three'

export function WorldBorder() {
    const materialRef = useRef<ShaderMaterial>(null)
    const { camera } = useThree()

    const uniforms = useMemo(
        () => ({
            uPlayerPos: { value: new Vector3() },
            uVisibleDistance: { value: 200.0 },
        }),
        []
    )

    useFrame(() => {
        if (materialRef.current) {
            materialRef.current.uniforms.uPlayerPos.value.copy(camera.position)
        }
    })

    const vertexShader = `
    varying vec3 vWorldPos;
void main() {
      vec4 worldPosition = modelMatrix * vec4(position, 1.0);
    vWorldPos = worldPosition.xyz;
    gl_Position = projectionMatrix * viewMatrix * worldPosition;
}
`

    const fragmentShader = `
    uniform vec3 uPlayerPos;
    uniform float uVisibleDistance;
    varying vec3 vWorldPos;

void main() {
      // Calculate distance from player to this fragment
      float distToPlayer = distance(uPlayerPos, vWorldPos);

      // Fade based on distance
      float alpha = 1.0 - smoothstep(0.0, uVisibleDistance, distToPlayer);

    if (alpha <= 0.0) discard;

    gl_FragColor = vec4(1.0, 0.0, 0.0, alpha * 0.8);
}
`

    const mapSize = 2500
    const halfSize = mapSize / 2
    const wallHeight = 100

    return (
        <group>
            {/* North Wall (-Z) */}
            <mesh position={[0, wallHeight / 2, -halfSize]}>
                <planeGeometry args={[mapSize, wallHeight]} />
                <shaderMaterial
                    ref={materialRef}
                    vertexShader={vertexShader}
                    fragmentShader={fragmentShader}
                    uniforms={uniforms}
                    transparent
                    side={DoubleSide}
                />
            </mesh>
            {/* South Wall (+Z) */}
            <mesh position={[0, wallHeight / 2, halfSize]}>
                <planeGeometry args={[mapSize, wallHeight]} />
                <shaderMaterial
                    vertexShader={vertexShader}
                    fragmentShader={fragmentShader}
                    uniforms={uniforms}
                    transparent
                    side={DoubleSide}
                />
            </mesh>
            {/* East Wall (+X) */}
            <mesh position={[halfSize, wallHeight / 2, 0]} rotation={[0, -Math.PI / 2, 0]}>
                <planeGeometry args={[mapSize, wallHeight]} />
                <shaderMaterial
                    vertexShader={vertexShader}
                    fragmentShader={fragmentShader}
                    uniforms={uniforms}
                    transparent
                    side={DoubleSide}
                />
            </mesh>
            {/* West Wall (-X) */}
            <mesh position={[-halfSize, wallHeight / 2, 0]} rotation={[0, Math.PI / 2, 0]}>
                <planeGeometry args={[mapSize, wallHeight]} />
                <shaderMaterial
                    vertexShader={vertexShader}
                    fragmentShader={fragmentShader}
                    uniforms={uniforms}
                    transparent
                    side={DoubleSide}
                />
            </mesh>
        </group>
    )
}
