import { useAuth } from "@/_core/hooks/useAuth";
import { trpc } from "@/lib/trpc";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { toast } from "sonner";
import { Camera, CameraOff, RotateCcw, CheckCircle2, AlertTriangle, Smartphone, Monitor, FlipHorizontal, Zap, Activity } from "lucide-react";
import { useRef, useState, useEffect, useCallback } from "react";

type CameraFacing = "user" | "environment";

interface PoseScore {
  overall: number;
  posture: number;
  balance: number;
  armAngle: number;
}

// Camera position guide steps
const SETUP_STEPS = [
  { title: "放置设备", desc: "将手机/平板固定在三脚架或稳定平面上", icon: <Smartphone className="h-6 w-6" /> },
  { title: "调整距离", desc: "确保摄像头能拍到全身（距离2-3米）", icon: <Monitor className="h-6 w-6" /> },
  { title: "调整高度", desc: "摄像头高度约在腰部位置，略微仰角", icon: <Camera className="h-6 w-6" /> },
  { title: "确认画面", desc: "确保光线充足，背景简洁，全身可见", icon: <CheckCircle2 className="h-6 w-6" /> },
];

export default function LiveCamera() {
  const { user } = useAuth();
  const videoRef = useRef<HTMLVideoElement>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const streamRef = useRef<MediaStream | null>(null);
  const poseRef = useRef<any>(null);
  const animFrameRef = useRef<number>(0);

  const [cameraActive, setCameraActive] = useState(false);
  const [facing, setFacing] = useState<CameraFacing>("environment");
  const [showSetupGuide, setShowSetupGuide] = useState(true);
  const [setupStep, setSetupStep] = useState(0);
  const [analyzing, setAnalyzing] = useState(false);
  const [liveScore, setLiveScore] = useState<PoseScore | null>(null);
  const [frameCount, setFrameCount] = useState(0);
  const [fps, setFps] = useState(0);
  const [hasMultipleCameras, setHasMultipleCameras] = useState(false);
  const [exerciseType, setExerciseType] = useState("forehand");
  const [feedback, setFeedback] = useState<string[]>([]);

  // Check available cameras
  useEffect(() => {
    navigator.mediaDevices?.enumerateDevices().then(devices => {
      const cameras = devices.filter(d => d.kind === "videoinput");
      setHasMultipleCameras(cameras.length > 1);
    }).catch(() => {});
  }, []);

  // FPS counter
  useEffect(() => {
    if (!analyzing) return;
    const interval = setInterval(() => {
      setFps(prev => {
        const current = frameCount;
        setFrameCount(0);
        return current;
      });
    }, 1000);
    return () => clearInterval(interval);
  }, [analyzing, frameCount]);

  const startCamera = useCallback(async () => {
    try {
      // Stop existing stream
      if (streamRef.current) {
        streamRef.current.getTracks().forEach(t => t.stop());
      }

      const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
      const constraints: MediaStreamConstraints = {
        video: {
          facingMode: facing,
          width: { ideal: isMobile ? 1280 : 1920 },
          height: { ideal: isMobile ? 720 : 1080 },
          frameRate: { ideal: 30, max: 30 },
        },
        audio: false,
      };

      const stream = await navigator.mediaDevices.getUserMedia(constraints);
      streamRef.current = stream;

      if (videoRef.current) {
        videoRef.current.srcObject = stream;
        await videoRef.current.play();
      }

      setCameraActive(true);
      toast.success("摄像头已启动");
    } catch (err: any) {
      console.error("Camera error:", err);
      if (err.name === "NotAllowedError") {
        toast.error("请允许摄像头访问权限");
      } else if (err.name === "NotFoundError") {
        toast.error("未找到摄像头设备");
      } else {
        toast.error("摄像头启动失败: " + err.message);
      }
    }
  }, [facing]);

  const stopCamera = useCallback(() => {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach(t => t.stop());
      streamRef.current = null;
    }
    if (animFrameRef.current) {
      cancelAnimationFrame(animFrameRef.current);
    }
    setCameraActive(false);
    setAnalyzing(false);
    setLiveScore(null);
  }, []);

  const switchCamera = useCallback(() => {
    const newFacing = facing === "user" ? "environment" : "user";
    setFacing(newFacing);
    if (cameraActive) {
      stopCamera();
      setTimeout(() => startCamera(), 300);
    }
  }, [facing, cameraActive, stopCamera, startCamera]);

  // Start pose analysis
  const startAnalysis = useCallback(async () => {
    if (!videoRef.current || !canvasRef.current) return;

    setAnalyzing(true);
    toast.info("正在加载姿势识别模型...");

    try {
      const { Pose } = await import("@mediapipe/pose");
      const { drawConnectors, drawLandmarks } = await import("@mediapipe/drawing_utils");

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

      pose.setOptions({
        modelComplexity: 1,
        smoothLandmarks: true,
        enableSegmentation: false,
        minDetectionConfidence: 0.5,
        minTrackingConfidence: 0.5,
      });

      const POSE_CONNECTIONS = [
        [11, 12], [11, 13], [13, 15], [12, 14], [14, 16],
        [11, 23], [12, 24], [23, 24], [23, 25], [24, 26],
        [25, 27], [26, 28], [15, 17], [16, 18], [15, 19],
        [16, 20], [17, 19], [18, 20],
      ];

      pose.onResults((results: any) => {
        const canvas = canvasRef.current;
        const ctx = canvas?.getContext("2d");
        if (!canvas || !ctx || !videoRef.current) return;

        canvas.width = videoRef.current.videoWidth;
        canvas.height = videoRef.current.videoHeight;

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(videoRef.current, 0, 0);

        if (results.poseLandmarks) {
          // Draw skeleton
          const landmarks = results.poseLandmarks;

          // Draw connections
          ctx.strokeStyle = "rgba(0, 200, 100, 0.8)";
          ctx.lineWidth = 3;
          POSE_CONNECTIONS.forEach(([a, b]) => {
            const la = landmarks[a];
            const lb = landmarks[b];
            if (la && lb && la.visibility > 0.3 && lb.visibility > 0.3) {
              ctx.beginPath();
              ctx.moveTo(la.x * canvas.width, la.y * canvas.height);
              ctx.lineTo(lb.x * canvas.width, lb.y * canvas.height);
              ctx.stroke();
            }
          });

          // Draw landmarks
          landmarks.forEach((lm: any, i: number) => {
            if (lm.visibility > 0.3) {
              ctx.fillStyle = [11, 12, 13, 14, 15, 16].includes(i) ? "#ff4444" : "#00cc66";
              ctx.beginPath();
              ctx.arc(lm.x * canvas.width, lm.y * canvas.height, 5, 0, 2 * Math.PI);
              ctx.fill();
            }
          });

          // Calculate live scores
          const score = calculateLiveScore(landmarks, exerciseType);
          setLiveScore(score);
          setFeedback(generateLiveFeedback(landmarks, exerciseType));
          setFrameCount(prev => prev + 1);

          // Draw score overlay
          ctx.fillStyle = "rgba(0,0,0,0.6)";
          ctx.fillRect(10, 10, 180, 40);
          ctx.fillStyle = "#fff";
          ctx.font = "bold 16px sans-serif";
          ctx.fillText(`评分: ${score.overall}/100`, 20, 35);
        }
      });

      poseRef.current = pose;

      const processFrame = async () => {
        if (!videoRef.current || !analyzing) return;
        if (videoRef.current.readyState >= 2) {
          await pose.send({ image: videoRef.current });
        }
        animFrameRef.current = requestAnimationFrame(processFrame);
      };

      toast.success("模型加载完成，开始实时分析");
      processFrame();
    } catch (err) {
      console.error("Pose init error:", err);
      toast.error("姿势识别模型加载失败");
      setAnalyzing(false);
    }
  }, [analyzing, exerciseType]);

  const stopAnalysis = useCallback(() => {
    if (animFrameRef.current) {
      cancelAnimationFrame(animFrameRef.current);
    }
    setAnalyzing(false);
    setLiveScore(null);
  }, []);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      stopCamera();
    };
  }, [stopCamera]);

  // Setup guide dialog
  const handleSetupComplete = () => {
    setShowSetupGuide(false);
    startCamera();
  };

  return (
    <div className="space-y-4">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">实时姿势分析</h1>
          <p className="text-muted-foreground text-sm mt-1">通过摄像头实时捕捉并分析您的挥拍动作</p>
        </div>
        <div className="flex items-center gap-2">
          <Select value={exerciseType} onValueChange={setExerciseType}>
            <SelectTrigger className="w-[120px] h-9 text-sm">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="forehand">正手挥拍</SelectItem>
              <SelectItem value="backhand">反手挥拍</SelectItem>
              <SelectItem value="serve">发球</SelectItem>
              <SelectItem value="volley">截击</SelectItem>
              <SelectItem value="footwork">脚步移动</SelectItem>
            </SelectContent>
          </Select>
        </div>
      </div>

      {/* Camera position setup guide */}
      <Dialog open={showSetupGuide} onOpenChange={setShowSetupGuide}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <Camera className="h-5 w-5 text-primary" />
              摄像头位置设置
            </DialogTitle>
            <DialogDescription>
              为获得最佳分析效果，请按以下步骤调整设备位置
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-2">
            {SETUP_STEPS.map((step, idx) => (
              <div key={idx} className={`flex items-start gap-3 p-3 rounded-lg transition-colors ${
                idx === setupStep ? "bg-primary/10 border border-primary/20" : idx < setupStep ? "bg-green-50" : "bg-muted/30"
              }`}>
                <div className={`h-10 w-10 rounded-full flex items-center justify-center shrink-0 ${
                  idx < setupStep ? "bg-green-100 text-green-600" : idx === setupStep ? "bg-primary/20 text-primary" : "bg-muted text-muted-foreground"
                }`}>
                  {idx < setupStep ? <CheckCircle2 className="h-5 w-5" /> : step.icon}
                </div>
                <div>
                  <p className="font-medium text-sm">{step.title}</p>
                  <p className="text-xs text-muted-foreground mt-0.5">{step.desc}</p>
                </div>
              </div>
            ))}
          </div>
          <DialogFooter className="flex gap-2">
            {setupStep > 0 && (
              <Button variant="outline" onClick={() => setSetupStep(s => s - 1)}>上一步</Button>
            )}
            {setupStep < SETUP_STEPS.length - 1 ? (
              <Button onClick={() => setSetupStep(s => s + 1)}>下一步</Button>
            ) : (
              <Button onClick={handleSetupComplete} className="gap-2">
                <Camera className="h-4 w-4" />开始使用摄像头
              </Button>
            )}
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Main camera view */}
      <div className="grid grid-cols-1 lg:grid-cols-4 gap-4">
        <div className="lg:col-span-3">
          <Card className="border-0 shadow-sm overflow-hidden">
            <CardContent className="p-0 relative">
              <div className="relative bg-black aspect-video w-full">
                <video
                  ref={videoRef}
                  className={`absolute inset-0 w-full h-full object-contain ${analyzing ? "opacity-0" : ""}`}
                  playsInline
                  muted
                  autoPlay
                />
                <canvas
                  ref={canvasRef}
                  className={`absolute inset-0 w-full h-full object-contain ${analyzing ? "" : "hidden"}`}
                />
                {!cameraActive && (
                  <div className="absolute inset-0 flex flex-col items-center justify-center text-white/60">
                    <CameraOff className="h-12 w-12 mb-3" />
                    <p className="text-sm">摄像头未启动</p>
                    <Button variant="secondary" className="mt-3 gap-2" onClick={() => setShowSetupGuide(true)}>
                      <Camera className="h-4 w-4" />启动摄像头
                    </Button>
                  </div>
                )}
                {/* FPS indicator */}
                {analyzing && (
                  <div className="absolute top-3 right-3 bg-black/60 text-white text-xs px-2 py-1 rounded">
                    {fps} FPS
                  </div>
                )}
              </div>

              {/* Controls bar */}
              <div className="flex items-center justify-center gap-3 p-3 bg-muted/30 flex-wrap">
                {!cameraActive ? (
                  <Button onClick={() => setShowSetupGuide(true)} className="gap-2">
                    <Camera className="h-4 w-4" />启动摄像头
                  </Button>
                ) : (
                  <>
                    <Button variant="outline" size="sm" onClick={stopCamera} className="gap-1.5">
                      <CameraOff className="h-3.5 w-3.5" />关闭
                    </Button>
                    {hasMultipleCameras && (
                      <Button variant="outline" size="sm" onClick={switchCamera} className="gap-1.5">
                        <FlipHorizontal className="h-3.5 w-3.5" />
                        {facing === "user" ? "后置" : "前置"}
                      </Button>
                    )}
                    {!analyzing ? (
                      <Button size="sm" onClick={startAnalysis} className="gap-1.5">
                        <Zap className="h-3.5 w-3.5" />开始分析
                      </Button>
                    ) : (
                      <Button variant="destructive" size="sm" onClick={stopAnalysis} className="gap-1.5">
                        <Activity className="h-3.5 w-3.5" />停止分析
                      </Button>
                    )}
                    <Button variant="outline" size="sm" onClick={() => setShowSetupGuide(true)} className="gap-1.5">
                      <RotateCcw className="h-3.5 w-3.5" />重新调整
                    </Button>
                  </>
                )}
              </div>
            </CardContent>
          </Card>
        </div>

        {/* Live score panel */}
        <div className="space-y-4">
          <Card className="border-0 shadow-sm">
            <CardHeader className="pb-2">
              <CardTitle className="text-sm flex items-center gap-2">
                <Activity className="h-4 w-4 text-primary" />实时评分
              </CardTitle>
            </CardHeader>
            <CardContent className="space-y-3">
              {liveScore ? (
                <>
                  <div className="text-center">
                    <p className="text-4xl font-bold text-primary">{liveScore.overall}</p>
                    <p className="text-xs text-muted-foreground">综合评分</p>
                  </div>
                  <div className="space-y-2">
                    <ScoreBar label="姿势" value={liveScore.posture} />
                    <ScoreBar label="平衡" value={liveScore.balance} />
                    <ScoreBar label="手臂" value={liveScore.armAngle} />
                  </div>
                </>
              ) : (
                <div className="text-center py-6 text-muted-foreground text-sm">
                  <Activity className="h-8 w-8 mx-auto mb-2 opacity-30" />
                  <p>开始分析后显示实时评分</p>
                </div>
              )}
            </CardContent>
          </Card>

          <Card className="border-0 shadow-sm">
            <CardHeader className="pb-2">
              <CardTitle className="text-sm flex items-center gap-2">
                <AlertTriangle className="h-4 w-4 text-orange-500" />实时反馈
              </CardTitle>
            </CardHeader>
            <CardContent>
              {feedback.length > 0 ? (
                <div className="space-y-2">
                  {feedback.map((f, i) => (
                    <div key={i} className="text-xs p-2 rounded bg-orange-50 text-orange-700 border border-orange-100">
                      {f}
                    </div>
                  ))}
                </div>
              ) : (
                <p className="text-xs text-muted-foreground text-center py-4">
                  分析中将显示实时矫正建议
                </p>
              )}
            </CardContent>
          </Card>

          {/* Tips card */}
          <Card className="border-0 shadow-sm bg-blue-50/50">
            <CardContent className="py-3">
              <p className="text-xs font-medium text-blue-700 mb-1">📱 移动端提示</p>
              <ul className="text-[11px] text-blue-600 space-y-1">
                <li>· 横屏模式效果更佳</li>
                <li>· 使用后置摄像头获得更高画质</li>
                <li>· 保持2-3米拍摄距离</li>
                <li>· 确保光线充足</li>
              </ul>
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  );
}

// Score bar component
function ScoreBar({ label, value }: { label: string; value: number }) {
  const color = value >= 80 ? "bg-green-500" : value >= 60 ? "bg-yellow-500" : "bg-red-500";
  return (
    <div>
      <div className="flex justify-between text-xs mb-0.5">
        <span className="text-muted-foreground">{label}</span>
        <span className="font-medium">{Math.round(value)}</span>
      </div>
      <div className="h-1.5 bg-muted rounded-full overflow-hidden">
        <div className={`h-full ${color} rounded-full transition-all duration-300`} style={{ width: `${value}%` }} />
      </div>
    </div>
  );
}

// Live score calculation from landmarks
function calculateLiveScore(landmarks: any[], exerciseType: string): PoseScore {
  const getAngle = (a: any, b: any, c: any) => {
    const radians = Math.atan2(c.y - b.y, c.x - b.x) - Math.atan2(a.y - b.y, a.x - b.x);
    let angle = Math.abs(radians * 180 / Math.PI);
    if (angle > 180) angle = 360 - angle;
    return angle;
  };

  // Shoulder alignment (posture)
  const leftShoulder = landmarks[11];
  const rightShoulder = landmarks[12];
  const shoulderDiff = Math.abs(leftShoulder.y - rightShoulder.y);
  const postureScore = Math.max(0, 100 - shoulderDiff * 500);

  // Hip alignment (balance)
  const leftHip = landmarks[23];
  const rightHip = landmarks[24];
  const hipDiff = Math.abs(leftHip.y - rightHip.y);
  const balanceScore = Math.max(0, 100 - hipDiff * 500);

  // Arm angle based on exercise type
  let armScore = 70;
  if (exerciseType === "forehand" || exerciseType === "backhand") {
    const shoulder = exerciseType === "forehand" ? landmarks[12] : landmarks[11];
    const elbow = exerciseType === "forehand" ? landmarks[14] : landmarks[13];
    const wrist = exerciseType === "forehand" ? landmarks[16] : landmarks[15];
    const angle = getAngle(shoulder, elbow, wrist);
    // Ideal forehand/backhand elbow angle: 90-150 degrees
    if (angle >= 90 && angle <= 150) armScore = 90 + (1 - Math.abs(angle - 120) / 30) * 10;
    else armScore = Math.max(30, 90 - Math.abs(angle - 120));
  } else if (exerciseType === "serve") {
    const rightElbow = landmarks[14];
    const rightShoulder2 = landmarks[12];
    const rightWrist = landmarks[16];
    const angle = getAngle(rightShoulder2, rightElbow, rightWrist);
    if (angle >= 150 && angle <= 180) armScore = 95;
    else armScore = Math.max(40, 95 - Math.abs(angle - 165) * 2);
  }

  const overall = Math.round(postureScore * 0.3 + balanceScore * 0.3 + armScore * 0.4);

  return {
    overall: Math.min(100, Math.max(0, overall)),
    posture: Math.min(100, Math.max(0, Math.round(postureScore))),
    balance: Math.min(100, Math.max(0, Math.round(balanceScore))),
    armAngle: Math.min(100, Math.max(0, Math.round(armScore))),
  };
}

// Generate live feedback
function generateLiveFeedback(landmarks: any[], exerciseType: string): string[] {
  const tips: string[] = [];
  const leftShoulder = landmarks[11];
  const rightShoulder = landmarks[12];

  if (Math.abs(leftShoulder.y - rightShoulder.y) > 0.05) {
    tips.push("⚠️ 双肩不平衡，注意保持肩膀水平");
  }

  const leftHip = landmarks[23];
  const rightHip = landmarks[24];
  if (Math.abs(leftHip.y - rightHip.y) > 0.05) {
    tips.push("⚠️ 重心不稳，注意保持髋部水平");
  }

  const nose = landmarks[0];
  const midShoulder = { x: (leftShoulder.x + rightShoulder.x) / 2, y: (leftShoulder.y + rightShoulder.y) / 2 };
  if (Math.abs(nose.x - midShoulder.x) > 0.08) {
    tips.push("⚠️ 头部偏移，保持头部在身体中心线上");
  }

  if (exerciseType === "forehand") {
    const rightElbow = landmarks[14];
    const rightWrist = landmarks[16];
    if (rightElbow.y > rightShoulder.y + 0.15) {
      tips.push("💡 正手：抬高肘部，保持手臂在肩膀高度");
    }
  }

  if (exerciseType === "serve") {
    const rightWrist = landmarks[16];
    if (rightWrist.y > rightShoulder.y) {
      tips.push("💡 发球：手臂需要充分伸展向上");
    }
  }

  if (tips.length === 0) {
    tips.push("✅ 姿势良好，继续保持！");
  }

  return tips;
}
