"use client";

import { useEffect, useRef, useState, Suspense, useMemo } from "react";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { motion, AnimatePresence } from "framer-motion";
import { Canvas, useFrame, useThree } from "@react-three/fiber";
import { useTexture } from "@react-three/drei";
import * as THREE from "three";
import Image from "next/image";

gsap.registerPlugin(ScrollTrigger);

// Custom shader source for storefront door clipping
const vertexShader = `
  varying vec2 vUv;
  void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }
`;

const facadeFragmentShader = `
  uniform sampler2D uTexture;
  uniform float uOpacity;
  varying vec2 vUv;
  void main() {
    vec4 col = texture2D(uTexture, vUv);
    // Discard double doors in center of storefront
    if (vUv.x >= 0.46 && vUv.x <= 0.54 && vUv.y >= 0.10 && vUv.y <= 0.52) {
      discard;
    }
    gl_FragColor = vec4(col.rgb, col.a * uOpacity);
  }
`;

const leftDoorFragmentShader = `
  uniform sampler2D uTexture;
  uniform float uOpacity;
  varying vec2 vUv;
  void main() {
    // Crop texture to left door leaf boundaries
    vec2 uv = vec2(0.46 + vUv.x * 0.04, 0.10 + vUv.y * 0.42);
    vec4 col = texture2D(uTexture, uv);
    gl_FragColor = vec4(col.rgb, col.a * uOpacity);
  }
`;

const rightDoorFragmentShader = `
  uniform sampler2D uTexture;
  uniform float uOpacity;
  varying vec2 vUv;
  void main() {
    // Crop texture to right door leaf boundaries
    vec2 uv = vec2(0.50 + vUv.x * 0.04, 0.10 + vUv.y * 0.42);
    vec4 col = texture2D(uTexture, uv);
    gl_FragColor = vec4(col.rgb, col.a * uOpacity);
  }
`;

// Helper notifier to hide CSS loader once textures resolve
function LoaderNotifier({ onLoad }: { onLoad: () => void }) {
  useEffect(() => {
    onLoad();
  }, [onLoad]);
  return null;
}

// 3D Cinematic flight renderer
function CinematicFlight({ progress }: { progress: number }) {
  const exteriorTex = useTexture("/images/my_dosa_place_exterior_webgl.jpg");
  const interiorTex = useTexture("/images/my_dosa_place_interior_webgl.jpg");
  const foodTex = useTexture("/images/my_dosa_place_food_webgl.jpg");

  const leftDoorRef = useRef<THREE.Group>(null);
  const rightDoorRef = useRef<THREE.Group>(null);

  // Set texture filtering to high quality linear
  useEffect(() => {
    [exteriorTex, interiorTex, foodTex].forEach((tex) => {
      tex.minFilter = THREE.LinearFilter;
      tex.magFilter = THREE.LinearFilter;
      tex.generateMipmaps = false;
    });
  }, [exteriorTex, interiorTex, foodTex]);

  const { width, height } = useThree((state) => state.viewport);

  // Compute facade dimensions based on dusk photo aspect ratio
  const aspect = 1920 / 864; 
  const planeH = height;
  const planeW = planeH * aspect;

  // Door dimensions matching facade coordinate percentages
  const dw = 0.04 * planeW;
  const dh = 0.42 * planeH;
  const doorY = -0.19 * planeH;
  const leftHingeX = -0.04 * planeW;
  const rightHingeX = 0.04 * planeW;

  const extGroupRef = useRef<THREE.Group>(null);
  const intMeshRef = useRef<THREE.Mesh>(null);
  const foodMeshRef = useRef<THREE.Mesh>(null);

  // Refs for materials to update opacities in the high-performance frame loop
  const facadeMatRef = useRef<THREE.ShaderMaterial>(null);
  const leftDoorMatRef = useRef<THREE.ShaderMaterial>(null);
  const rightDoorMatRef = useRef<THREE.ShaderMaterial>(null);
  const intMatRef = useRef<THREE.MeshBasicMaterial>(null);
  const foodMatRef = useRef<THREE.MeshBasicMaterial>(null);

  // Smooth frame loop camera zoom and door swing animations
  useFrame(() => {
    // 1. Storefront zoom and centering translation
    // Scale goes from 1.0 to 5.5
    const targetExtScale = 1.0 + progress * 4.5;
    if (extGroupRef.current) {
      extGroupRef.current.scale.setScalar(THREE.MathUtils.lerp(extGroupRef.current.scale.x, targetExtScale, 0.08));
      // Pan Y upward to center the doors as we scale
      const currentScale = extGroupRef.current.scale.x;
      const targetY = -doorY * (currentScale - 1.0);
      extGroupRef.current.position.y = THREE.MathUtils.lerp(extGroupRef.current.position.y, targetY, 0.08);
    }

    // 2. Door opening rotation (swing inward Y-axis)
    let doorProgress = 0;
    if (progress >= 0.08 && progress <= 0.25) {
      doorProgress = (progress - 0.08) / 0.17;
    } else if (progress > 0.25) {
      doorProgress = 1;
    }
    const angle = (Math.PI / 1.8) * doorProgress;

    if (leftDoorRef.current) {
      leftDoorRef.current.rotation.y = THREE.MathUtils.lerp(leftDoorRef.current.rotation.y, angle, 0.08);
    }
    if (rightDoorRef.current) {
      rightDoorRef.current.rotation.y = THREE.MathUtils.lerp(rightDoorRef.current.rotation.y, -angle, 0.08);
    }

    // 3. Interior Dining Hall zoom
    // Scale goes from 1.0 to 2.6
    let intProgress = 0;
    if (progress > 0.08) {
      intProgress = Math.min(1, (progress - 0.08) / 0.62);
    }
    const targetIntScale = 1.0 + intProgress * 1.6;
    if (intMeshRef.current) {
      intMeshRef.current.scale.setScalar(THREE.MathUtils.lerp(intMeshRef.current.scale.x, targetIntScale, 0.08));
    }

    // 4. Food Platter landing zoom
    // Scale goes from 0.8 to 1.15
    let foodProgress = 0;
    if (progress > 0.58) {
      foodProgress = Math.min(1, (progress - 0.58) / 0.27);
    }
    const targetFoodScale = 0.8 + foodProgress * 0.35;
    if (foodMeshRef.current) {
      foodMeshRef.current.scale.setScalar(THREE.MathUtils.lerp(foodMeshRef.current.scale.x, targetFoodScale, 0.08));
    }

    // 5. Reactive Opacity Updates inside useFrame to prevent unmounting stutters
    const extOpacity = progress < 0.25 ? 1 : Math.max(0, 1 - (progress - 0.25) / 0.15);
    
    let intOpacity = 0;
    if (progress >= 0.08 && progress <= 0.25) {
      intOpacity = (progress - 0.08) / 0.17;
    } else if (progress > 0.25 && progress < 0.60) {
      intOpacity = 1;
    } else if (progress >= 0.60 && progress <= 0.78) {
      intOpacity = Math.max(0, 1 - (progress - 0.60) / 0.18);
    } else if (progress > 0.78) {
      intOpacity = 0;
    }

    const foodOpacity = progress < 0.58 ? 0 : Math.min(1, (progress - 0.58) / 0.20);

    // Apply opacities to materials
    if (facadeMatRef.current) facadeMatRef.current.uniforms.uOpacity.value = extOpacity;
    if (leftDoorMatRef.current) leftDoorMatRef.current.uniforms.uOpacity.value = extOpacity;
    if (rightDoorMatRef.current) rightDoorMatRef.current.uniforms.uOpacity.value = extOpacity;
    if (intMatRef.current) intMatRef.current.opacity = intOpacity;
    if (foodMatRef.current) foodMatRef.current.opacity = foodOpacity;
  });

  // Memoize initial shader uniforms
  const facadeUniforms = useMemo(() => ({
    uTexture: { value: exteriorTex },
    uOpacity: { value: 1 }
  }), [exteriorTex]);

  const leftDoorUniforms = useMemo(() => ({
    uTexture: { value: exteriorTex },
    uOpacity: { value: 1 }
  }), [exteriorTex]);

  const rightDoorUniforms = useMemo(() => ({
    uTexture: { value: exteriorTex },
    uOpacity: { value: 1 }
  }), [exteriorTex]);

  return (
    <>
      <ambientLight intensity={1.5} />
      <directionalLight position={[0, 5, 5]} intensity={1.5} />

      {/* Plane 1: Storefront Facade & 3D Swinging Door Panels (Z = 0.02) */}
      <group ref={extGroupRef} position={[0, 0, 0.02]}>
        <mesh>
          <planeGeometry args={[planeW, planeH]} />
          <shaderMaterial
            ref={facadeMatRef}
            vertexShader={vertexShader}
            fragmentShader={facadeFragmentShader}
            uniforms={facadeUniforms}
            transparent
            depthWrite={false}
          />
        </mesh>

        {/* Left Door Hinge Pivot Group */}
        <group ref={leftDoorRef} position={[leftHingeX, doorY, 0.002]}>
          <mesh position={[dw / 2, 0, 0]}>
            <planeGeometry args={[dw, dh]} />
            <shaderMaterial
              ref={leftDoorMatRef}
              vertexShader={vertexShader}
              fragmentShader={leftDoorFragmentShader}
              uniforms={leftDoorUniforms}
              transparent
              depthWrite={false}
            />
          </mesh>
        </group>

        {/* Right Door Hinge Pivot Group */}
        <group ref={rightDoorRef} position={[rightHingeX, doorY, 0.002]}>
          <mesh position={[-dw / 2, 0, 0]}>
            <planeGeometry args={[dw, dh]} />
            <shaderMaterial
              ref={rightDoorMatRef}
              vertexShader={vertexShader}
              fragmentShader={rightDoorFragmentShader}
              uniforms={rightDoorUniforms}
              transparent
              depthWrite={false}
            />
          </mesh>
        </group>
      </group>

      {/* Plane 2: Pillars Dining Hall (Z = 0.01) */}
      <mesh ref={intMeshRef} position={[0, 0, 0.01]}>
        <planeGeometry args={[planeW * 1.1, planeH * 1.1]} />
        <meshBasicMaterial
          ref={intMatRef}
          map={interiorTex}
          transparent
          opacity={0}
          depthWrite={false}
        />
      </mesh>

      {/* Plane 3: South Indian Platter Table (Z = 0.0) */}
      <mesh ref={foodMeshRef} position={[0, 0, 0.0]}>
        <planeGeometry args={[planeW * 1.1, planeH * 1.1]} />
        <meshBasicMaterial
          ref={foodMatRef}
          map={foodTex}
          transparent
          opacity={0}
          depthWrite={false}
        />
      </mesh>
    </>
  );
}

export default function EntranceExperience({ onProgress }: { onProgress?: (progress: number) => void }) {
  const containerRef = useRef<HTMLDivElement>(null);
  const scrollIndicatorRef = useRef<HTMLDivElement>(null);

  const [scrollProgress, setScrollProgress] = useState(0);
  const [loaded, setLoaded] = useState(false);
  const [isMounted, setIsMounted] = useState(false);

  useEffect(() => {
    setIsMounted(true);
  }, []);

  // Sync GSAP pinning scrub triggers
  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    const ctx = gsap.context(() => {
      const scrollIndicator = scrollIndicatorRef.current;

      const tl = gsap.timeline({
        scrollTrigger: {
          trigger: container,
          start: "top top",
          end: "+=450%", 
          scrub: 1.2,
          pin: true,
          onUpdate: (self) => {
            setScrollProgress(self.progress);
            if (onProgress) {
              onProgress(self.progress);
            }
          },
        },
      });

      // Initial fade-out of the scroll indicator
      if (scrollIndicator) {
        tl.to(scrollIndicator, {
          opacity: 0,
          y: -25,
          duration: 1,
        });
      }
    }, container);

    return () => ctx.revert();
  }, []);

  return (
    <div
      ref={containerRef}
      className="relative w-full h-screen overflow-hidden bg-[#050c08] select-none"
    >
      {/* Traditional loading spinner overlay */}
      {!loaded && (
        <div className="absolute inset-0 flex flex-col justify-center items-center z-50 bg-[#050c08]">
          <div className="w-12 h-12 rounded-full border-2 border-gold/30 border-t-gold animate-spin mb-4" />
          <span className="font-serif text-gold text-sm tracking-[0.3em] uppercase animate-pulse">
            Entering My Dosa Place...
          </span>
        </div>
      )}

      {/* Three.js R3F WebGL Scene */}
      {isMounted && (
        <div className="absolute inset-0 w-full h-full z-0">
          <Canvas>
            <Suspense fallback={null}>
              <CinematicFlight progress={scrollProgress} />
              <LoaderNotifier onLoad={() => setLoaded(true)} />
            </Suspense>
          </Canvas>
        </div>
      )}

      {/* Screen edge lighting overlays */}
      <div className="absolute inset-0 bg-[radial-gradient(circle,_transparent_40%,_rgba(0,0,0,0.5)_95%)] pointer-events-none z-10" />

      {/* ----------------- OVERLAY HERO ELEMENT (OUTSIDE STATE) ----------------- */}
      <div className="absolute inset-0 flex flex-col justify-end items-center pb-20 px-6 z-30 pointer-events-none">
        {/* Scroll Indicator */}
        <div
          ref={scrollIndicatorRef}
          className="flex flex-col items-center gap-3 animate-bounce"
        >
          <div className="w-6 h-10 rounded-full border border-gold/45 flex justify-center p-1">
            <div className="w-1.5 h-2.5 bg-gold rounded-full animate-[scroll-dot_1.5s_infinite_linear]" />
          </div>
        </div>
      </div>

      {/* ----------------- FOOD PLATTER STORYTELLING CARD (REVEALS AT END) ----------------- */}
      <AnimatePresence>
        {scrollProgress > 0.75 && (
          <motion.div
            initial={{ opacity: 0, x: -50, scale: 0.95 }}
            animate={{ opacity: 1, x: 0, scale: 1 }}
            exit={{ opacity: 0, x: -50, scale: 0.95 }}
            transition={{ duration: 0.8, ease: "easeOut" }}
            className="absolute top-28 left-8 z-30 w-[360px] sm:w-[480px] max-w-[calc(100vw-32px)] max-sm:top-auto max-sm:bottom-16 max-sm:left-4 max-sm:right-4 max-sm:mx-auto bg-[#fcfaf2]/95 border-2 border-double border-gold/45 rounded-3xl p-6 sm:p-8 shadow-2xl pointer-events-none"
          >
            {/* Inner traditional gold frame */}
            <div className="absolute top-2 left-2 right-2 bottom-2 border border-gold/15 pointer-events-none rounded-[22px]" />

            <span className="font-sans text-[#188754] text-base sm:text-base tracking-[0.4em] uppercase font-bold block mb-2.5 text-center mt-1">
              AUTHENTIC SOUTH INDIAN · PURE VEGETARIAN
            </span>

            <h3 className="font-serif text-[#188754] text-xl sm:text-2xl tracking-[0.15em] uppercase font-bold mb-3 text-center">
              A Royal Banquet in the Heart of Waterloo
            </h3>

            <div className="w-24 h-[1px] bg-gradient-to-r from-transparent via-[#d8c396] to-transparent mx-auto mb-4" />

            <p className="font-sans text-sm sm:text-lg text-stone-800 leading-relaxed tracking-wider font-medium text-justify">
              A tradition older than memory. The table is set for a royal banquet on fresh banana leaves—dosas roasted in pure ghee to a crisp, golden perfection, slow-simmered sambar, and chutneys hand-ground fresh every morning. Served exactly as it was meant to be. 100% pure vegetarian.
            </p>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Styled inline keyframes animations */}
      <style jsx>{`
        @keyframes scroll-dot {
          0% { transform: translateY(0); opacity: 1; }
          50% { transform: translateY(6px); opacity: 0.3; }
          100% { transform: translateY(0); opacity: 1; }
        }
      `}</style>
    </div>
  );
}
