"use client";

import { useEffect, useRef, useState } from "react";

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

// MediaPipe Pose types (loaded from CDN)
declare global {
  interface Window {
    Pose: any;
  }
}

export function usePoseDetection() {
  const [isReady, setIsReady] = useState(false);
  const poseRef = useRef<any>(null);
  const resultsRef = useRef<any>(null);
  const isProcessingRef = useRef(false);
  const pendingResolveRef = useRef<((value: Landmark[] | null) => void) | null>(null);

  useEffect(() => {
    // Load MediaPipe scripts from CDN
    const loadMediaPipeScripts = async () => {
      // Check if already loaded
      if (window.Pose) {
        await initializePose();
        return;
      }

      try {
        // Load main Pose script
        await loadScript(
          "https://cdn.jsdelivr.net/npm/@mediapipe/pose/pose.js"
        );

        // Wait longer for WASM to fully initialize
        await new Promise((resolve) => setTimeout(resolve, 1000));

        if (window.Pose) {
          await initializePose();
        } else {
          console.error("MediaPipe Pose failed to load");
        }
      } catch (error) {
        console.error("Error loading MediaPipe scripts:", error);
      }
    };

    const loadScript = (src: string): Promise<void> => {
      return new Promise((resolve, reject) => {
        // Check if script already exists
        const existing = document.querySelector(`script[src="${src}"]`);
        if (existing) {
          resolve();
          return;
        }

        const script = document.createElement("script");
        script.src = src;
        script.crossOrigin = "anonymous";
        script.onload = () => resolve();
        script.onerror = () => reject(new Error(`Failed to load ${src}`));
        document.body.appendChild(script);
      });
    };

    const initializePose = async () => {
      if (!window.Pose) {
        console.error("window.Pose not available");
        return;
      }

      try {
        const pose = new window.Pose({
          locateFile: (file: string) => {
            return `https://cdn.jsdelivr.net/npm/@mediapipe/pose/${file}`;
          },
        });

        pose.setOptions({
          modelComplexity: 0, // Use lighter model for better performance
          smoothLandmarks: true,
          enableSegmentation: false,
          minDetectionConfidence: 0.5,
          minTrackingConfidence: 0.5,
        });

        pose.onResults((results: any) => {
          resultsRef.current = results;
          isProcessingRef.current = false;
          
          // Resolve pending promise if there is one
          if (pendingResolveRef.current) {
            if (results && results.poseLandmarks) {
              const landmarks = results.poseLandmarks.map((landmark: any) => ({
                x: landmark.x,
                y: landmark.y,
                z: landmark.z,
                visibility: landmark.visibility || 0,
              }));
              pendingResolveRef.current(landmarks);
            } else {
              pendingResolveRef.current(null);
            }
            pendingResolveRef.current = null;
          }
        });

        poseRef.current = pose;
        
        // Wait a bit more for WASM to be fully ready
        await new Promise((resolve) => setTimeout(resolve, 500));
        
        setIsReady(true);
        console.log("MediaPipe Pose initialized and ready");
      } catch (error) {
        console.error("Error initializing MediaPipe Pose:", error);
      }
    };

    loadMediaPipeScripts();

    return () => {
      if (poseRef.current) {
        try {
          poseRef.current.close();
        } catch (e) {
          // Ignore errors on cleanup
        }
      }
    };
  }, []);

  const detectPose = async (
    source: HTMLVideoElement | HTMLImageElement
  ): Promise<Landmark[] | null> => {
    if (!poseRef.current || !isReady || isProcessingRef.current) {
      return null;
    }

    // Don't process if video isn't ready
    if (source instanceof HTMLVideoElement) {
      if (source.readyState < 2 || source.videoWidth === 0 || source.videoHeight === 0) {
        return null;
      }
    }

    try {
      isProcessingRef.current = true;
      
      // Create a promise that will be resolved by onResults callback
      const detectionPromise = new Promise<Landmark[] | null>((resolve) => {
        pendingResolveRef.current = resolve;
        
        // Set a timeout in case results never come back
        setTimeout(() => {
          if (pendingResolveRef.current === resolve) {
            pendingResolveRef.current = null;
            isProcessingRef.current = false;
            resolve(null);
          }
        }, 200);
      });

      // Send the source to MediaPipe
      await poseRef.current.send({ image: source });

      return await detectionPromise;
    } catch (error) {
      console.error("Error detecting pose:", error);
      isProcessingRef.current = false;
      pendingResolveRef.current = null;
      return null;
    }
  };

  return { detectPose, isReady };
}
