// src/components/EarthBody.jsx
import React, { useRef, useEffect, useImperativeHandle } from 'react';
import { useLoader, useFrame } from '@react-three/fiber';
import { Sphere } from '@react-three/drei';
import { TextureLoader, LinearSRGBColorSpace, AdditiveBlending, Euler, Quaternion, Vector3, Color } from 'three';
import { gsap } from 'gsap';

import atmosphereVertexShader from "../shaders/atmosphereVertex.glsl";
import atmosphereFragmentShader from "../shaders/atmosphereFragment.glsl";

// Clouds และ AtmosphereGlow components เหมือนเดิม (ไม่มีการเปลี่ยนแปลง)
function Clouds() {
    const cloudsRef = useRef();
    const cloudMap = useLoader(TextureLoader, '/textures/05_earthcloudmaptrans.jpg');
    cloudMap.colorSpace = LinearSRGBColorSpace;
    useFrame(() => {
        if (cloudsRef.current) {
            cloudsRef.current.rotation.y += 0.0006;
        }
    });
    return (
        <Sphere ref={cloudsRef} args={[1.005, 64, 64]}>
            <meshStandardMaterial
                map={cloudMap}
                transparent
                opacity={0.5}
                blending={AdditiveBlending}
            />
        </Sphere>
    );
}

function AtmosphereGlow() {
    const material = useRef();
    useEffect(() => {
        if (material.current) {
            material.current.uniforms.u_color.value = new Color(0x3e90ff);
        }
    }, []);
    return (
        <Sphere args={[1.15, 64, 64]}>
            <shaderMaterial
                ref={material}
                vertexShader={atmosphereVertexShader}
                fragmentShader={atmosphereFragmentShader}
                blending={AdditiveBlending}
                side={2}
                transparent={true}
                uniforms={{
                    u_color: { value: new Color(0x3e90ff) },
                }}
            />
        </Sphere>
    );
}

const EarthBody = React.forwardRef(function EarthBody(props, ref) {
    const { orbitControlsRef } = props;

    const [dayMap, bumpMap, specularMap, lightsMap] = useLoader(TextureLoader, [
        '/textures/earth_daymap_prime_meridian_centered.jpg',
        '/textures/01_earthbump1k.jpg',
        '/textures/02_earthspec1k.jpg',
        '/textures/03_earthlights1k.jpg',
    ]);

    dayMap.colorSpace = LinearSRGBColorSpace;
    lightsMap.colorSpace = LinearSRGBColorSpace;

    const internalMeshRef = useRef();
    const groupRef = useRef(); // Group for static tilt
    const rotationTween = useRef(null);

    // This offset aligns the prime meridian (0 longitude) on the texture correctly.
    const textureLonOffsetDegrees = 70;

    // Static tilt for the entire globe group (e.g., Earth's axial tilt)
    const tiltAngle = -23.4 * Math.PI / 180;

    useEffect(() => {
        if (groupRef.current) {
            groupRef.current.rotation.x = tiltAngle;
        }
    }, []);

    useImperativeHandle(ref, () => {
        return {
            get mesh() {
                return internalMeshRef.current;
            },
            rotateToLatLon: (lat, lon, duration = 1.5) => {
                if (!internalMeshRef.current) {
                    console.warn("EarthBody.rotateToLatLon: internalMeshRef.current is null. Cannot start animation.");
                    return;
                }
                if (!orbitControlsRef.current) {
                    console.warn("EarthBody.rotateToLatLon: orbitControlsRef.current is null. Cannot start animation.");
                    return;
                }

                if (rotationTween.current) {
                    rotationTween.current.kill();
                    console.log("Previous rotation tween killed.");
                }

                console.log(`--- rotateToLatLon Called ---`);
                console.log(`Target Lat: ${lat}, Target Lon: ${lon}`);

                const targetRotationX = lat * Math.PI / 180;
                let targetRotationY = -(lon + textureLonOffsetDegrees) * Math.PI / 180;

                let currentRotationY = internalMeshRef.current.rotation.y;

                // Normalize currentRotationY to be within (-PI, PI]
                currentRotationY = (currentRotationY + Math.PI) % (2 * Math.PI);
                if (currentRotationY > Math.PI) currentRotationY -= (2 * Math.PI);

                let diff = targetRotationY - currentRotationY;
                if (diff > Math.PI) {
                    diff -= 2 * Math.PI;
                } else if (diff <= -Math.PI) {
                    diff += 2 * Math.PI;
                }

                if (diff < 0) {
                    diff += 2 * Math.PI;
                }
                const finalTargetRotationY = currentRotationY + diff;

                const animationTarget = {
                    x: internalMeshRef.current.rotation.x,
                    y: internalMeshRef.current.rotation.y,
                    z: internalMeshRef.current.rotation.z
                };

                console.log("Current Euler (rad):", internalMeshRef.current.rotation);
                console.log("Target Lat (x-axis, rad):", targetRotationX);
                console.log("Target Lon (y-axis, adjusted rad):", finalTargetRotationY);
                console.log("Calculated Delta Y (rad):", diff);


                if (orbitControlsRef.current) {
                    orbitControlsRef.current.enabled = false; // ปิด OrbitControls ชั่วคราว
                    console.log("OrbitControls temporarily disabled during animation.");
                }

                rotationTween.current = gsap.to(animationTarget, {
                    duration: duration,
                    ease: "power2.inOut",
                    x: targetRotationX,
                    y: finalTargetRotationY,
                    z: 0,
                    onStart: () => {
                        console.log("GSAP animation started.");
                    },
                    onUpdate: () => {
                        internalMeshRef.current.rotation.set(animationTarget.x, animationTarget.y, animationTarget.z);
                    },
                    onComplete: () => {
                        console.log("GSAP animation complete.");
                        if (orbitControlsRef.current) {
                            orbitControlsRef.current.enabled = true; // เปิด OrbitControls กลับมา
                            orbitControlsRef.current.target.set(0, 0, 0); // รีเซ็ต target ไปที่ศูนย์กลางโลก
                            orbitControlsRef.current.update();
                            console.log("OrbitControls re-enabled (zoom only).");
                        }
                    },
                });

                if (rotationTween.current) {
                    console.log("GSAP Tween instance created. Is active:", rotationTween.current.isActive());
                } else {
                    console.error("GSAP Tween instance was NOT created.");
                }
            }
        };
    }, [internalMeshRef, textureLonOffsetDegrees, orbitControlsRef]);


    useFrame(() => {
        // Only apply continuous rotation if no active tween
        if (internalMeshRef.current && (!rotationTween.current || !rotationTween.current.isActive())) {
            internalMeshRef.current.rotation.y += 0.0005;
        }
    });

    return (
        <group ref={groupRef}>
            <Sphere ref={internalMeshRef} args={[1, 64, 64]}>
                <meshStandardMaterial
                    map={dayMap}
                    bumpMap={bumpMap}
                    bumpScale={0.02}
                    roughnessMap={specularMap}
                    metalness={0.0}
                    emissiveMap={lightsMap}
                    emissiveIntensity={0.5}
                    emissive={new Color(0xffffff)}
                />
            </Sphere>
            <Clouds />
            <AtmosphereGlow />
        </group>
    );
});

export default EarthBody;