import * as THREE from 'three';

export class Graphics {
    constructor() {
        // Main scene rendering
        this.scene = new THREE.Scene();
        this.scene.fog = new THREE.Fog(0x000000, 2, 12);
        this.scene.background = new THREE.Color(0x000000);

        this.camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100);

        // Real Screen Renderer
        this.renderer = new THREE.WebGLRenderer({ antialias: false });
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.renderer.domElement.id = 'three-canvas';

        // Append to the correct container, not body directly
        const container = document.getElementById('game-container');
        if (container) container.appendChild(this.renderer.domElement);
        else document.body.appendChild(this.renderer.domElement);

        // --- Retro Pipeline Setup ---
        this.targetWidth = 320;
        this.targetHeight = 240;

        this.renderTarget = new THREE.WebGLRenderTarget(this.targetWidth, this.targetHeight, {
            minFilter: THREE.NearestFilter,
            magFilter: THREE.NearestFilter,
            format: THREE.RGBAFormat
        });

        this.postCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
        this.postScene = new THREE.Scene();

        const planeGeometry = new THREE.PlaneGeometry(2, 2);

        const postMaterial = new THREE.ShaderMaterial({
            uniforms: {
                tDiffuse: { value: this.renderTarget.texture },
                colorDepth: { value: 24.0 } // 24 levels
            },
            vertexShader: `
                varying vec2 vUv;
                void main() {
                    vUv = uv;
                    gl_Position = vec4(position, 1.0);
                }
            `,
            fragmentShader: `
                uniform sampler2D tDiffuse;
                uniform float colorDepth;
                varying vec2 vUv;
                void main() {
                    vec4 tex = texture2D(tDiffuse, vUv);
                    vec3 color = floor(tex.rgb * colorDepth + 0.5) / colorDepth;
                    gl_FragColor = vec4(color, tex.a);
                }
            `
        });

        this.postQuad = new THREE.Mesh(planeGeometry, postMaterial);
        this.postScene.add(this.postQuad);

        this.handleResize();
        window.addEventListener('resize', this.handleResize.bind(this));
    }

    init() { }

    handleResize() {
        const aspect = window.innerWidth / window.innerHeight;
        this.camera.aspect = aspect;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.targetHeight = Math.floor(this.targetWidth / aspect);
        this.renderTarget.setSize(this.targetWidth, this.targetHeight);
    }

    render() {
        // 1. Render 3D Scene to RenderTarget
        this.renderer.setRenderTarget(this.renderTarget);
        this.renderer.render(this.scene, this.camera);

        // 2. Render Post-Processing Quad to Screen
        this.renderer.setRenderTarget(null);
        this.renderer.render(this.postScene, this.postCamera);
    }
}
