'use client';

/**
 * Native OCR Scanner Component
 * 
 * Uses the Shape Detection API (TextDetector) for zero-latency, 
 * zero-download OCR directly from the camera stream.
 * 
 * Only works on Android/Chrome/Edge. iOS uses the Live Text fallback.
 */

import React, { useRef, useEffect, useState, useCallback } from 'react';
import { X, Camera, Loader2, Zap, CheckCircle } from 'lucide-react';
import { useScanFlow } from '@/hooks/useScanFlow';
import { normalizeDistillery } from '@/lib/distillery-matcher';

interface NativeOCRScannerProps {
    isOpen: boolean;
    onClose: () => void;
    onTextDetected: (texts: string[]) => void;
    onAutoCapture?: (result: {
        rawTexts: string[];
        distillery: string | null;
        abv: number | null;
        age: number | null;
    }) => void;
}

// RegEx patterns for auto-extraction
const PATTERNS = {
    abv: /(\d{1,2}[.,]\d{1}|\d{1,2})\s*%\s*(?:vol|alc)?/i,
    age: /(\d{1,2})\s*(?:years?|yo|y\.?o\.?|jahre?)\s*(?:old)?/i,
};

export default function NativeOCRScanner({
    isOpen,
    onClose,
    onTextDetected,
    onAutoCapture
}: NativeOCRScannerProps) {
    const videoRef = useRef<HTMLVideoElement>(null);
    const streamRef = useRef<MediaStream | null>(null);
    const animationRef = useRef<number | null>(null);

    const { processVideoFrame } = useScanFlow();

    const [isStreaming, setIsStreaming] = useState(false);
    const [detectedTexts, setDetectedTexts] = useState<string[]>([]);
    const [extractedData, setExtractedData] = useState<{
        distillery: string | null;
        abv: number | null;
        age: number | null;
    }>({ distillery: null, abv: null, age: null });
    const [isAutoCapturing, setIsAutoCapturing] = useState(false);

    // Start camera stream
    const startStream = useCallback(async () => {
        try {
            console.log('[NativeOCR] Starting camera stream...');
            const stream = await navigator.mediaDevices.getUserMedia({
                video: {
                    facingMode: 'environment',
                    width: { ideal: 1280 },
                    height: { ideal: 720 },
                },
            });

            streamRef.current = stream;

            if (videoRef.current) {
                videoRef.current.srcObject = stream;
                await videoRef.current.play();
                setIsStreaming(true);
                console.log('[NativeOCR] Camera stream started');
            }
        } catch (err) {
            console.error('[NativeOCR] Camera access failed:', err);
        }
    }, []);

    // Stop camera stream
    const stopStream = useCallback(() => {
        console.log('[NativeOCR] Stopping camera stream...');

        if (animationRef.current) {
            cancelAnimationFrame(animationRef.current);
            animationRef.current = null;
        }

        if (streamRef.current) {
            streamRef.current.getTracks().forEach(track => track.stop());
            streamRef.current = null;
        }

        if (videoRef.current) {
            videoRef.current.srcObject = null;
        }

        setIsStreaming(false);
        setDetectedTexts([]);
    }, []);

    // Process frames continuously
    const processLoop = useCallback(async () => {
        if (!videoRef.current || !isStreaming) return;

        const texts = await processVideoFrame(videoRef.current);

        if (texts.length > 0) {
            setDetectedTexts(texts);
            onTextDetected(texts);

            // Try to extract structured data
            const allText = texts.join(' ');

            // ABV
            const abvMatch = allText.match(PATTERNS.abv);
            const abv = abvMatch ? parseFloat(abvMatch[1].replace(',', '.')) : null;

            // Age
            const ageMatch = allText.match(PATTERNS.age);
            const age = ageMatch ? parseInt(ageMatch[1], 10) : null;

            // Distillery (fuzzy match)
            let distillery: string | null = null;
            for (const text of texts) {
                if (text.length >= 4 && text.length <= 40) {
                    const match = normalizeDistillery(text);
                    if (match.matched) {
                        distillery = match.name;
                        break;
                    }
                }
            }

            setExtractedData({ distillery, abv, age });

            // Auto-capture if we have enough data
            if (distillery && (abv || age) && !isAutoCapturing) {
                console.log('[NativeOCR] Auto-capture triggered:', { distillery, abv, age });
                setIsAutoCapturing(true);

                if (onAutoCapture) {
                    onAutoCapture({
                        rawTexts: texts,
                        distillery,
                        abv,
                        age,
                    });
                }

                // Visual feedback before closing
                setTimeout(() => {
                    onClose();
                }, 1500);
            }
        }

        // Continue loop (throttled to ~5 FPS for performance)
        animationRef.current = window.setTimeout(() => {
            requestAnimationFrame(processLoop);
        }, 200) as unknown as number;
    }, [isStreaming, processVideoFrame, onTextDetected, onAutoCapture, isAutoCapturing, onClose]);

    // Start/stop based on isOpen
    useEffect(() => {
        if (isOpen) {
            startStream();
        } else {
            stopStream();
        }

        return () => {
            stopStream();
        };
    }, [isOpen, startStream, stopStream]);

    // Start processing loop when streaming
    useEffect(() => {
        if (isStreaming) {
            processLoop();
        }
    }, [isStreaming, processLoop]);

    if (!isOpen) return null;

    return (
        <div className="fixed inset-0 z-50 bg-black">
            {/* Header */}
            <div className="absolute top-0 left-0 right-0 z-10 flex items-center justify-between p-4 bg-gradient-to-b from-black/80 to-transparent">
                <div className="flex items-center gap-2 text-white">
                    <Zap size={20} className="text-orange-500" />
                    <span className="font-bold text-sm">Native OCR</span>
                </div>
                <button
                    onClick={onClose}
                    className="p-2 rounded-full bg-white/10 text-white hover:bg-white/20"
                >
                    <X size={24} />
                </button>
            </div>

            {/* Video Feed */}
            <video
                ref={videoRef}
                playsInline
                muted
                className="w-full h-full object-cover"
            />

            {/* Scan Overlay */}
            <div className="absolute inset-0 pointer-events-none">
                {/* Scan Frame */}
                <div className="absolute inset-[10%] border-2 border-orange-500/50 rounded-2xl">
                    <div className="absolute top-0 left-0 w-8 h-8 border-t-4 border-l-4 border-orange-500 rounded-tl-xl" />
                    <div className="absolute top-0 right-0 w-8 h-8 border-t-4 border-r-4 border-orange-500 rounded-tr-xl" />
                    <div className="absolute bottom-0 left-0 w-8 h-8 border-b-4 border-l-4 border-orange-500 rounded-bl-xl" />
                    <div className="absolute bottom-0 right-0 w-8 h-8 border-b-4 border-r-4 border-orange-500 rounded-br-xl" />
                </div>

                {/* Scanning indicator */}
                {isStreaming && !isAutoCapturing && (
                    <div className="absolute top-[12%] left-1/2 -translate-x-1/2 flex items-center gap-2 px-4 py-2 bg-black/60 rounded-full text-white text-sm">
                        <Loader2 size={16} className="animate-spin text-orange-500" />
                        Scanning...
                    </div>
                )}

                {/* Auto-capture success */}
                {isAutoCapturing && (
                    <div className="absolute top-[12%] left-1/2 -translate-x-1/2 flex items-center gap-2 px-4 py-2 bg-green-600 rounded-full text-white text-sm">
                        <CheckCircle size={16} />
                        Captured!
                    </div>
                )}
            </div>

            {/* Detected Text Display */}
            <div className="absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/90 to-transparent">
                {extractedData.distillery && (
                    <div className="mb-2 px-3 py-1 bg-orange-600 rounded-full inline-block">
                        <span className="text-white text-sm font-bold">
                            🏭 {extractedData.distillery}
                        </span>
                    </div>
                )}

                <div className="flex gap-2 flex-wrap mb-2">
                    {extractedData.abv && (
                        <span className="px-2 py-1 bg-white/20 rounded text-white text-xs">
                            {extractedData.abv}% ABV
                        </span>
                    )}
                    {extractedData.age && (
                        <span className="px-2 py-1 bg-white/20 rounded text-white text-xs">
                            {extractedData.age} Years
                        </span>
                    )}
                </div>

                {detectedTexts.length > 0 && (
                    <div className="max-h-20 overflow-y-auto">
                        <p className="text-zinc-400 text-xs">
                            {detectedTexts.slice(0, 5).join(' • ')}
                        </p>
                    </div>
                )}

                {!detectedTexts.length && isStreaming && (
                    <p className="text-zinc-500 text-sm text-center">
                        Point camera at the bottle label
                    </p>
                )}
            </div>
        </div>
    );
}
