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

export class ReproWall extends SceneFeature {
    constructor() {
        super();
        this.boxes = [];
        sceneFeatureManager.register(this);
    }

    init() {
        const boxSize = 2.6;
        const boxStacks = 3;
        const startZ = -20;
        const endZ = -18;
        const leftX = -8;
        const rightX = 8;

        const cabinetGeometry = new THREE.BoxGeometry(boxSize, boxSize, boxSize);
        
        const cabinetMaterial = new THREE.MeshStandardMaterial({
            color: 0x333333,
            roughness: 0.6,
            metalness: 0.2,
        });
 
        const grilleSize = boxSize * 0.85;
        const grilleGeometry = new THREE.PlaneGeometry(grilleSize, grilleSize);
        const grilleMaterial = new THREE.MeshStandardMaterial({
            color: 0x1a1a1a, // Not completely dark so the mesh is visible
            roughness: 0.9,
            metalness: 0.1,
        });

        // Helper to create a stack of boxes
        const createStack = (baseX, baseZ, rotY) => {
            const stackHeight = 4// + Math.floor(Math.random() * 2);
            for (let i = 0; i < stackHeight; i++) {
                const speakerGroup = new THREE.Group();

                const cabinet = new THREE.Mesh(cabinetGeometry, cabinetMaterial);
                cabinet.castShadow = true;
                cabinet.receiveShadow = true;
                speakerGroup.add(cabinet);

                const grille = new THREE.Mesh(grilleGeometry, grilleMaterial);
                grille.position.z = (boxSize / 2) + 0.01; // Place on front face, slightly forward
                grille.receiveShadow = true;
                speakerGroup.add(grille);

                // Slight random offset for realism
                const x = baseX + (Math.random() * 0.1 - 0.05);
                const z = baseZ + (Math.random() * 0.4 - 0.05);
                const y = (i * boxSize) + (boxSize / 2);
                
                speakerGroup.position.set(x, y, z);
                
                // Slight random rotation
                speakerGroup.rotation.y = rotY + (Math.random() * 0.1 - 0.05);

                state.scene.add(speakerGroup);
                this.boxes.push({ mesh: speakerGroup, originalScale: new THREE.Vector3(1, 1, 1) });
            }
        };

        // Create walls on both sides of the stage
        const z = startZ;
        for (let x = 0; x <= boxStacks * boxSize; x += boxSize) {
            // left side
            createStack(leftX - x, z + x / 2, 0.3);
            // right side
            createStack(rightX + x, z + x / 2, -0.3);
        }
    }

    update(deltaTime) {
        if (state.music && state.music.beatIntensity > 0.5) {
            const scale = 1 + (state.music.beatIntensity - 0.5) * 0.1;
            this.boxes.forEach(item => {
                item.mesh.scale.setScalar(scale);
            });
        } else {
            this.boxes.forEach(item => {
                item.mesh.scale.lerp(item.originalScale, deltaTime * 5);
            });
        }
    }
}

new ReproWall();