import * as THREE from 'three'
import {
  EffectComposer,
  EffectPass,
  RenderPass,
  BloomEffect,
  SSAOEffect,
  DepthOfFieldEffect,
  NormalPass,
  SMAAEffect
} from 'postprocessing'

export class PostProcessingManager {
  private composer: EffectComposer
  private bloomEffect: BloomEffect
  private ssaoEffect: SSAOEffect
  private depthOfFieldEffect: DepthOfFieldEffect
  private normalPass: NormalPass

  constructor(
    renderer: THREE.WebGLRenderer,
    scene: THREE.Scene,
    camera: THREE.PerspectiveCamera
  ) {
    // Create effect composer
    this.composer = new EffectComposer(renderer)

    // Add render pass (renders the scene)
    const renderPass = new RenderPass(scene, camera)
    this.composer.addPass(renderPass)

    // Create normal pass for SSAO
    this.normalPass = new NormalPass(scene, camera)
    this.composer.addPass(this.normalPass)

    // Create bloom effect - enhanced for more dramatic glow
    this.bloomEffect = new BloomEffect({
      intensity: 1.2,
      luminanceThreshold: 0.1,
      luminanceSmoothing: 0.15,
      radius: 0.9,
      mipmapBlur: true
    })

    // Create SSAO effect - enhanced for better ambient occlusion
    this.ssaoEffect = new SSAOEffect(camera, this.normalPass.texture, {
      intensity: 0.8,
      fade: 0.01,
      radius: 0.15,
      samples: 32,
      rings: 4,
      worldDistanceThreshold: 20,
      worldDistanceFalloff: 5,
      worldProximityThreshold: 0.0005,
      worldProximityFalloff: 0.001,
      luminanceInfluence: 0.7,
      bias: 0.02
    })

    // Create depth of field effect - tighter focus for more dramatic effect
    this.depthOfFieldEffect = new DepthOfFieldEffect(camera, {
      focusDistance: 0.015,  // Closer focus point
      focalLength: 0.12,     // Shorter focal length for stronger blur
      bokehScale: 4.0,       // Larger bokeh for more pronounced blur
      height: 480
    })

    // Create SMAA effect for better antialiasing
    const smaaEffect = new SMAAEffect()

    // Combine effects in a single pass for better performance
    const effectPass = new EffectPass(
      camera,
      this.bloomEffect,
      this.ssaoEffect,
      this.depthOfFieldEffect,
      smaaEffect
    )

    this.composer.addPass(effectPass)
  }

  public render(deltaTime?: number): void {
    this.composer.render(deltaTime)
  }

  public resize(width: number, height: number): void {
    this.composer.setSize(width, height)
  }

  // Control methods for real-time adjustments
  public setBloomIntensity(intensity: number): void {
    this.bloomEffect.intensity = intensity
  }

  public setSSAOIntensity(intensity: number): void {
    this.ssaoEffect.intensity = intensity
  }

  public setDepthOfFieldFocus(focusDistance: number): void {
    this.depthOfFieldEffect.circleOfConfusionMaterial.uniforms.focusDistance.value = focusDistance
  }

  // Get the composer for advanced usage
  public getComposer(): EffectComposer {
    return this.composer
  }

  // Update method for any per-frame updates
  public update(_deltaTime: number): void {
    // Add any custom update logic here if needed
  }

  // Dispose method for cleanup
  public dispose(): void {
    this.composer.dispose()
    this.bloomEffect.dispose()
    this.ssaoEffect.dispose()
    this.depthOfFieldEffect.dispose()
    this.normalPass.dispose()
  }
}
