'use client';
import { useEffect, useRef } from 'react';

/** Bağımsız WebGL equirectangular (360°) görüntüleyici: tam ekran quad + fragment shader.
 *  Sürükle = bakış yönü, tekerlek/çimdik = yakınlaştırma. Harici kütüphane yok. */
export function PanoViewer({ src }: { src: string }) {
  const canvas = useRef<HTMLCanvasElement>(null);
  useEffect(() => {
    const cv = canvas.current!; const gl = cv.getContext('webgl'); if (!gl) return;
    const vs = `attribute vec2 p; varying vec2 uv; void main(){ uv=p; gl_Position=vec4(p,0.,1.); }`;
    const fs = `precision highp float; varying vec2 uv; uniform sampler2D t; uniform vec2 res; uniform float yaw, pitch, fov;
      const float PI=3.14159265;
      void main(){
        vec2 ndc = uv * vec2(res.x/res.y, 1.0) * tan(fov*0.5);
        vec3 dir = normalize(vec3(ndc.x, ndc.y, -1.0));
        float cy=cos(pitch), sy=sin(pitch); dir=vec3(dir.x, cy*dir.y - sy*dir.z, sy*dir.y + cy*dir.z);
        float cx=cos(yaw), sx=sin(yaw); dir=vec3(cx*dir.x + sx*dir.z, dir.y, -sx*dir.x + cx*dir.z);
        float u = atan(dir.x, -dir.z)/(2.0*PI)+0.5;
        float v = acos(clamp(dir.y,-1.0,1.0))/PI;
        gl_FragColor = texture2D(t, vec2(u, v));
      }`;
    const mk = (type: number, src: string) => { const s = gl.createShader(type)!; gl.shaderSource(s, src); gl.compileShader(s); return s; };
    const prog = gl.createProgram()!; gl.attachShader(prog, mk(gl.VERTEX_SHADER, vs)); gl.attachShader(prog, mk(gl.FRAGMENT_SHADER, fs)); gl.linkProgram(prog); gl.useProgram(prog);
    const buf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buf);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
    const loc = gl.getAttribLocation(prog, 'p'); gl.enableVertexAttribArray(loc); gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
    const U = (n: string) => gl.getUniformLocation(prog, n);
    const tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([40, 44, 38, 255]));

    const state = { yaw: 0, pitch: 0, fov: 1.1, drag: false, px: 0, py: 0, auto: true };
    const img = new Image(); img.crossOrigin = 'anonymous'; img.src = src;
    img.onload = () => { gl.bindTexture(gl.TEXTURE_2D, tex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); };

    let raf = 0;
    const resize = () => { const d = Math.min(window.devicePixelRatio || 1, 2); cv.width = cv.clientWidth * d; cv.height = cv.clientHeight * d; gl.viewport(0, 0, cv.width, cv.height); };
    const draw = () => {
      if (state.auto) state.yaw += 0.0012;
      gl.uniform2f(U('res'), cv.width, cv.height); gl.uniform1f(U('yaw'), state.yaw); gl.uniform1f(U('pitch'), state.pitch); gl.uniform1f(U('fov'), state.fov);
      gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); raf = requestAnimationFrame(draw);
    };
    resize(); draw();
    const ro = new ResizeObserver(resize); ro.observe(cv);
    const down = (x: number, y: number) => { state.drag = true; state.auto = false; state.px = x; state.py = y; };
    const move = (x: number, y: number) => { if (!state.drag) return; state.yaw -= (x - state.px) * 0.005 * state.fov; state.pitch = Math.max(-1.4, Math.min(1.4, state.pitch + (y - state.py) * 0.005 * state.fov)); state.px = x; state.py = y; };
    const up = () => { state.drag = false; };
    const md = (e: MouseEvent) => down(e.clientX, e.clientY); const mm = (e: MouseEvent) => move(e.clientX, e.clientY);
    const td = (e: TouchEvent) => down(e.touches[0].clientX, e.touches[0].clientY);
    const tm = (e: TouchEvent) => { move(e.touches[0].clientX, e.touches[0].clientY); e.preventDefault(); };
    const wheel = (e: WheelEvent) => { state.fov = Math.max(0.5, Math.min(2.0, state.fov + e.deltaY * 0.001)); e.preventDefault(); };
    cv.addEventListener('mousedown', md); window.addEventListener('mousemove', mm); window.addEventListener('mouseup', up);
    cv.addEventListener('touchstart', td, { passive: true }); cv.addEventListener('touchmove', tm, { passive: false }); cv.addEventListener('touchend', up);
    cv.addEventListener('wheel', wheel, { passive: false });
    return () => { cancelAnimationFrame(raf); ro.disconnect(); cv.removeEventListener('mousedown', md); window.removeEventListener('mousemove', mm); window.removeEventListener('mouseup', up); cv.removeEventListener('touchstart', td); cv.removeEventListener('touchmove', tm); cv.removeEventListener('touchend', up); cv.removeEventListener('wheel', wheel); };
  }, [src]);
  return <canvas ref={canvas} className="h-full w-full cursor-grab touch-none active:cursor-grabbing" aria-label="360 derece sanal tur" />;
}
