"use client";
import { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { IMAGE_BASE } from "@/constants";

const PACK_DATA = {
  bgVideo: "bg-videos/JapanBack.mp4",
  pack: "/assets/images/Apocalypse.png",
  cards: [],
};

const ThreeDScene = ({
  isAnimationPlaying,
  setIsAnimationPlaying,
  setIsPlay,
  pack_image,
  cards,
  pack,
  muted,
}) => {
  const [showStack, setShowStack] = useState(false);
  const [isFlinging, setIsFlinging] = useState(false);
  const canvasRef = useRef(null);
  const total = cards?.length || 0;
  const mutedRef = useRef(muted);

  const playSfx = (src) => {
    if (mutedRef.current) return;
    const audio = new Audio(src);
    audio.volume = 0.6;
    audio.play().catch(() => {
      // mobile browsers user gesture ke baghair block kar dete hain
    });
  };

  useEffect(() => {
    mutedRef.current = muted;
  }, [muted]);

  const onStackClick = () => {
    if (!total) return;
    if (isFlinging) return; // double click prevent
    setIsFlinging(true);
  };

  const resolvePackUrl = (p) => {
    const s = (p || "").trim();
    if (!s) return "";

    // full url
    if (s.startsWith("http://") || s.startsWith("https://")) return s;

    // already absolute AND already under /cards
    if (s.startsWith("/cards/")) return s;

    // absolute but missing /cards  → simulate case "/images/..."
    if (s.startsWith("/images/")) return `/cards${s}`;

    // relative path → simulate case "images/..."
    return `/cards/${s.replace(/^\/+/, "")}`;
  };

  PACK_DATA.pack = resolvePackUrl(pack_image);

  const SPREAD_DELAY = 2.2;

  useEffect(() => {
    let stackTriggered = false;
    const CUT_AT = 0.55;

    const myClass = document.querySelector(".main-card");
    myClass.classList.add("animation-cards");
    const canvasSize = {
      width: window.innerWidth,
      height: window.innerHeight,
    };

    const sceneData = {
      frontTextures: [],
    };

    const scene = new THREE.Scene();
    scene.background = null;

    const camera = new THREE.PerspectiveCamera(
      50,
      canvasSize.width / canvasSize.height,
      0.1,
      4000,
    );
    camera.position.set(34, 0.2, -0.2);

    camera.aspect = canvasSize.width / canvasSize.height;
    camera.updateProjectionMatrix();

    const renderer = new THREE.WebGLRenderer({
      antialias: true,
      alpha: true,
      canvas: canvasRef.current,
      useLegacyLights: false,
      preserveDrawingBuffer: true,
    });
    // ✅ COLOR FIX — YAHAN ADD KARO
    THREE.ColorManagement.enabled = true;

    renderer.outputColorSpace = THREE.SRGBColorSpace;
    renderer.toneMapping = THREE.NoToneMapping;
    renderer.toneMappingExposure = 1;

    renderer.setPixelRatio(window.devicePixelRatio);

    renderer.setClearColor(0x000000, 0);
    const directionalLight = new THREE.DirectionalLight(0xffffff, 5);
    directionalLight.position.set(33, 100, -110);
    scene.add(directionalLight);

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.target = new THREE.Vector3(0, 0, 0);
    controls.enableDamping = false;
    controls.enableZoom = false;
    controls.enableRotate = false;
    controls.enablePan = false;
    controls.update();

    let orientationIsLandscape = isLandscape();
    if (orientationIsLandscape) {
      switchToLandscape();
    } else {
      switchToPortrait();
    }

    handleOrientationChange();
    function handleOrientationChange() {
      if (isLandscape()) {
        if (!orientationIsLandscape) switchToLandscape();
        orientationIsLandscape = true;
      } else {
        if (orientationIsLandscape) switchToPortrait();
        orientationIsLandscape = false;
      }
    }
    function isLandscape() {
      return window.innerWidth > window.innerHeight;
    }

    window.addEventListener("resize", function () {
      handleOrientationChange();
    });

    function switchToLandscape() {
      camera.fov = 50; // desktop normal
      camera.position.x = 19; // same as before
      camera.updateProjectionMatrix();
    }

    function switchToPortrait() {
      camera.fov = 60; //  mobile zoom-in feel
      camera.position.x = 22; // 👈 30 hata diya
      camera.updateProjectionMatrix();
    }

    const loadingManager = new THREE.LoadingManager();
    loadingManager.onLoad = () => startScene();

    loadingManager.onError = (url) => {
      console.error(`Error loading ${url}`);
    };

    // load 3d models
    const gltfloader = new GLTFLoader(loadingManager);

    gltfloader.load("/images/3d/card.glb", function (gltf) {
      const model = gltf.scene;
      sceneData.card = model;
    });

    gltfloader.load("/images/3d/pack.glb", function (gltf) {
      const model = gltf.scene;
      sceneData.pack = model;

      if (!gltf.animations?.length) {
        console.warn("No animation found in pack.glb");
        return;
      }

      const originalClip = gltf.animations[0];

      // ✅ Only animate TOP (upper part + morph cut)
      const filteredTracks = originalClip.tracks.filter((t) =>
        t.name.startsWith("top."),
      );

      const topOnlyClip = new THREE.AnimationClip(
        originalClip.name + "_TOP_ONLY",
        originalClip.duration,
        filteredTracks,
      );

      sceneData.openingAnimation = topOnlyClip;

      sceneData.openingMixer = new THREE.AnimationMixer(model);
      sceneData.openingAction = sceneData.openingMixer.clipAction(topOnlyClip);
      sceneData.openingAction.setLoop(THREE.LoopOnce, 0);
      sceneData.openingAction.clampWhenFinished = true;
      sceneData.openingAction.timeScale = 0.7;
    });

    const textureLoader = new THREE.TextureLoader(loadingManager);
    textureLoader.setCrossOrigin("anonymous");

    textureLoader.load(PACK_DATA.pack, function (texture) {
      // texture.encoding = THREE.sRGBEncoding;
      texture.colorSpace = THREE.SRGBColorSpace;
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      texture.repeat.set(1, 1);
      sceneData.packTexture = texture;
    });

    function startScene() {
      function resize() {
        const w = window.innerWidth;
        const h = window.innerHeight;

        renderer.setSize(w, h, false);
        camera.aspect = w / h;
        camera.updateProjectionMatrix();
      }
      resize();
      window.addEventListener("resize", resize);

      function resize() {
        const w = window.innerWidth;
        const h = window.innerHeight;

        renderer.setSize(w, h, false);
        camera.aspect = w / h;
        camera.updateProjectionMatrix();
      }
      resize();
      window.addEventListener("resize", resize);

      let pack = sceneData.pack;
      scene.add(pack);

      pack.position.set(1, 0, 0);

      pack.position.x = 1;
      pack.traverse((child) => {
        if (
          child.isMesh &&
          child.material &&
          child.material.name == "pack-mat"
        ) {
          child.material.map = sceneData.packTexture;
          child.material.transparent = true;
          child.material.needsUpdate = true;
        }
      });

      // pack.scale.setScalar(0.55);
      // if (sceneData.packTexture) {
      //   pack.scale.setScalar(0.7);
      // }

      const isMobile = window.innerWidth < 768;

      pack.scale.setScalar(isMobile ? 0.9 : 0.7);

      const handleInteraction = () => {
        if (isAnimationPlaying) return;
        setIsAnimationPlaying(true);

        stackTriggered = false; // reset
        sceneData.freezePack = false;

        sceneData.openingAction.reset();
        sceneData.openingAction.play();
        sceneData.openingMixer.addEventListener("finished", () => {
          const clip = sceneData.openingAnimation;
          const action = sceneData.openingAction;

          action.clampWhenFinished = true;
          action.enabled = true;
          action.setLoop(THREE.LoopOnce, 0);

          // lock on last frame
          action.time = clip.duration;
          action.paused = true;
          action.setEffectiveTimeScale(0);
          action.setEffectiveWeight(1);

          // stop mixer from moving anything further
          sceneData.openingMixer.timeScale = 0;

          setIsAnimationPlaying(false);

          setTimeout(() => {
            // setShowStack(false); // stack remove
            setIsPlay(true); // next component show
          }, 0);
        });

        setTimeout(() => {}, SPREAD_DELAY * 720);
        setTimeout(() => {}, SPREAD_DELAY * 1320);
      };
      // handleInteraction();

      const canvasEl = renderer.domElement;

      const onUserInteract = (e) => {
        e.preventDefault();
        playSfx("/sfx/imgCut.mp3");
        handleInteraction();

        // optional: only once
        canvasEl.removeEventListener("click", onUserInteract);
        canvasEl.removeEventListener("touchstart", onUserInteract);
      };

      canvasEl.addEventListener("click", onUserInteract);
      canvasEl.addEventListener("touchstart", onUserInteract, {
        passive: false,
      });

      const clock = new THREE.Clock();

      function animate() {
        if (sceneData.openingMixer && !sceneData.freezePack) {
          sceneData.openingMixer.update(clock.getDelta());
        }

        // ✅ cut ke moment pe trigger
        if (
          sceneData.openingAction &&
          sceneData.openingAnimation &&
          sceneData.openingAction.isRunning() &&
          !stackTriggered
        ) {
          const t = sceneData.openingAction.time;
          const dur = sceneData.openingAnimation.duration || 1;
          const progress = t / dur;

          if (progress >= CUT_AT) {
            stackTriggered = true;

            playSfx("/sfx/stackOpening.mp3");

            setShowStack(true);
            setIsFlinging(false);
            requestAnimationFrame(() => setIsFlinging(true));
          }
        }

        requestAnimationFrame(animate);
        renderer.render(scene, camera);
      }
      animate();
    }
    window.removeEventListener("resize", handleOrientationChange);
  }, []);

  return (
    <div className="pack-container mt-16 ">
      {/* <div className="pack-box  mt-10 md:mt-20"> */}
      <canvas ref={canvasRef} className="pack-canvas md:mt-10 " />
      <div className="pack-text">Click to open</div>
      {/* {showFly && ( */}

      {showStack && (
        <div className="stack-wrap">
          <div
            className={`card-stack w-[80px] h-[170px] md:w-[120px] md:h-[140px]  2xl:w-[200px] 2xl:h-[350px] ${isFlinging ? "is-flinging" : ""}`}
            role="button"
            tabIndex={0}
            onKeyDown={(e) => e.key === "Enter" && onStackClick()}
          >
            {Array.from({ length: total }).map((_, i) => {
              const card = cards[i];

              // const order = total - 1 - i; // ✅ reverse for delay
              // const z = i + 1;
              const order = i; // normal order
              const z = total + i;
// w-24 h-32  md:w-28 md:h-36.5 xl:w-76 xl:h-auto
              return (
                <img
                  key={i}
                  className="fly-card rounded-xl mx-auto mt-10 "
                  style={{
                    zIndex: z,
                    transform: `translate(${(i - total / 2) * 0.6}px, ${(total - i) * 0.25}px)`,
                    ["--delay"]: `${order * 90}ms`, // ✅ now top goes first
                    ["--rot"]: `${(i - total / 2) * 0.4}deg`,
                  }}
                  src={
                    pack.brand === "MTG"
                      ? "/images/inventory/magicBack.webp"
                      : pack.brand === "Pokemon"
                        ? "/images/inventory/pokemonBack.png"
                        : "/images/inventory/lorcanaBack.png"
                  }
                  alt=""
                  draggable="false"
                />
              );
            })}
          </div>
        </div>
      )}
      {/* )} */}
    </div>
    // </div>
  );
};

export default ThreeDScene;
