import React, { useState, useRef, useEffect } from 'react';
import Tesseract from 'tesseract.js';

interface CameraScannerProps {
  onCardScanned: (cardData: any) => void;
  onError: (error: string) => void;
}

interface ScanResult {
  text: string;
  confidence: number;
  cardName?: string;
  setName?: string;
}

const CameraScanner: React.FC<CameraScannerProps> = ({ onCardScanned, onError }) => {
  const [isStreaming, setIsStreaming] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [scanResult, setScanResult] = useState<ScanResult | null>(null);
  const [capturedImage, setCapturedImage] = useState<string | null>(null);
  
  const videoRef = useRef<HTMLVideoElement>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const streamRef = useRef<MediaStream | null>(null);

  // Start camera stream
  const startCamera = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: {
          facingMode: 'environment', // Use back camera on mobile
          width: { ideal: 1920 },
          height: { ideal: 1080 }
        }
      });

      if (videoRef.current) {
        videoRef.current.srcObject = stream;
        streamRef.current = stream;
        setIsStreaming(true);
      }
    } catch (err) {
      console.error('Camera access error:', err);
      onError('Unable to access camera. Please check permissions.');
    }
  };

  // Stop camera stream
  const stopCamera = () => {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach(track => track.stop());
      streamRef.current = null;
    }
    setIsStreaming(false);
    setCapturedImage(null);
    setScanResult(null);
  };

  // Capture image from video stream
  const captureImage = () => {
    if (!videoRef.current || !canvasRef.current) return;

    const video = videoRef.current;
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');

    // Set canvas dimensions to match video
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;

    // Draw current video frame to canvas
    ctx?.drawImage(video, 0, 0, canvas.width, canvas.height);

    // Get image data URL
    const imageDataUrl = canvas.toDataURL('image/jpeg', 0.8);
    setCapturedImage(imageDataUrl);

    // Process with OCR
    processImage(imageDataUrl);
  };

  // Process image with Tesseract OCR
  const processImage = async (imageData: string) => {
    setIsProcessing(true);
    setScanResult(null);

    try {
      const { data: { text, confidence } } = await Tesseract.recognize(imageData, 'eng', {
        logger: m => console.log(m) // Optional: log progress
      });

      console.log('OCR Result:', text);
      console.log('Confidence:', confidence);

      // Extract card information from OCR text
      const cardInfo = extractCardInfo(text);
      
      const result: ScanResult = {
        text: text.trim(),
        confidence,
        cardName: cardInfo.name,
        setName: cardInfo.set
      };

      setScanResult(result);

      // If we found card info, try to match against database
      if (cardInfo.name) {
        onCardScanned({
          name: cardInfo.name,
          set: cardInfo.set,
          ocrText: text,
          confidence: confidence
        });
      }

    } catch (error) {
      console.error('OCR processing error:', error);
      onError('Failed to process image. Please try again.');
    } finally {
      setIsProcessing(false);
    }
  };

  // Extract card name and set from OCR text
  const extractCardInfo = (text: string) => {
    const lines = text.split('\n').map(line => line.trim()).filter(line => line.length > 0);
    
    // Common patterns for different card games
    const patterns = {
      // Magic: The Gathering patterns
      mtg: {
        cardName: /^[A-Z][a-zA-Z\s,'-]+(?=\s|$)/,
        setInfo: /\b([A-Z]{3}|[A-Z]{4})\b/, // 3-4 letter set codes
      },
      // Pokemon patterns  
      pokemon: {
        cardName: /^[A-Z][a-zA-Z\s]+(?=\s+[0-9])/,
        hpPattern: /HP\s*[0-9]+/,
      },
      // Lorcana patterns
      lorcana: {
        cardName: /^[A-Z][a-zA-Z\s,'-]+(?=\s*-)/,
        subtitle: /-\s*([A-Z][a-zA-Z\s]+)/,
      }
    };

    let cardName = '';
    let setName = '';

    // Try to find the card name (usually the first substantial line)
    for (const line of lines) {
      if (line.length > 3 && line.length < 50) { // Reasonable card name length
        // Skip common non-name text
        if (!line.match(/^(hp|©|legendary|instant|sorcery|creature|artifact|enchantment)$/i)) {
          if (!cardName || line.length > cardName.length) {
            cardName = line;
          }
        }
      }
    }

    // Try to extract set information
    const setText = lines.find(line => patterns.mtg.setInfo.test(line));
    if (setText) {
      const setMatch = setText.match(patterns.mtg.setInfo);
      if (setMatch) {
        setName = setMatch[1];
      }
    }

    return {
      name: cardName || '',
      set: setName || ''
    };
  };

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

  return (
    <div className="camera-scanner">
      {/* Camera Controls */}
      <div className="flex gap-4 mb-4">
        {!isStreaming ? (
          <button
            onClick={startCamera}
            className="bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-3 rounded-lg font-medium transition-colors flex items-center gap-2"
          >
            <span>📹</span> Start Camera
          </button>
        ) : (
          <>
            <button
              onClick={captureImage}
              disabled={isProcessing}
              className="bg-green-600 hover:bg-green-700 disabled:bg-gray-400 text-white px-6 py-3 rounded-lg font-medium transition-colors flex items-center gap-2"
            >
              <span>📸</span> 
              {isProcessing ? 'Processing...' : 'Capture Card'}
            </button>
            <button
              onClick={stopCamera}
              className="bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg font-medium transition-colors flex items-center gap-2"
            >
              <span>⏹️</span> Stop Camera
            </button>
          </>
        )}
      </div>

      {/* Camera Preview */}
      {isStreaming && (
        <div className="relative bg-black rounded-lg overflow-hidden mb-4">
          <video
            ref={videoRef}
            autoPlay
            playsInline
            muted
            className="w-full h-auto max-h-96 object-cover"
          />
          
          {/* Scan Guide Overlay */}
          <div className="absolute inset-0 pointer-events-none">
            <div className="absolute inset-4 border-2 border-white border-dashed rounded-lg flex items-center justify-center">
              <div className="bg-black bg-opacity-50 text-white px-4 py-2 rounded-lg text-sm text-center">
                <div className="font-medium">Position card within this area</div>
                <div className="text-xs opacity-75">Ensure good lighting and focus</div>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Hidden canvas for image capture */}
      <canvas ref={canvasRef} className="hidden" />

      {/* Processing Status */}
      {isProcessing && (
        <div className="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4">
          <div className="flex items-center gap-3">
            <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600"></div>
            <div>
              <div className="font-medium text-blue-900">Processing image...</div>
              <div className="text-sm text-blue-600">Extracting card information</div>
            </div>
          </div>
        </div>
      )}

      {/* Captured Image Preview */}
      {capturedImage && !isProcessing && (
        <div className="bg-white rounded-lg border border-gray-200 p-4 mb-4">
          <div className="font-medium text-gray-900 mb-2">Captured Image</div>
          <img 
            src={capturedImage} 
            alt="Captured card"
            className="max-w-full h-auto max-h-48 rounded border border-gray-300"
          />
        </div>
      )}

      {/* OCR Results */}
      {scanResult && (
        <div className="bg-white rounded-lg border border-gray-200 p-4">
          <div className="font-medium text-gray-900 mb-2">Scan Results</div>
          
          {scanResult.cardName ? (
            <div className="space-y-2">
              <div className="flex items-center gap-2">
                <span className="text-green-600">✅</span>
                <div>
                  <div className="font-medium">Card Found: {scanResult.cardName}</div>
                  {scanResult.setName && (
                    <div className="text-sm text-gray-600">Set: {scanResult.setName}</div>
                  )}
                </div>
              </div>
              <div className="text-sm text-gray-500">
                Confidence: {Math.round(scanResult.confidence)}%
              </div>
            </div>
          ) : (
            <div className="space-y-2">
              <div className="flex items-center gap-2">
                <span className="text-yellow-600">⚠️</span>
                <div className="font-medium">Card not recognized</div>
              </div>
              <details className="text-sm text-gray-600">
                <summary className="cursor-pointer">View OCR text</summary>
                <pre className="mt-2 whitespace-pre-wrap bg-gray-50 p-2 rounded text-xs">
                  {scanResult.text}
                </pre>
              </details>
            </div>
          )}
        </div>
      )}

      {/* Instructions */}
      <div className="bg-gray-50 rounded-lg p-4 mt-4">
        <div className="font-medium text-gray-900 mb-2">📋 Scanning Tips</div>
        <ul className="text-sm text-gray-600 space-y-1">
          <li>• Ensure good lighting and avoid shadows</li>
          <li>• Keep the card flat and in focus</li>
          <li>• Position the card name clearly in view</li>
          <li>• Avoid glare and reflections</li>
          <li>• Works best with English cards</li>
        </ul>
      </div>
    </div>
  );
};

export default CameraScanner; 