import * as THREE from 'three';
import { state } from '../state.js';
import { fireVertexShader, fireFragmentShader } from '../shaders/fire-shaders.js';
import stoneTextureUrl from '/textures/stone_floor.png';

let fireMaterial;
let fireLight;

export function createFireplace(x, z, rotY) {
    const fireplaceGroup = new THREE.Group();

    // --- Materials ---
    const stoneTexture = state.loader.load(stoneTextureUrl);
    stoneTexture.wrapS = THREE.RepeatWrapping;
    stoneTexture.wrapT = THREE.RepeatWrapping;
    stoneTexture.repeat.set(2, 2);
    const stoneMaterial = new THREE.MeshPhongMaterial({ map: stoneTexture, color: 0x999999, shininess: 10 });

    const hearthWidth = 2.5;
    const hearthHeight = 0.2;
    const hearthDepth = 1.5;

    // 1. Hearth (base)
    const hearthGeo = new THREE.BoxGeometry(hearthWidth, hearthHeight, hearthDepth);
    const hearth = new THREE.Mesh(hearthGeo, stoneMaterial);
    hearth.position.y = hearthHeight / 2;
    hearth.receiveShadow = true;
    fireplaceGroup.add(hearth);

    // 2. Fireplace Body
    const bodyWidth = 2.2;
    const bodyHeight = 2.0;
    const bodyDepth = 0.8;
    const bodyGeo = new THREE.BoxGeometry(bodyWidth, bodyHeight, bodyDepth);
    const body = new THREE.Mesh(bodyGeo, stoneMaterial);
    body.position.y = hearthHeight + bodyHeight / 2;
    body.castShadow = true;
    body.receiveShadow = true;
    fireplaceGroup.add(body);

    // 3. Fireplace Opening (carved out look)
    const openingWidth = 1.2;
    const openingHeight = 1.0;
    const openingGeo = new THREE.BoxGeometry(openingWidth, openingHeight, bodyDepth);
    const openingMaterial = new THREE.MeshPhongMaterial({ color: 0x1a1a1a }); // Dark interior
    const opening = new THREE.Mesh(openingGeo, openingMaterial);
    opening.position.set(0, hearthHeight + openingHeight / 2, 0.01);
    fireplaceGroup.add(opening);

    // 3.5. Thick Stone Frame around Opening
    const frameThickness = 0.2;
    const frameDepth = bodyDepth * 0.25; // Make it stick out a bit

    // Lintel (Top Frame)
    const lintelWidth = openingWidth + 2 * frameThickness;
    const lintelGeo = new THREE.BoxGeometry(lintelWidth, frameThickness, frameDepth);
    const lintel = new THREE.Mesh(lintelGeo, stoneMaterial);
    lintel.position.set(0, hearthHeight + openingHeight + frameThickness / 2, bodyDepth / 2 + frameDepth / 2);
    lintel.castShadow = true;
    lintel.receiveShadow = true;
    fireplaceGroup.add(lintel);

    // Jambs (Side Frames)
    const jambHeight = openingHeight + frameThickness; // Go up to the lintel
    const jambGeo = new THREE.BoxGeometry(frameThickness, jambHeight, frameDepth);
    
    const leftJamb = new THREE.Mesh(jambGeo, stoneMaterial);
    leftJamb.position.set(-openingWidth / 2 - frameThickness / 2, hearthHeight + jambHeight / 2, bodyDepth / 2 + frameDepth / 2);
    fireplaceGroup.add(leftJamb);

    const rightJamb = new THREE.Mesh(jambGeo, stoneMaterial);
    rightJamb.position.set(openingWidth / 2 + frameThickness / 2, hearthHeight + jambHeight / 2, bodyDepth / 2 + frameDepth / 2);
    fireplaceGroup.add(rightJamb);

    // 4. Animated Fire
    fireMaterial = new THREE.ShaderMaterial({
        uniforms: {
            u_time: { value: 0.0 },
        },
        vertexShader: fireVertexShader,
        fragmentShader: fireFragmentShader,
        transparent: true,
        depthWrite: false,
    });
    const fireGeo = new THREE.PlaneGeometry(openingWidth * 1.2, openingHeight * 1.2);
    const firePlane = new THREE.Mesh(fireGeo, fireMaterial);
    firePlane.position.set(0, hearthHeight + openingHeight / 2, 0.42);
    fireplaceGroup.add(firePlane);

    // 5. Fire Light
    fireLight = new THREE.PointLight(0xffaa33, 1.5, 8);
    fireLight.position.set(0, hearthHeight + openingHeight / 2, 0.3);
    fireLight.castShadow = true;
    fireLight.shadow.mapSize.width = 512;
    fireLight.shadow.mapSize.height = 512;
    fireplaceGroup.add(fireLight);

    // Position and add to scene
    fireplaceGroup.position.set(x, 0, z);
    fireplaceGroup.rotation.y = rotY;
    state.scene.add(fireplaceGroup);
}

export function updateFire() {
    if (!fireMaterial || !fireLight) return;

    // Animate shader time
    fireMaterial.uniforms.u_time.value = state.clock.getElapsedTime();

    // Flicker light
    const flicker = Math.random() * 0.4;
    fireLight.intensity = 1.2 + flicker;
    fireLight.position.y = 0.2 + 1.0 / 2 + (Math.random() - 0.5) * 0.1;
}