import * as THREE from 'three';
import { state } from '../state.js';
import { SceneFeature } from './SceneFeature.js';
import sceneFeatureManager from './SceneFeatureManager.js';

export class StageLightBars extends SceneFeature {
    constructor() {
        super();
        this.bars = [];
        this.mode = 'STATIC'; // 'STATIC' or 'CHASE'
        this.lastModeChange = 0;
        this.chaseOffset = 0;
        this.staticIndices = [];
        sceneFeatureManager.register(this);
    }

    init() {
        // Shared Geometry/Material setup
        // We use individual materials to allow different colors per bar if needed, 
        // or we can update them dynamically.
        
        // 1. Stage Front Edge Bar
        this.createBar(new THREE.Vector3(0, 1.50, -14.95), new THREE.Vector3(11, 0.1, 0.1));

        // 2. Stage Side Bars (Vertical)
        // Left Front
        this.createBar(new THREE.Vector3(-5.45, 0.7, -14.95), new THREE.Vector3(0.1, 1.5, 0.1));
        // Right Front
        this.createBar(new THREE.Vector3(5.45, 0.7, -14.95), new THREE.Vector3(0.1, 1.5, 0.1));

        // 3. Overhead Beam Bars
        this.createBar(new THREE.Vector3(0, 8.5, -14), new THREE.Vector3(31, 0.1, 0.1));
        
        // 4. Vertical Truss Bars (Sides of the beam)
        this.createBar(new THREE.Vector3(-15.9, 3, -14), new THREE.Vector3(0.2, 12, 0.2));
        this.createBar(new THREE.Vector3(15.9, 3, -14), new THREE.Vector3(0.2, 12, 0.2));

        this.applyColors();
        this.setVisibility(state.config.lightBarsEnabled);
    }

    createBar(position, size) {
        const geometry = new THREE.BoxGeometry(size.x, size.y, size.z);
        const material = new THREE.MeshStandardMaterial({
            color: 0xffffff,
            emissive: 0xffffff,
            emissiveIntensity: 1.0,
            roughness: 0.4,
            metalness: 0.8
        });
        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.copy(position);
        mesh.castShadow = true; // Maybe cast shadow?
        state.scene.add(mesh);

        this.bars.push({ mesh, material });
    }

    applyColors() {
        const colors = state.config.lightBarColors;
        if (!colors || colors.length === 0) {
            this.staticIndices = [];
        } else {
            // Default distribution (sequential)
            this.staticIndices = this.bars.map((_, i) => i % colors.length);
        }
        this.updateBarColors();
    }

    updateBarColors() {
        const colors = state.config.lightBarColors;
        if (!colors || colors.length === 0) {
            this.bars.forEach(bar => {
                bar.material.color.setHex(0x111111);
                bar.material.emissive.setHex(0x000000);
            });
            return;
        }
        
        this.bars.forEach((bar, index) => {
            let colorIndex;
            if (this.mode === 'CHASE') {
                colorIndex = Math.floor(index + this.chaseOffset) % colors.length;
            } else {
                // Ensure staticIndices is populated
                if (this.staticIndices.length <= index) {
                     this.staticIndices.push(index % colors.length);
                }
                colorIndex = this.staticIndices[index] % colors.length;
            }
            
            if (colorIndex < 0) colorIndex += colors.length;

            const colorHex = colors[colorIndex];
            const color = new THREE.Color(colorHex);
            bar.material.color.copy(color);
            bar.material.emissive.copy(color);
        });
    }

    redistributeColors() {
        const colors = state.config.lightBarColors;
        if (colors && colors.length > 0) {
            this.staticIndices = this.bars.map(() => Math.floor(Math.random() * colors.length));
        }
    }

    setVisibility(visible) {
        this.bars.forEach(bar => {
            bar.mesh.visible = visible;
        });
    }

    update(deltaTime) {
        if (!state.partyStarted) return;
        if (!state.config.lightBarsEnabled) return;
        
        if (state.blackoutMode) {
            this.bars.forEach(bar => {
                bar.material.emissiveIntensity = 0;
            });
            return;
        }

        const time = state.clock.getElapsedTime();
        const beatIntensity = state.music ? state.music.beatIntensity : 0;
        const isBeat = beatIntensity > 0.8;

        // Mode Switching Logic
        if (isBeat && time - this.lastModeChange > 4.0) {
            // Chance to switch mode or redistribute
            if (Math.random() < 0.3) {
                this.mode = this.mode === 'STATIC' ? 'CHASE' : 'STATIC';
                this.lastModeChange = time;
                
                if (this.mode === 'STATIC') {
                    this.redistributeColors();
                }
            } else if (this.mode === 'STATIC' && Math.random() < 0.5) {
                // Redistribute without switching mode
                this.redistributeColors();
                this.lastModeChange = time;
            }
        }

        // Update Chase
        if (this.mode === 'CHASE') {
            this.chaseOffset += deltaTime * 4.0;
        }
        
        this.updateBarColors();

        // Pulsate
        const baseIntensity = 0.2;
        const pulse = Math.sin(time * 2.0) * 0.3 + 0.3; // Breathing
        const beatFlash = beatIntensity * 2.0; // Sharp flash on beat

        const totalIntensity = baseIntensity + pulse + beatFlash;

        this.bars.forEach(bar => {
            bar.material.emissiveIntensity = totalIntensity;
        });
    }

    refreshColors() {
        this.applyColors();
    }
}

new StageLightBars();
