/// file: public/assets/js/modules/home-diamond/post-pass.js

import {
  CHROMATIC_EDGE_MUL,
  CHROMATIC_PX,
  VIGNETTE_RADIUS,
  VIGNETTE_STRENGTH,
} from './constants.js';

/**
 * Fullscreen pass: subtle radial chromatic aberration + vignette (no EffectComposer).
 * @param {typeof import('three')} THREE
 * @param {import('three').WebGLRenderer} renderer
 */
export function createChromaticVignettePass(THREE, renderer) {
  const vs = `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = vec4(position.xy, 0.0, 1.0);
    }
  `;

  const fs = `
    uniform sampler2D tDiffuse;
    uniform vec2 resolution;
    uniform float chromaticAmt;
    uniform float chromaticEdgeMul;
    uniform float vignetteStrength;
    uniform float vignetteRadius;
    varying vec2 vUv;

    void main() {
      vec2 uv = vUv;
      vec2 c = uv - 0.5;
      float r = length(c);
      float edge = smoothstep(vignetteRadius, 0.98, r);
      float caMul = mix(1.0, chromaticEdgeMul, edge);
      vec2 dir = length(c) > 1e-5 ? normalize(c) : vec2(1.0, 0.0);
      float off = chromaticAmt * caMul;

      vec4 base = texture2D(tDiffuse, uv);
      float rCh = texture2D(tDiffuse, uv + dir * off).r;
      float gCh = base.g;
      float bCh = texture2D(tDiffuse, uv - dir * off).b;
      vec3 col = vec3(rCh, gCh, bCh);

      float vig = 1.0 - vignetteStrength * edge * edge;
      gl_FragColor = vec4(col * vig, base.a);
    }
  `;

  const material = new THREE.ShaderMaterial({
    uniforms: {
      tDiffuse: { value: null },
      resolution: { value: new THREE.Vector2(1, 1) },
      chromaticAmt: { value: CHROMATIC_PX },
      chromaticEdgeMul: { value: CHROMATIC_EDGE_MUL },
      vignetteStrength: { value: VIGNETTE_STRENGTH },
      vignetteRadius: { value: VIGNETTE_RADIUS },
    },
    vertexShader: vs,
    fragmentShader: fs,
    depthTest: false,
    depthWrite: false,
  });

  const quad = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material);
  const postScene = new THREE.Scene();
  postScene.add(quad);

  const ortho = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);

  const rt = new THREE.WebGLRenderTarget(1, 1, {
    minFilter: THREE.LinearFilter,
    magFilter: THREE.LinearFilter,
    format: THREE.RGBAFormat,
    type: THREE.UnsignedByteType,
    depthBuffer: true,
    stencilBuffer: false,
  });
  let enabled = true;

  /** Match main framebuffer size (accounts for renderer pixel ratio). */
  function syncSize() {
    const el = renderer.domElement;
    const w = Math.max(1, el.width || 1);
    const h = Math.max(1, el.height || 1);
    rt.setSize(w, h);
    material.uniforms.resolution.value.set(w, h);
  }

  function setEnabled(v) {
    enabled = v;
  }

  function render(scene, camera) {
    if (!enabled) {
      renderer.setRenderTarget(null);
      renderer.render(scene, camera);
      return;
    }
    renderer.setRenderTarget(rt);
    renderer.render(scene, camera);
    material.uniforms.tDiffuse.value = rt.texture;
    renderer.setRenderTarget(null);
    renderer.render(postScene, ortho);
  }

  function dispose() {
    material.dispose();
    quad.geometry.dispose();
    rt.dispose();
  }

  return {
    syncSize,
    setEnabled,
    render,
    dispose,
    get enabled() {
      return enabled;
    },
  };
}
