import * as THREE from 'three';
import SunCalc from 'suncalc';
import { Ref } from 'vue';

export function useSunSystem(scene: THREE.Scene, state: Ref<{ currentTime: number; brightness?: number }>) {
    let directionalLight: THREE.DirectionalLight;
    let ambientLight: THREE.AmbientLight;

    const COLORS = {
        day: new THREE.Color(0xa9d3fd),
        night: new THREE.Color(0x0a0a23),
        sunriseSun: new THREE.Color(0xa3d1ff),
        daySun: new THREE.Color(0xffffa9),
        sunsetSun: new THREE.Color(0xffcc25),
        nightSun: new THREE.Color(0x222244),
        dayAmbient: new THREE.Color(0xa9d3fd),
        nightAmbient: new THREE.Color(0x555588),
        tempSun: new THREE.Color(),
        tempAmbient: new THREE.Color(),
        tempBg: new THREE.Color()
    };

    const initSun = () => {
        ambientLight = new THREE.AmbientLight(0x90bbbd, 1.2); // Boosted Ambient
        scene.add(ambientLight);

        directionalLight = new THREE.DirectionalLight(0xffffff);
        directionalLight.position.set(20, 30, 10);
        directionalLight.castShadow = true;
        directionalLight.shadow.mapSize.width = 2048;
        directionalLight.shadow.mapSize.height = 2048;
        directionalLight.shadow.camera.near = 0.5;
        directionalLight.shadow.camera.far = 500;
        directionalLight.shadow.bias = -0.0005;
        directionalLight.shadow.normalBias = 0.05;
        directionalLight.shadow.camera.left = -100;
        directionalLight.shadow.camera.right = 100;
        directionalLight.shadow.camera.top = 100;
        directionalLight.shadow.camera.bottom = -100;
        scene.add(directionalLight);
    };

    // --- Gradient Logic ---
    const getSunColors = (elevation: number) => {
        // Elevation is in radians. Convert to degrees for easier mental mapping.
        const deg = elevation * (180 / Math.PI);

        // Keyframes
        // Day: > 10 deg
        if (deg > 10) {
            return {
                sun: COLORS.daySun,
                ambient: COLORS.dayAmbient,
                bg: COLORS.day,
                intensity: 1.5, // Boosted Sun Intensity
                shadow: true
            };
        }

        // Golden Hour / Sunrise / Sunset: 0 to 10 deg
        if (deg > 0) {
            const t = deg / 10; // 0 to 1
            COLORS.tempSun.copy(COLORS.sunsetSun).lerp(COLORS.daySun, t);
            COLORS.tempAmbient.copy(COLORS.nightAmbient).lerp(COLORS.dayAmbient, t); // approximate transition
            COLORS.tempBg.copy(COLORS.night).lerp(COLORS.day, t); // simple fade

            return {
                sun: COLORS.tempSun,
                ambient: COLORS.tempAmbient,
                bg: COLORS.tempBg, // We might want a more "orange" sky here, but lerp is safe
                intensity: 0.5 + (1.0 * t), // 0.5 to 1.5
                shadow: true
            };
        }

        // Twilight: -6 to 0 deg (Civil Twilight)
        if (deg > -6) {
            const t = (deg + 6) / 6; // 0 to 1
            COLORS.tempSun.copy(COLORS.nightSun).lerp(COLORS.sunsetSun, t);
            COLORS.tempAmbient.copy(COLORS.nightAmbient).lerp(COLORS.nightAmbient, t); // Stay darkish
            COLORS.tempBg.copy(COLORS.night).lerp(new THREE.Color(0x443355), t); // Purple-ish twilight

            return {
                sun: COLORS.tempSun,
                ambient: COLORS.tempAmbient,
                bg: COLORS.tempBg,
                intensity: t * 0.5, // 0 to 0.5
                shadow: false // Shadows get weird at low angles, disable for clean look
            };
        }

        // Night: < -6 deg
        return {
            sun: COLORS.nightSun,
            ambient: COLORS.nightAmbient,
            bg: COLORS.night,
            intensity: 0.2, // Moonlight
            shadow: false
        };
    };

    const updateSun = () => {
        if (!directionalLight || !ambientLight) return;

        // Calculate Position
        const latitude = 41.17873;
        const longitude = -8.60835;
        const currentHour = state.value.currentTime;
        const now = new Date();
        now.setHours(Math.floor(currentHour));
        now.setMinutes(Math.floor((currentHour % 1) * 60));
        now.setSeconds(0);

        const sunPos = SunCalc.getPosition(now, latitude, longitude);

        // Position the light
        const sunRadius = 100;
        const azimuth = sunPos.azimuth;
        const elevation = sunPos.altitude;

        const sunX = sunRadius * Math.cos(elevation) * Math.cos(azimuth);
        const sunY = sunRadius * Math.sin(elevation);
        const sunZ = sunRadius * Math.cos(elevation) * Math.sin(azimuth);

        if (directionalLight) {
            directionalLight.position.set(sunX, sunY, sunZ);
            directionalLight.target.position.set(0, 0, 0);
            directionalLight.target.updateMatrixWorld();
        }

        // Update Colors based on elevation
        const colors = getSunColors(sunPos.altitude);

        // Update Colors based on brightness
        const brightness = state.value.brightness ?? 1.0;

        directionalLight.color.copy(colors.sun);
        directionalLight.intensity = colors.intensity * brightness;
        directionalLight.castShadow = colors.shadow;

        ambientLight.color.copy(colors.ambient);
        ambientLight.intensity = 1.2 * brightness;

        scene.background = colors.bg;
    };

    return {
        initSun,
        updateSun
    };
}
