import * as THREE from 'three'
	import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
	import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
	import { RenderPixelatedPass } from 'three/addons/postprocessing/RenderPixelatedPass.js';
	import { OutputPass } from 'three/addons/postprocessing/OutputPass.js';

	let scene, camera, renderer
	let aspect, frustumSize
	let time = 0
	let lastTime = 0
	let controls
	let mesh
	let composer
	let pixelSize = 3
	let container_element = document.getElementById('container-article')
	
	let containerW = container_element.offsetWidth
	let containerH = container_element.offsetHeight

	let imgW, imgH, imgRatio

	var clock = new THREE.Clock();


	function init(){
		SetupRenderer()
		scene = new THREE.Scene()
		SetupCamera()
		SetupControls()

		composer = new EffectComposer( renderer );
		if (window.innerWidth < 1024 )
		{
			pixelSize = 1.5
		}
		const renderPixelatedPass = new RenderPixelatedPass( pixelSize, scene, camera );
        renderPixelatedPass.normalEdgeStrength = 1;
        renderPixelatedPass.depthEdgeStrength = 1;
        renderPixelatedPass.pixelAlignedPanning = false;
		composer.addPass( renderPixelatedPass );

		const outputPass = new OutputPass();
		composer.addPass( outputPass );
		
		AddLights()

		const textureLoader = new THREE.TextureLoader()
		textureLoader.crossOrigin = "Anonymous"
		const texture = textureLoader.load(imageUrl, function ( tex ) {
			// tex and texture are the same in this example, but that might not always be the case
			imgW = tex.image.width
			imgH = tex.image.height
			imgRatio = imgW / imgH

			tex.minFilter = THREE.NearestFilter
			tex.colorSpace = THREE.SRGBColorSpace;
			tex.wrapS = THREE.RepeatWrapping;
			tex.wrapT = THREE.RepeatWrapping;
			const geom = new THREE.PlaneGeometry(imgRatio, 1)
			const mat = new THREE.MeshPhongMaterial({map: texture})
			mesh = new THREE.Mesh(geom, mat)
			scene.add(mesh)
			container_element.style.opacity = 1;
			animate()
		} );
	}

	function SetupRenderer(){
		renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
		renderer.setClearColor(0xffffff, 0);
		renderer.setSize(containerW, containerH)
		document.getElementById('container-article').appendChild(renderer.domElement)
	}

	function SetupCamera(){
		aspect = (containerW) / (containerH)
		frustumSize = 0.5
		camera = new THREE.OrthographicCamera(
			frustumSize * aspect / -2,
			frustumSize * aspect / 2,
			frustumSize / 2,
			frustumSize / -2,
			0.01,
			5000
		)

		camera.position.x = 5
	}

	function SetupControls(){
		controls = new OrbitControls(camera, renderer.domElement)
		controls.enableRotate = false;
		controls.enablePan = false
		controls.zoomToCursor = false;
		controls.mouseButtons = {
			RIGHT: THREE.MOUSE.ROTATE,
			MIDDLE: THREE.MOUSE.DOLLY,
			LEFT: THREE.MOUSE.PAN
		}
		controls.minZoom = 0.3
		controls.maxZoom = 0.75
		camera.position.set(0, 0, 5)

		controls.update()
	}

	function AddLights() {
		// Add Ambient Light
		const ambientLight = new THREE.AmbientLight(0xffffff, 3); // Soft white light
		scene.add(ambientLight);
	
		// Add Directional Light
		const directionalLight = new THREE.DirectionalLight(0x0075FF, 4); // Soft white light
		directionalLight.position.set(-5, 0, 5).normalize();
		//scene.add(directionalLight);
	}

	function animate(){
		requestAnimationFrame(animate)
		const deltaTime = (time - lastTime) / 1000
		controls.update()
		let sin = Math.sin(clock.getElapsedTime() * 0.5)
		mesh.rotation.z = sin * 0.1
		mesh.rotation.x = sin * 0.15
		composer.render()
	}

	function getContainerDimensions(){
		containerW = container_element.offsetWidth
		containerH = container_element.offsetHeight
	}

	window.addEventListener('resize', () => {
		getContainerDimensions()
		aspect = (containerW) / (containerH)
		camera.left = -frustumSize * aspect / 2
		camera.right = frustumSize * aspect / 2
		camera.top = frustumSize / 2
		camera.bottom = -frustumSize / 2
		camera.updateProjectionMatrix()
		renderer.setPixelRatio(window.devicePixelRatio)
		renderer.setSize(containerW, containerH)
	})


	init()