"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import CardFace from "../card-face";
import { OrderDetailsModel } from "@/lib/types/models/order";

const ROTATION_SPEED = 0.4;
const MAX_X_ROTATION = 85;
const TRANSITION_DURATION = 1000;
const MIN_SCALE = 1;
const MAX_SCALE = 1.3;
const SCALE_STEP = 0.2;

const clamp = (value: number, min: number, max: number) =>
  Math.max(min, Math.min(max, value));

const normalizeAngle = (angle: number) => {
  let normalized = angle % 360;
  if (normalized > 180) normalized -= 360;
  if (normalized <= -180) normalized += 360;
  return normalized;
};

type RotationState = {
  x: number;
  y: number;
};

export default function Page({
  orderDetail,
}: {
  orderDetail: OrderDetailsModel;
}) {
  const [rotation, setRotation] = useState<RotationState>({ x: 0, y: 0 });
  const [isDragging, setIsDragging] = useState(false);
  const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
  const [lastRotation, setLastRotation] = useState({ x: 0, y: 0 });
  const [scale, setScale] = useState(1);

  const cardRef = useRef<HTMLDivElement | null>(null);
  const frontRef = useRef<HTMLDivElement | null>(null);
  const backRef = useRef<HTMLDivElement | null>(null);

  const displayX = clamp(rotation.x, -MAX_X_ROTATION, MAX_X_ROTATION);
  const displayY = normalizeAngle(rotation.y);
  const isBackVisible = displayY > 90 || displayY < -90;

  const handleManualRotation = useCallback((side: "front" | "back") => {
    const newY = side === "back" ? 180 : 0;
    setRotation({ x: 0, y: newY });
    setLastRotation({ x: 0, y: newY });
  }, []);

  const startDragging = useCallback((x: number, y: number) => {
    setIsDragging(true);
    setDragStart({ x, y });
  }, []);

  const handleMoveDelta = useCallback(
    (dx: number, dy: number) => {
      const newY = lastRotation.y + dx * ROTATION_SPEED;
      const newX = clamp(
        lastRotation.x - dy * ROTATION_SPEED,
        -MAX_X_ROTATION,
        MAX_X_ROTATION
      );
      setRotation({ x: newX, y: newY });
    },
    [lastRotation]
  );

  const stopDragging = useCallback(() => {
    if (!isDragging) return;
    setIsDragging(false);

    const normX = clamp(rotation.x, -MAX_X_ROTATION, MAX_X_ROTATION);
    const normY = normalizeAngle(rotation.y);

    setRotation({ x: normX, y: normY });
    setLastRotation({ x: normX, y: normY });
  }, [isDragging, rotation]);

  const handleWheel = useCallback((e: WheelEvent) => {
    e.preventDefault();
    setScale((prev) =>
      clamp(
        prev + (e.deltaY < 0 ? SCALE_STEP : -SCALE_STEP),
        MIN_SCALE,
        MAX_SCALE
      )
    );
  }, []);

  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      if (!isDragging) return;
      handleMoveDelta(e.clientX - dragStart.x, e.clientY - dragStart.y);
    };
    const handleTouchMove = (e: TouchEvent) => {
      if (!isDragging) return;
      const t = e.touches[0];
      handleMoveDelta(t.clientX - dragStart.x, t.clientY - dragStart.y);
      e.preventDefault();
    };

    if (isDragging) {
      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", stopDragging);
      document.addEventListener("touchmove", handleTouchMove, {
        passive: false,
      });
      document.addEventListener("touchend", stopDragging);
    }
    return () => {
      document.removeEventListener("mousemove", handleMouseMove);
      document.removeEventListener("mouseup", stopDragging);
      document.removeEventListener("touchmove", handleTouchMove);
      document.removeEventListener("touchend", stopDragging);
    };
  }, [isDragging, dragStart, handleMoveDelta, stopDragging]);

  useEffect(() => {
    const frontEl = frontRef.current;
    const backEl = backRef.current;

    frontEl?.addEventListener("wheel", handleWheel, { passive: false });
    backEl?.addEventListener("wheel", handleWheel, { passive: false });

    return () => {
      frontEl?.removeEventListener("wheel", handleWheel);
      backEl?.removeEventListener("wheel", handleWheel);
    };
  }, [handleWheel]);

  return (
    <>
      <div className="w-full p-8 bg-gradient-to-br from-gray-50 to-gray-100 flex flex-col items-center overflow-hidden">
        <div className="perspective w-full max-w-[500px] aspect-[16/12] mb-10 lg:mb-16 ">
          <div
            ref={cardRef}
            className={`relative w-full h-full preserve-3d ${isDragging ? "cursor-grabbing" : "cursor-grab"
              }`}
            style={{
              transform: `rotateX(${displayX}deg) rotateY(${displayY}deg)`,
              transition: isDragging
                ? "transform 0ms linear"
                : `transform ${TRANSITION_DURATION}ms ease-in-out`,
            }}
            onMouseDown={(e) => {
              e.preventDefault();
              startDragging(e.clientX, e.clientY);
            }}
            onTouchStart={(e) => {
              e.preventDefault();
              const t = e.touches[0];
              startDragging(t.clientX, t.clientY);
            }}
          >
            <div
              className="absolute inset-0 backface-hidden rounded-xl "
              ref={frontRef}
              style={{
                overscrollBehavior: "contain",
                touchAction: "none",
              }}
            >
              <CardFace
                scale={scale}
                imgSrc={orderDetail?.artworkFiles[0]?.image as string}
              />
            </div>
            <div
              className="absolute inset-0 backface-hidden rounded-xl "
              ref={backRef}
              style={{
                transform: "rotateY(180deg)",
                overscrollBehavior: "contain",
                touchAction: "none",
              }}
            >
              {orderDetail?.artworkFiles[1]?.image ? (
                <CardFace
                  scale={scale}
                  imgSrc={orderDetail?.artworkFiles[1]?.image as string}
                />
              ) : (
                <div
                  className="bg-white/80 w-full h-full"
                  style={{
                    transform: `scale(${scale})`,
                    transition: "transform 0.2s ease",
                  }}
                />
              )}
            </div>
          </div>
        </div>

        {orderDetail?.artworkFiles[1]?.image && (
          <div className="flex justify-center relative z-10">
            <button
              onClick={() => handleManualRotation("front")}
              className={`px-6 py-2 rounded-l-md border-2 font-medium transition-colors ${!isBackVisible
                ? "bg-white text-black border-black"
                : "bg-white text-gray-600 border-gray-300 hover:border-gray-400"
                }`}
            >
              Front
            </button>
            <button
              onClick={() => handleManualRotation("back")}
              className={`px-6 py-2 rounded-r-md border-2 font-medium transition-colors  ${isBackVisible
                ? "bg-white text-black border-black"
                : "bg-white text-gray-600 border-gray-300 hover:border-gray-400"
                }`}
            >
              Back
            </button>
          </div>
        )}
      </div>
      <style jsx>{`
        .perspective {
          perspective: 1200px;
        }
        .preserve-3d {
          transform-style: preserve-3d;
          will-change: transform;
        }
        .backface-hidden {
          backface-visibility: hidden;
        }
      `}</style>
    </>
  );
}
