"use client";

import { useState, useRef, useEffect } from "react";
import AnimatedSkeleton from "../components/AnimatedSkeleton";
import ScoreModal from "../components/ScoreModal";

interface Landmark {
  x: number;
  y: number;
  z: number;
  visibility: number;
}

interface MotionMetadata {
  num_frames: number;
  duration: number;
  fps: number;
}

export default function SkeletonTestPage() {
  const [motionLoaded, setMotionLoaded] = useState(false);
  const [motionMetadata, setMotionMetadata] = useState<MotionMetadata | null>(null);
  const [motionFrames, setMotionFrames] = useState<Landmark[][]>([]);
  const [message, setMessage] = useState<string>("");
  const [referenceLandmarks, setReferenceLandmarks] = useState<Landmark[] | null>(null);
  const [currentTime, setCurrentTime] = useState(0);
  const [isPlaying, setIsPlaying] = useState(false);
  const [currentFrame, setCurrentFrame] = useState(0);
  
  // Score modal testing
  const [showScoreModal, setShowScoreModal] = useState(false);
  const [testScore, setTestScore] = useState(85);

  const motionFileInputRef = useRef<HTMLInputElement>(null);
  const animationFrameRef = useRef<number | null>(null);
  const startTimeRef = useRef<number>(0);

  const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL || "http://localhost:8000";

  // Handle motion file upload
  const handleMotionUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    if (!file.name.endsWith(".pkl")) {
      setMessage("Error: Please upload a .pkl file");
      return;
    }

    const formData = new FormData();
    formData.append("file", file);

    try {
      setMessage("Loading motion data...");
      const response = await fetch(`${BACKEND_URL}/api/load-motion`, {
        method: "POST",
        body: formData,
      });

      if (response.ok) {
        const data = await response.json();
        setMotionMetadata(data.metadata);
        setMotionFrames(data.frames);

        if (data.frames && data.frames.length > 0) {
          setReferenceLandmarks(data.frames[0]);
        }

        setMotionLoaded(true);
        setMessage(
          `✅ Motion loaded! ${data.metadata.num_frames} frames, ${data.metadata.duration.toFixed(1)}s duration`
        );
      } else {
        const error = await response.json();
        setMessage(`Error: ${error.detail}`);
      }
    } catch (error) {
      setMessage("Error connecting to backend. Make sure it's running on port 8000.");
      console.error("Error uploading motion:", error);
    }
  };

  // Update reference skeleton based on elapsed time
  const updateReferenceSkeleton = () => {
    if (!motionLoaded || motionFrames.length === 0) return;

    const now = performance.now();
    const elapsed = (now - startTimeRef.current) / 1000;
    setCurrentTime(elapsed);

    const fps = motionMetadata?.fps || 30;
    const frameIndex = Math.floor(elapsed * fps) % motionFrames.length;
    setCurrentFrame(frameIndex);

    if (frameIndex >= 0 && frameIndex < motionFrames.length) {
      setReferenceLandmarks(motionFrames[frameIndex]);
    }

    animationFrameRef.current = requestAnimationFrame(updateReferenceSkeleton);
  };

  // Start/stop animation
  useEffect(() => {
    if (isPlaying && motionLoaded) {
      startTimeRef.current = performance.now() - (currentFrame / (motionMetadata?.fps || 30)) * 1000;
      animationFrameRef.current = requestAnimationFrame(updateReferenceSkeleton);
    } else {
      if (animationFrameRef.current) {
        cancelAnimationFrame(animationFrameRef.current);
      }
    }

    return () => {
      if (animationFrameRef.current) {
        cancelAnimationFrame(animationFrameRef.current);
      }
    };
  }, [isPlaying, motionLoaded]);

  const handlePlayPause = () => {
    setIsPlaying(!isPlaying);
  };

  const handleReset = () => {
    setIsPlaying(false);
    setCurrentFrame(0);
    setCurrentTime(0);
    if (motionFrames.length > 0) {
      setReferenceLandmarks(motionFrames[0]);
    }
  };

  const handleFrameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const frame = parseInt(e.target.value);
    setCurrentFrame(frame);
    setCurrentTime(frame / (motionMetadata?.fps || 30));
    if (frame >= 0 && frame < motionFrames.length) {
      setReferenceLandmarks(motionFrames[frame]);
    }
  };

  return (
    <main className="min-h-screen bg-gradient-to-br from-purple-900 via-blue-900 to-pink-900 p-8">
      <div className="max-w-7xl mx-auto">
        {/* Header */}
        <div className="text-center mb-8">
          <h1 className="text-6xl font-bold text-white mb-2 drop-shadow-lg">
            🎨 Neon Skeleton Test
          </h1>
          <p className="text-xl text-purple-200">
            Upload a .pkl file to see the Just Dance style visualization
          </p>
        </div>

        {/* Message Display */}
        {message && (
          <div className="bg-blue-500/20 backdrop-blur-md rounded-lg p-4 mb-6 text-center">
            <p className="text-white">{message}</p>
          </div>
        )}

        {/* Score Modal Test Section */}
        <div className="bg-white/10 backdrop-blur-md rounded-lg p-6 mb-8">
          <h2 className="text-2xl font-semibold text-white mb-4 text-center">
            Score Modal Preview
          </h2>
          <p className="text-purple-200 mb-4 text-center">
            Test the score modal with different scores
          </p>
          <div className="flex flex-col gap-4">
            <div className="flex items-center gap-4 justify-center">
              <label className="text-white font-medium">Score:</label>
              <input
                type="range"
                min="0"
                max="100"
                value={testScore}
                onChange={(e) => setTestScore(Number(e.target.value))}
                className="w-64"
              />
              <span className="text-white font-bold text-xl w-12">{testScore}</span>
            </div>
            <button
              onClick={() => setShowScoreModal(true)}
              className="bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white font-bold py-3 px-8 rounded-lg transition-all mx-auto"
            >
              Show Score Modal
            </button>
          </div>
        </div>

        {/* Motion Upload Section */}
        {!motionLoaded && (
          <div className="bg-white/10 backdrop-blur-md rounded-lg p-6 mb-8 text-center">
            <h2 className="text-2xl font-semibold text-white mb-4">
              Upload Dance Motion
            </h2>
            <p className="text-purple-200 mb-4">
              Upload a .pkl file containing the reference dance moves
            </p>
            <input
              ref={motionFileInputRef}
              type="file"
              accept=".pkl"
              onChange={handleMotionUpload}
              className="hidden"
            />
            <button
              onClick={() => motionFileInputRef.current?.click()}
              className="bg-purple-600 hover:bg-purple-700 text-white font-bold py-4 px-8 rounded-lg transition-colors hover:cursor-pointer"
            >
              Upload Motion File (.pkl)
            </button>
          </div>
        )}

        {/* Skeleton Display */}
        {motionLoaded && (
          <>
            <div className="bg-black/40 backdrop-blur-md rounded-xl p-8 mb-8">
              <div className="flex justify-center items-center min-h-[600px]">
                <AnimatedSkeleton
                  landmarks={referenceLandmarks}
                  width={600}
                  height={800}
                />
              </div>
            </div>

            {/* Controls */}
            <div className="bg-white/10 backdrop-blur-md rounded-xl p-8">
              {/* Info Display */}
              <div className="grid grid-cols-3 gap-4 mb-6 text-center">
                <div className="bg-black/30 rounded-lg p-4">
                  <p className="text-purple-200 text-sm">Current Frame</p>
                  <p className="text-white text-2xl font-bold">
                    {currentFrame} / {motionMetadata?.num_frames || 0}
                  </p>
                </div>
                <div className="bg-black/30 rounded-lg p-4">
                  <p className="text-purple-200 text-sm">Time</p>
                  <p className="text-white text-2xl font-bold">
                    {(currentTime % (motionMetadata?.duration || 1)).toFixed(2)}s / {motionMetadata?.duration.toFixed(2)}s
                  </p>
                </div>
                <div className="bg-black/30 rounded-lg p-4">
                  <p className="text-purple-200 text-sm">FPS</p>
                  <p className="text-white text-2xl font-bold">
                    {motionMetadata?.fps || 0}
                  </p>
                </div>
              </div>

              {/* Frame Slider */}
              <div className="mb-6">
                <label className="text-white text-sm mb-2 block">Frame Scrubber</label>
                <input
                  type="range"
                  min="0"
                  max={(motionMetadata?.num_frames || 1) - 1}
                  value={currentFrame}
                  onChange={handleFrameChange}
                  className="w-full h-2 bg-purple-300/30 rounded-lg appearance-none cursor-pointer slider"
                  disabled={isPlaying}
                />
              </div>

              {/* Playback Controls */}
              <div className="flex gap-4 justify-center items-center flex-wrap">
                <button
                  onClick={handlePlayPause}
                  className={`${
                    isPlaying
                      ? "bg-red-600 hover:bg-red-700"
                      : "bg-green-600 hover:bg-green-700"
                  } text-white font-bold py-4 px-12 rounded-lg transition-colors text-xl hover:cursor-pointer`}
                >
                  {isPlaying ? "⏸ Pause" : "▶ Play"}
                </button>

                <button
                  onClick={handleReset}
                  className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-4 px-12 rounded-lg transition-colors text-xl hover:cursor-pointer"
                >
                  ⏮ Reset
                </button>

                <button
                  onClick={() => {
                    setMotionLoaded(false);
                    setMotionFrames([]);
                    setReferenceLandmarks(null);
                    setIsPlaying(false);
                    setCurrentFrame(0);
                    setCurrentTime(0);
                    setMessage("");
                  }}
                  className="bg-gray-600 hover:bg-gray-700 text-white font-bold py-4 px-12 rounded-lg transition-colors text-xl hover:cursor-pointer"
                >
                  📁 Load New File
                </button>
              </div>
            </div>
          </>
        )}

        {/* Footer */}
        <div className="mt-12 text-center text-purple-300">
          <p>
            Test page for the neon Just Dance skeleton visualization
          </p>
        </div>
      </div>

      {/* Score Modal */}
      {showScoreModal && (
        <ScoreModal
          score={testScore}
          onClose={() => setShowScoreModal(false)}
        />
      )}

      <style jsx>{`
        .slider::-webkit-slider-thumb {
          appearance: none;
          width: 20px;
          height: 20px;
          border-radius: 50%;
          background: #a855f7;
          cursor: pointer;
          box-shadow: 0 0 10px rgba(168, 85, 247, 0.5);
        }

        .slider::-moz-range-thumb {
          width: 20px;
          height: 20px;
          border-radius: 50%;
          background: #a855f7;
          cursor: pointer;
          border: none;
          box-shadow: 0 0 10px rgba(168, 85, 247, 0.5);
        }
      `}</style>
    </main>
  );
}

