import React, { useState, useRef, useEffect, useCallback } from 'react';
import { useParams, useNavigate, useSearchParams } from 'react-router-dom';
import { Page } from './_util';
import { Button } from '@/components/ui/button';
import { useAppearance } from '../../hooks/use-appearance';
import { Camera, RotateCcw, Zap, ZapOff } from 'lucide-react';
import BottomNav from '../components/BottomNav';
import { uploadPhoto } from '../services/photosApi';

interface Task {
  id: number;
  title: string;
  description: string;
  instructions?: string;
  duration: number;
  emotion?: { slug: string; name: string };
  difficulty?: 'easy' | 'medium' | 'hard';
}

export default function UploadPage() {
  const { slug } = useParams<{ slug: string }>();
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const { appearance } = useAppearance();
  const isDark = appearance === 'dark';

  // Task data from URL params
  const taskId = searchParams.get('task');
  const emotionSlug = searchParams.get('emotion') || '';
  const [task, setTask] = useState<Task | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);

  // Camera state
  const videoRef = useRef<HTMLVideoElement>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [stream, setStream] = useState<MediaStream | null>(null);
  const [facingMode, setFacingMode] = useState<'user' | 'environment'>('user'); // front = user, back = environment
  const [flashOn, setFlashOn] = useState(false);
  const [isPulsing, setIsPulsing] = useState(false);
  const [countdown, setCountdown] = useState(3);
  const [capturing, setCapturing] = useState(false);

  // Load task data from API
  useEffect(() => {
    if (!slug || !taskId) {
      setError('Keine Aufgabendaten gefunden');
      setLoading(false);
      return;
    }

    const taskIdNum = parseInt(taskId);
    if (isNaN(taskIdNum)) {
      setError('Ungültige Aufgaben-ID');
      setLoading(false);
      return;
    }

    async function fetchTask() {
      try {
        setLoading(true);
        setError(null);
        
        const response = await fetch(`/api/v1/events/${slug}/tasks`);
        if (!response.ok) throw new Error('Tasks konnten nicht geladen werden');
        
        const tasks = await response.json();
        const foundTask = tasks.find((t: any) => t.id === taskIdNum);
        
        if (foundTask) {
          setTask({
            id: foundTask.id,
            title: foundTask.title || `Aufgabe ${taskIdNum}`,
            description: foundTask.description || 'Stelle dich für das Foto auf und lächle in die Kamera.',
            instructions: foundTask.instructions,
            duration: foundTask.duration || 2,
            emotion: foundTask.emotion,
            difficulty: 'medium' as const
          });
        } else {
          // Fallback for unknown task ID
          setTask({
            id: taskIdNum,
            title: `Unbekannte Aufgabe ${taskIdNum}`,
            description: 'Stelle dich für das Foto auf und lächle in die Kamera.',
            instructions: 'Positioniere dich gut und warte auf den Countdown.',
            duration: 2,
            emotion: emotionSlug ? { slug: emotionSlug, name: emotionSlug.replace('-', ' ').replace(/\b\w/g, l => l.toUpperCase()) } : undefined,
            difficulty: 'medium' as const
          });
        }
      } catch (err) {
        console.error('Failed to fetch task:', err);
        setError('Aufgabe konnte nicht geladen werden');
        // Set fallback task
        setTask({
          id: taskIdNum,
          title: `Unbekannte Aufgabe ${taskIdNum}`,
          description: 'Stelle dich für das Foto auf und lächle in die Kamera.',
          instructions: 'Positioniere dich gut und warte auf den Countdown.',
          duration: 2,
          emotion: emotionSlug ? { slug: emotionSlug, name: emotionSlug.replace('-', ' ').replace(/\b\w/g, l => l.toUpperCase()) } : undefined,
          difficulty: 'medium' as const
        });
      } finally {
        setLoading(false);
      }
    }

    fetchTask();
  }, [slug, taskId, emotionSlug]);

  // Camera setup
  useEffect(() => {
    if (!slug || loading || !task) return;

    const setupCamera = async () => {
      try {
        const constraints: MediaStreamConstraints = {
          video: {
            width: { ideal: 1280 },
            height: { ideal: 720 },
            facingMode: facingMode ? { ideal: facingMode } : undefined
          }
        };

        console.log('Requesting camera with constraints:', constraints);

        const newStream = await navigator.mediaDevices.getUserMedia(constraints);
        if (videoRef.current) {
          videoRef.current.srcObject = newStream;
          videoRef.current.play().catch(e => console.error('Video play error:', e));
          // Set video dimensions after metadata is loaded
          videoRef.current.onloadedmetadata = () => {
            if (videoRef.current) {
              videoRef.current.style.display = 'block';
            }
          };
        }
        setStream(newStream);
        setError(null); // Clear any previous errors
      } catch (err: any) {
        console.error('Camera access error:', err.name, err.message);
        
        let errorMessage = 'Kamera konnte nicht gestartet werden.';
        
        switch (err.name) {
          case 'NotAllowedError':
            errorMessage = 'Kamera-Zugriff verweigert.\n\n' +
              '• Chrome: Adressleiste klicken → Kamera-Symbol → "Zulassen"\n' +
              '• Safari: Einstellungen → Website-Einstellungen → Kamera → "Erlauben"\n' +
              '• Firefox: Adressleiste → Berechtigungen → Kamera → "Erlauben"\n\n' +
              'Danach Seite neu laden.';
            break;
          case 'NotFoundError':
            errorMessage = 'Keine Kamera gefunden. Bitte überprüfen Sie:\n' +
              '• Ob eine Kamera am Gerät verfügbar ist\n' +
              '• Ob andere Apps die Kamera verwenden\n' +
              '• Gerätekonfiguration in den Browser-Einstellungen';
            break;
          case 'NotSupportedError':
            errorMessage = 'Kamera nicht unterstützt. Bitte verwenden Sie:\n' +
              '• Chrome, Firefox oder Safari (neueste Version)\n' +
              '• HTTPS-Verbindung (nicht HTTP)';
            break;
          case 'OverconstrainedError':
            errorMessage = 'Kamera-Einstellungen nicht verfügbar. Versuche mit Standard-Einstellungen...';
            // Fallback to basic constraints
            try {
              const fallbackConstraints = { video: true };
              const fallbackStream = await navigator.mediaDevices.getUserMedia(fallbackConstraints);
              if (videoRef.current) {
                videoRef.current.srcObject = fallbackStream;
                videoRef.current.play();
              }
              setStream(fallbackStream);
              setError(null);
              return;
            } catch (fallbackErr) {
              console.error('Fallback camera failed:', fallbackErr);
            }
            break;
          default:
            errorMessage = `Kamera-Fehler (${err.name}): ${err.message}\n\nBitte versuchen Sie:\n• Seite neu laden\n• Browser neu starten\n• Anderen Browser verwenden`;
        }
        
        setError(errorMessage);
      }
    };

    setupCamera();

    return () => {
      if (stream) {
        stream.getTracks().forEach(track => track.stop());
        setStream(null);
      }
    };
  }, [slug, loading, task, facingMode]);

  // Handle capture
  const handleCapture = useCallback(async () => {
    if (!videoRef.current || !canvasRef.current || !task) return;

    setCapturing(true);
    setIsPulsing(false);

    // Start countdown
    let count = 3;
    setCountdown(count);
    
    const countdownInterval = setInterval(() => {
      count--;
      setCountdown(count);
      if (count <= 0) {
        clearInterval(countdownInterval);
        
        // Capture photo
        const video = videoRef.current;
        const canvas = canvasRef.current;
        if (!canvas) return;
        
        const context = canvas.getContext('2d');
        if (!context || !video) return;
        
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        context.drawImage(video, 0, 0);
        
        // Convert to blob
        canvas.toBlob(async (blob) => {
          if (blob && task && slug) {
            try {
              // Show uploading state
              setUploading(true);
              setCapturing(false);
              setCountdown(3);
              setError(null);
              
              // Use emotionSlug directly (backend expects string slug)
              
              // Convert Blob to File with proper filename
              const timestamp = Date.now();
              const fileName = `photo-${timestamp}-${task.id}.jpg`;
              const file = new File([blob], fileName, {
                type: 'image/jpeg',
                lastModified: timestamp
              });
              
              console.log('Uploading photo:', {
                taskId: task.id,
                emotionSlug,
                fileName,
                fileSize: file.size
              });
              
              // Upload the photo
              const photoId = await uploadPhoto(slug, file, task.id, emotionSlug);
              
              console.log('Upload successful, photo ID:', photoId);
              
              // Navigate to gallery with success
              navigate(`/e/${slug}/gallery?task=${task.id}&emotion=${emotionSlug}&uploaded=true`);
            } catch (error: any) {
              console.error('Upload failed:', error);
              setError(`Upload fehlgeschlagen: ${error.message}\n\nFoto wurde erstellt, aber nicht hochgeladen.\nVersuchen Sie es erneut oder wählen Sie ein anderes Foto aus.`);
            } finally {
              setUploading(false);
            }
          }
        }, 'image/jpeg', 0.8);
        
        setCapturing(false);
        setCountdown(3);
      }
    }, 1000);

    // Start pulsing animation
    setIsPulsing(true);
  }, [task, emotionSlug, slug, navigate]);

  // Switch camera
  const switchCamera = () => {
    setFacingMode(prev => prev === 'user' ? 'environment' : 'user');
  };

  // Toggle flash (for back camera only)
  const toggleFlash = () => {
    if (facingMode !== 'environment') return;
    setFlashOn(prev => !prev);
    // TODO: Implement actual flash control if possible
  };

  if (loading) {
    return (
      <Page title="Kamera laden...">
        <div className={`flex flex-col items-center justify-center min-h-[60vh] p-4 ${
          isDark ? 'text-white' : 'text-gray-900'
        }`}>
          <Camera className="h-12 w-12 animate-pulse mb-4 text-pink-500" />
          <p className="text-sm">Kamera wird gestartet...</p>
        </div>
        <BottomNav />
      </Page>
    );
  }

  if (error || !task) {
    return (
      <Page title="Fehler">
        <div className={`flex flex-col items-center justify-center min-h-[60vh] p-4 ${
          isDark ? 'text-white' : 'text-gray-900'
        }`}>
          <Camera className="h-12 w-12 text-red-500 mb-4" />
          <div className="text-center space-y-2">
            <h2 className="text-xl font-semibold">Kamera nicht verfügbar</h2>
            <p className="text-sm text-muted-foreground max-w-md">{error}</p>
            <Button onClick={() => navigate(`/e/${slug}`)} variant="outline" className="mt-4">
              Zurück zur Startseite
            </Button>
          </div>
        </div>
        <BottomNav />
      </Page>
    );
  }

  if (uploading) {
    return (
      <Page title="Foto wird hochgeladen...">
        <div className={`flex flex-col items-center justify-center min-h-screen p-4 ${
          isDark ? 'text-white' : 'text-gray-900'
        }`}>
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-pink-500 mb-4"></div>
          <h2 className="text-xl font-semibold mb-2">Foto wird hochgeladen</h2>
          <p className="text-sm text-center text-muted-foreground">Bitte warten... Dies kann einen Moment dauern.</p>
          <Button
            onClick={() => navigate(`/e/${slug}/gallery`)}
            variant="outline"
            className="mt-6"
            disabled={true}
          >
            Zur Galerie
          </Button>
        </div>
        <BottomNav />
      </Page>
    );
  }

  const difficultyColor = task.difficulty === 'easy' ? 'text-green-400' :
                         task.difficulty === 'medium' ? 'text-yellow-400' : 'text-red-400';

  return (
    <Page title={task.title}>
      <div className={`min-h-screen flex flex-col ${
        isDark ? 'bg-gray-900 text-white' : 'bg-black text-white'
      }`}>
        {/* Camera Preview Container */}
        <div className="flex-1 relative overflow-hidden">
          {/* Video Background */}
          <video
            ref={videoRef}
            className="absolute inset-0 w-full h-full object-cover"
            playsInline
            muted
          />
          
          {/* Task Info Overlay */}
          <div className="absolute top-4 left-4 right-4 z-10">
            <div className="space-y-2 bg-black/40 backdrop-blur-sm rounded-xl p-4 border border-white/20">
              <h1 className="text-xl font-bold">{task.title}</h1>
              <p className="text-sm leading-relaxed opacity-90">{task.description}</p>
              {task.instructions && (
                <div className="text-xs italic opacity-80 mt-2 pt-2 border-t border-white/20">
                  💡 {task.instructions}
                </div>
              )}
              <div className="flex items-center justify-between pt-2">
                <span className={`text-xs font-medium ${difficultyColor}`}>
                  Schwierigkeit: {task.difficulty}
                </span>
                {emotionSlug && (
                  <span className="text-xs opacity-80">
                    Stimmung: {task.emotion?.name || emotionSlug}
                  </span>
                )}
              </div>
            </div>
          </div>

          {/* Camera Controls */}
          <div className="absolute bottom-20 left-4 right-4 z-10">
            <div className="flex justify-between items-center mb-6">
              {/* Flash Button */}
              <Button
                variant="ghost"
                size="icon"
                onClick={toggleFlash}
                disabled={facingMode === 'user'}
                className="h-12 w-12 rounded-full bg-black/40 backdrop-blur-sm border border-white/20"
              >
                {flashOn ? <Zap className="h-6 w-6 text-yellow-400" /> : <ZapOff className="h-6 w-6" />}
              </Button>

              {/* Capture Button */}
              <div className="relative">
                <Button
                  variant="ghost"
                  size="icon"
                  onClick={handleCapture}
                  disabled={capturing}
                  className={`
                    h-20 w-20 rounded-full bg-white/20 backdrop-blur-sm border-4 border-white/30
                    ${isPulsing ? 'animate-pulse-ring' : ''}
                    disabled:opacity-50 disabled:cursor-not-allowed
                  `}
                >
                  <div className="relative">
                    <Camera className="h-8 w-8" />
                    {capturing && (
                      <div className="absolute inset-0 flex items-center justify-center">
                        <div className="text-lg font-bold text-white">{countdown}</div>
                      </div>
                    )}
                  </div>
                </Button>
                {/* Pulsing Ring Animation */}
                {isPulsing && (
                  <div className="absolute inset-0 rounded-full h-20 w-20 border-4 border-pink-400/50 animate-ping" />
                )}
              </div>

              {/* Switch Camera Button */}
              <Button
                variant="ghost"
                size="icon"
                onClick={switchCamera}
                className="h-12 w-12 rounded-full bg-black/40 backdrop-blur-sm border border-white/20"
              >
                <RotateCcw className="h-6 w-6" />
              </Button>
            </div>
          </div>

          {/* Hidden Canvas for Capture */}
          <canvas ref={canvasRef} className="hidden" />
        </div>

        <BottomNav />
      </div>

      <style>{`
        @keyframes pulse-ring {
          0% {
            transform: scale(1);
            opacity: 1;
          }
          100% {
            transform: scale(1.5);
            opacity: 0;
          }
        }
        .animate-ping {
          animation: pulse-ring 1.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
        }
      `}</style>
    </Page>
  );
}
