// @ts-nocheck
import React, { forwardRef, Suspense, useEffect, useRef, useState, } from 'react';
import { Canvas, extend, invalidate, PerformanceMonitor, PerspectiveCamera, } from '../../modules/three';
import Globe from './Globe';
import { easings, useSpring } from '@react-spring/web';
import { GestureDetector, Gesture } from '../../modules/gesture';
import { useWindowDimensions } from 'react-native';
import { Raycaster, Vector2 } from 'three';
import { clamp, getPhiTheta } from '../../utils/helpers';
import { Environment } from '@react-three/drei/native';
extend([Raycaster, Vector2]);
export default function GlobeScene({ locations = [], beams = [], currentLocation, isVisible, offsetView = [0, 0, 0], isSender, showBeams, theme, }) {
    /* Memo & Refs
    --------------------------------------------------------- */
    const camera = useRef(null);
    const earth = useRef(null);
    const projectionPlane = useRef(null);
    /* States
    --------------------------------------------------------- */
    const [dpr, setDpr] = useState(1.5);
    const [pos] = useState([0.8, -2.5, 3.5]);
    const [pan, setPan] = useState([0, 0]);
    const [size, setSize] = useState(null);
    const [state, setState] = useState(null);
    const [focalPoint, setFocal] = useState([0, 0]);
    const [isRevealed, setReveal] = useState(false);
    const [isTransitioning, setTransitionState] = useState(false);
    const { width, height } = useWindowDimensions();
    const [isGesture] = useState((React.createElement(GestureDetector, null)).type !== React.Fragment);
    /* Springs
    --------------------------------------------------------- */
    const [{ position, rotation }] = useSpring({
        position: isVisible ? offsetView : pos,
        rotation: isVisible
            ? [focalPoint[0], focalPoint[1], 0]
            : [0.3, focalPoint[1] + Math.PI, 0],
        onStart: () => {
            setTransitionState(true);
            if (!isVisible) {
                setReveal(false);
            }
        },
        onChange: () => {
            invalidate();
        },
        onRest: () => {
            setTransitionState(false);
            if (isVisible) {
                setReveal(true);
            }
        },
        config: {
            precision: 0.000001,
            duration: isVisible ? 2800 : 1600,
            easing: isVisible ? easings.easeOutCubic : easings.easeInCubic,
        },
    }, [isVisible, focalPoint, pos]);
    const [, api] = useSpring(() => ({
        x: 0,
        y: 0,
        onChange: ({ value }) => {
            invalidate();
            const x = value.x / size[0];
            const y = -value.y / size[1];
            setPan([x * (Math.PI * 2) * 0.015, y * 0.1]);
        },
    }), [size]);
    /* Effects
    --------------------------------------------------------- */
    useEffect(() => {
        const earthMesh = earth.current;
        if (!earthMesh || !(isTransitioning && !isRevealed)) {
            return;
        }
        const { lat, lng } = currentLocation.coordinates;
        const { phi, theta } = getPhiTheta(lat, lng);
        const x = clamp(Math.PI / 2 - phi, -0.3, 0.3);
        const y = -theta + Math.PI * 0.35;
        setFocal([x, y]);
    }, [isRevealed, isTransitioning, isVisible, currentLocation]);
    useEffect(() => {
        if (!state) {
            return;
        }
        setSize([width, height]);
    }, [height, state, width]);
    /* Gestures
    --------------------------------------------------------- */
    // /* eslint-disable */
    let panGesture;
    if (isGesture) {
        panGesture = Gesture.Pan()
            .runOnJS(true)
            .onStart(() => {
            if (!isRevealed) {
                return;
            }
            api.start({ x: 0, y: 0 });
        })
            .onUpdate((e) => {
            if (!isRevealed) {
                return;
            }
            api.start({
                x: e.velocityX,
                y: e.velocityY,
                config: {
                    mass: 100,
                    friction: 3000,
                    tension: 3000,
                },
            });
        })
            .onEnd(() => {
            if (!isRevealed) {
                return;
            }
            api.start({ x: 0, y: 0 });
        });
    }
    // /* eslint-enable */
    return (React.createElement(React.Fragment, null,
        isGesture && (React.createElement(GestureDetector, { gesture: panGesture },
            React.createElement(Canvas, { gl: { antialias: false, useLegacyLights: true }, frameloop: "demand", dpr: dpr, onCreated: s => {
                    setState(s);
                } },
                React.createElement(PerformanceMonitor, { onIncline: () => setDpr(2), onDecline: () => setDpr(1) }),
                React.createElement(PerspectiveCamera, { ref: camera, makeDefault: true, position: [0, 0, 3] }),
                React.createElement("directionalLight", { position: [1, 0.5, 1], intensity: 1.2, castShadow: true, "shadow-bias": -0.0001, "shadow-mapSize-width": 2048, "shadow-mapSize-height": 2048, "shadow-camera-far": 5 }),
                React.createElement("directionalLight", { position: [-2, -0.5, 0], intensity: 0.2, castShadow: true, "shadow-bias": -0.0001, "shadow-mapSize-width": 2048, "shadow-mapSize-height": 2048, "shadow-camera-far": 5 }),
                React.createElement(Suspense, { fallback: null },
                    React.createElement(Globe, { ref: earth, position: position, rotation: rotation, currentLocation: currentLocation, locations: locations, beams: beams, showBeams: showBeams, globeTheme: theme, isRevealed: isRevealed, panRotation: pan, isVisible: isVisible, isTransitioning: isTransitioning, isSender: isSender }),
                    React.createElement(Environment, { preset: "studio" })),
                React.createElement(DummyPlane, { position: [0, 0, 1.5], ref: projectionPlane })))),
        !isGesture && (React.createElement(Canvas, { gl: { antialias: false, useLegacyLights: true }, frameloop: "demand", dpr: dpr, onCreated: s => {
                setState(s);
            } },
            React.createElement(PerformanceMonitor, { onIncline: () => setDpr(2), onDecline: () => setDpr(1) }),
            React.createElement(PerspectiveCamera, { ref: camera, makeDefault: true, position: [0, 0, 3] }),
            React.createElement("directionalLight", { position: [1, 0.5, 1], intensity: 1.2, castShadow: true, "shadow-bias": -0.0001, "shadow-mapSize-width": 2048, "shadow-mapSize-height": 2048, "shadow-camera-far": 5 }),
            React.createElement("directionalLight", { position: [-2, -0.5, 0], intensity: 0.2, castShadow: true, "shadow-bias": -0.0001, "shadow-mapSize-width": 2048, "shadow-mapSize-height": 2048, "shadow-camera-far": 5 }),
            React.createElement(Suspense, { fallback: null },
                React.createElement(Globe, { ref: earth, position: position, rotation: rotation, currentLocation: currentLocation, locations: locations, beams: beams, showBeams: showBeams, globeTheme: theme, isRevealed: isRevealed, panRotation: pan, isVisible: isVisible, isTransitioning: isTransitioning, isSender: isSender }),
                React.createElement(Environment, { preset: "studio" })),
            React.createElement(DummyPlane, { position: [0, 0, 1.5], ref: projectionPlane })))));
}
const DummyPlane = forwardRef((props, ref) => {
    return (React.createElement("mesh", Object.assign({ visible: false, ref: ref }, props),
        React.createElement("planeGeometry", { args: [10, 10] }),
        React.createElement("meshBasicMaterial", null)));
});
