import * as THREE from 'three';
import { state } from '../state.js';
import wallTextureUrl from '/textures/stone_wall.png';
import sceneFeatureManager from './SceneFeatureManager.js';
import { SceneFeature } from './SceneFeature.js';
const length = 40;

export class RoomWalls extends SceneFeature {
    constructor() {
        super();
        sceneFeatureManager.register(this);
    }
    init() {
    const naveWidth = 12;
    const aisleWidth = 6;
    const totalWidth = naveWidth + 2 * aisleWidth;

    const aisleHeight = 8;
    const naveHeight = 15;
    const roofPeakHeight = 6; // Additional height for the nave's vaulted roof peak

    // --- Pillar and Arch Dimensions ---
    const pillarSize = 1.0;
    const pillarHeight = aisleHeight;
    const numPillars = 5; // Number of pillars along each side
    const pillarSpacing = length / (numPillars + 1);

    // --- Materials and Textures ---
    const wallTexture = state.loader.load(wallTextureUrl);
    wallTexture.wrapS = THREE.RepeatWrapping;
    wallTexture.wrapT = THREE.RepeatWrapping;

    const wallMaterial = new THREE.MeshStandardMaterial({
        map: wallTexture,
        side: THREE.DoubleSide,
        shininess: 5,
        roughness: 0.2,
        metalness: 0.1,
        specular: 0x111111
    });

    // --- Geometry Definitions ---
    const pillarGeo = new THREE.CylinderGeometry(pillarSize / 2, pillarSize / 2, pillarHeight, 24);

    // --- Object Creation Functions ---
    const createMesh = (geometry, material, position, rotation = new THREE.Euler()) => {
        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.copy(position);
        mesh.rotation.copy(rotation);
        mesh.castShadow = true;
        mesh.receiveShadow = true;
        state.scene.add(mesh);
        return mesh;
    };

    // --- Build the Cathedral ---

    // 1. Back Wall
    const backWallGeo = new THREE.PlaneGeometry(totalWidth, aisleHeight);
    const backWallMat = wallMaterial.clone();
    backWallMat.map = wallTexture.clone();
    backWallMat.map.repeat.set(totalWidth / 4, aisleHeight / 4);
    createMesh(backWallGeo, backWallMat, new THREE.Vector3(0, aisleHeight / 2, -length / 2));

    // 2. Outer Aisle Walls
    const outerWallGeo = new THREE.PlaneGeometry(length, aisleHeight);
    const outerWallMat = wallMaterial.clone();
    outerWallMat.map = wallTexture.clone();
    outerWallMat.map.repeat.set(length / 4, aisleHeight / 4);
    createMesh(outerWallGeo, outerWallMat, new THREE.Vector3(-totalWidth / 2, aisleHeight / 2, 0), new THREE.Euler(0, Math.PI / 2, 0));
    createMesh(outerWallGeo, outerWallMat, new THREE.Vector3(totalWidth / 2, aisleHeight / 2, 0), new THREE.Euler(0, -Math.PI / 2, 0));

    // 3. Aisle Roofs (Flat)
    const aisleRoofGeo = new THREE.PlaneGeometry(aisleWidth, length);
    const aisleRoofMat = wallMaterial.clone();
    aisleRoofMat.map = wallTexture.clone();
    aisleRoofMat.map.repeat.set(aisleWidth / 4, length / 4);
    createMesh(aisleRoofGeo, aisleRoofMat, new THREE.Vector3(-naveWidth / 2 - aisleWidth / 2, aisleHeight, 0), new THREE.Euler(-Math.PI / 2, 0, 0));
    createMesh(aisleRoofGeo, aisleRoofMat, new THREE.Vector3(naveWidth / 2 + aisleWidth / 2, aisleHeight, 0), new THREE.Euler(-Math.PI / 2, 0, 0));

    // 4. Pillars and Arcades
    const arcadeWallHeight = aisleHeight - pillarHeight;
    const arcadeWallGeo = new THREE.PlaneGeometry(pillarSpacing - pillarSize, arcadeWallHeight);
    const arcadeWallMat = wallMaterial.clone();
    arcadeWallMat.map = wallTexture.clone();
    arcadeWallMat.map.repeat.set((pillarSpacing - pillarSize) / 4, arcadeWallHeight / 4);

    for (let i = 0; i <= numPillars; i++) {
        const z = -length / 2 + pillarSpacing * (i + 0.5);
        // Add wall sections between pillars
        if (i <= numPillars) {
            createMesh(arcadeWallGeo, arcadeWallMat, new THREE.Vector3(-naveWidth / 2 , pillarHeight + arcadeWallHeight / 2, z));
            createMesh(arcadeWallGeo, arcadeWallMat, new THREE.Vector3(naveWidth / 2, pillarHeight + arcadeWallHeight / 2, z));
        }

        const pillarZ = -length / 2 + pillarSpacing * (i + 1) - pillarSize / 2;
        // Left side pillars
        createMesh(pillarGeo, wallMaterial, new THREE.Vector3(-naveWidth / 2 - pillarSize, pillarHeight / 2, pillarZ));
            // Right side pillars
        createMesh(pillarGeo, wallMaterial, new THREE.Vector3(naveWidth / 2 + pillarSize, pillarHeight / 2, pillarZ));
        }

    // 5. Clerestory (Upper Nave Walls)
    const clerestoryHeight = naveHeight - aisleHeight;
    const clerestoryGeo = new THREE.PlaneGeometry(length, clerestoryHeight);
    const clerestoryMat = wallMaterial.clone();
    clerestoryMat.map = wallTexture.clone();
    clerestoryMat.map.repeat.set(length / 4, clerestoryHeight / 4);
        // Left and Right Clerestory walls
    createMesh(clerestoryGeo, clerestoryMat, new THREE.Vector3(-naveWidth / 2, aisleHeight + clerestoryHeight / 2, 0), new THREE.Euler(0, - Math.PI / 2, 0));
    createMesh(clerestoryGeo, clerestoryMat, new THREE.Vector3(naveWidth / 2, aisleHeight + clerestoryHeight / 2, 0), new THREE.Euler(0, Math.PI/2, 0));

    // Upper part of the back wall (for the nave)
    const backClerestoryGeo = new THREE.PlaneGeometry(naveWidth, clerestoryHeight);
    const backClerestoryMat = wallMaterial.clone();
    backClerestoryMat.map = wallTexture.clone();
    backClerestoryMat.map.repeat.set(naveWidth / 4, clerestoryHeight / 4);
    createMesh(backClerestoryGeo, backClerestoryMat, new THREE.Vector3(0, aisleHeight + clerestoryHeight / 2, -length / 2));

    // 6. Nave's Vaulted Roof
    const roofPanelWidth = Math.sqrt(Math.pow(naveWidth / 2, 2) + Math.pow(roofPeakHeight, 2));
    const roofAngle = Math.atan2(roofPeakHeight, naveWidth / 2);
    const roofGeo = new THREE.PlaneGeometry(roofPanelWidth, length); // Swapped width and length
    const roofMat = wallMaterial.clone();
    roofMat.map = wallTexture.clone();
    roofMat.map.repeat.set(roofPanelWidth / 4, length / 4);

    // Left and Right roof panels
    createMesh(roofGeo, roofMat,
        new THREE.Vector3(-naveWidth / 4, naveHeight + roofPeakHeight / 2, 0),
        new THREE.Euler(Math.PI / 2, roofAngle, 0) // Flipped the roof right side up
    );
    createMesh(roofGeo, roofMat,
        new THREE.Vector3(naveWidth / 4, naveHeight + roofPeakHeight / 2, 0),
        new THREE.Euler(Math.PI / 2, -roofAngle, 0) // Flipped the roof right side up
    );

    // 7. Back gable wall (triangle part)
    const gableShape = new THREE.Shape();
    gableShape.moveTo(-naveWidth / 2, naveHeight);
    gableShape.lineTo(naveWidth / 2, naveHeight);
    gableShape.lineTo(0, naveHeight + roofPeakHeight);
    const gableGeo = new THREE.ShapeGeometry(gableShape);
    const gableMat = wallMaterial.clone();
    gableMat.map = wallTexture.clone();
    gableMat.map.repeat.set(naveWidth / 8, roofPeakHeight / 8);
    createMesh(gableGeo, gableMat, new THREE.Vector3(0, 0, -length / 2));

        // Note: crawlSurfaces and landingSurfaces might need to be updated if spiders/rats are used.
    }

    update(deltaTime) {
    // Add any per-frame update logic here, if needed
    }
}
new RoomWalls();
