import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';

export function createScene() {
  // Scene setup
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.setFocalLength(50);
  const raycaster = new THREE.Raycaster();
  const mouse = new THREE.Vector2();

  // Renderer setup
  const renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setClearColor(0x000000);
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  renderer.toneMapping = THREE.ACESFilmicToneMapping;
  renderer.toneMappingExposure = 1.2;
  renderer.outputColorSpace = THREE.SRGBColorSpace;
  renderer.physicallyCorrectLights = true;
  document.body.appendChild(renderer.domElement);

  // Post-processing: Bloom
  const composer = new EffectComposer(renderer);
  const renderPass = new RenderPass(scene, camera);
  composer.addPass(renderPass);

  const bloomPass = new UnrealBloomPass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    1.0, // strength
    0.45, // radius
    0.85 // threshold
  );
  composer.addPass(bloomPass);

  // Local procedural environment for better PBR response (no network)
  const pmrem = new THREE.PMREMGenerator(renderer);
  const roomEnv = new RoomEnvironment();
  scene.environment = pmrem.fromScene(roomEnv).texture;
  pmrem.dispose();
  roomEnv.dispose();
  scene.environment = null; // This will make the renderer's clear color visible again

  return { scene, camera, renderer, composer, raycaster, mouse };
}

export function setupLighting(scene, camera) {
  // Consistent Lighting Setup
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
  scene.add(ambientLight);

  const hemiLight = new THREE.HemisphereLight(0xffffff, 0x666666, 1.5);
  hemiLight.position.set(0, 20, 0);
  scene.add(hemiLight);

  const fillLight = new THREE.DirectionalLight(0xffffff, 1.2);
  fillLight.position.set(-12, 6, -8);
  scene.add(fillLight);

  const topLight = new THREE.DirectionalLight(0xffffff, 1.5);
  topLight.position.set(5, 15, 5);
  scene.add(topLight);

  const bottomLight = new THREE.DirectionalLight(0xffffff, 0.8);
  bottomLight.position.set(-3, -8, 3);
  scene.add(bottomLight);

  const leftLight = new THREE.DirectionalLight(0xffffff, 1.0);
  leftLight.position.set(-12, 2, 5);
  scene.add(leftLight);

  const rightLight = new THREE.DirectionalLight(0xffffff, 1.0);
  rightLight.position.set(12, 2, -5);
  scene.add(rightLight);

  const frontLight = new THREE.DirectionalLight(0xffffff, 0.8);
  frontLight.position.set(8, 4, 12);
  scene.add(frontLight);

  const backLight = new THREE.DirectionalLight(0xffffff, 0.8);
  backLight.position.set(-8, 4, -12);
  scene.add(backLight);

  const cameraLight = new THREE.PointLight(0xffffff, 0.8, 0, 2);
  camera.add(cameraLight);
  scene.add(camera);
}

export function setupControls(camera, renderer) {
  // Controls with zoom disabled and camera constraints
  const controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.dampingFactor = 0.25;
  controls.enableZoom = false; // Disable zoom

  // Add camera constraints to prevent extreme angles
  controls.maxPolarAngle = Math.PI * 0.8; // Prevent looking too far up
  controls.minPolarAngle = Math.PI * 0.2; // Prevent looking too far down

  console.log('Orbit controls initialized with camera constraints');
  return controls;
}
