'use client';

import React, { useRef, useState } from 'react';
import { Camera, Upload, CheckCircle2, AlertCircle, Sparkles, ExternalLink, ChevronRight } from 'lucide-react';
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs';
import { useRouter, useSearchParams } from 'next/navigation';
import { analyzeBottle } from '@/services/analyze-bottle';
import { saveBottle } from '@/services/save-bottle';
import { BottleMetadata } from '@/types/whisky';
import { savePendingBottle } from '@/lib/offline-db';
import { v4 as uuidv4 } from 'uuid';
import { findMatchingBottle } from '@/services/find-matching-bottle';
import { validateSession } from '@/services/validate-session';
import Link from 'next/link';

interface CameraCaptureProps {
    onImageCaptured?: (base64Image: string) => void;
    onAnalysisComplete?: (data: BottleMetadata) => void;
    onSaveComplete?: () => void;
}

export default function CameraCapture({ onImageCaptured, onAnalysisComplete, onSaveComplete }: CameraCaptureProps) {
    const supabase = createClientComponentClient();
    const router = useRouter();
    const searchParams = useSearchParams();
    const sessionId = searchParams.get('session_id');
    const [validatedSessionId, setValidatedSessionId] = React.useState<string | null>(null);

    React.useEffect(() => {
        const checkSession = async () => {
            if (sessionId) {
                const isValid = await validateSession(sessionId);
                setValidatedSessionId(isValid ? sessionId : null);
            } else {
                setValidatedSessionId(null);
            }
        };
        checkSession();
    }, [sessionId]);

    const fileInputRef = useRef<HTMLInputElement>(null);
    const [isProcessing, setIsProcessing] = useState(false);
    const [isSaving, setIsSaving] = useState(false);
    const [previewUrl, setPreviewUrl] = useState<string | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [analysisResult, setAnalysisResult] = useState<BottleMetadata | null>(null);
    const [isQueued, setIsQueued] = useState(false);
    const [matchingBottle, setMatchingBottle] = useState<{ id: string; name: string } | null>(null);
    const [lastSavedId, setLastSavedId] = useState<string | null>(null);

    const handleCapture = async (event: React.ChangeEvent<HTMLInputElement>) => {
        const file = event.target.files?.[0];
        if (!file) return;

        setIsProcessing(true);
        setError(null);
        setAnalysisResult(null);
        setIsQueued(false);
        setMatchingBottle(null);

        try {
            let fileToProcess = file;

            // HEIC / HEIF Check
            const isHeic = file.type === 'image/heic' || file.type === 'image/heif' || file.name.toLowerCase().endsWith('.heic') || file.name.toLowerCase().endsWith('.heif');

            if (isHeic) {
                console.log('HEIC detected, converting...');
                const heic2any = (await import('heic2any')).default;
                const convertedBlob = await heic2any({
                    blob: file,
                    toType: 'image/jpeg',
                    quality: 0.8
                });

                // heic2any can return an array if the file contains multiple images
                const blob = Array.isArray(convertedBlob) ? convertedBlob[0] : convertedBlob;
                fileToProcess = new File([blob], file.name.replace(/\.(heic|heif)$/i, '.jpg'), {
                    type: 'image/jpeg'
                });
            }

            const compressedBase64 = await compressImage(fileToProcess);
            setPreviewUrl(compressedBase64);

            if (onImageCaptured) {
                onImageCaptured(compressedBase64);
            }

            // Check if Offline
            if (!navigator.onLine) {
                console.log('Offline detected. Queuing image...');
                await savePendingBottle({
                    id: uuidv4(),
                    imageBase64: compressedBase64,
                    timestamp: Date.now(),
                });
                setIsQueued(true);
                return;
            }

            const response = await analyzeBottle(compressedBase64);

            if (response.success && response.data) {
                setAnalysisResult(response.data);

                // Duplicate Check
                const match = await findMatchingBottle(response.data);
                if (match) {
                    setMatchingBottle(match);
                }

                if (onAnalysisComplete) {
                    onAnalysisComplete(response.data);
                }
            } else {
                setError(response.error || 'Analyse fehlgeschlagen.');
            }
        } catch (err) {
            console.error('Processing failed:', err);
            setError('Verarbeitung fehlgeschlagen. Bitte erneut versuchen.');
        } finally {
            setIsProcessing(false);
        }
    };

    const handleSave = async () => {
        if (!analysisResult || !previewUrl) return;

        setIsSaving(true);
        setError(null);

        try {
            // Get current user (simple check for now, can be improved with Auth)
            const { data: { user } } = await supabase.auth.getUser();
            if (!user) {
                throw new Error('Bitte melde dich an, um Flaschen zu speichern.');
            }

            const response = await saveBottle(analysisResult, previewUrl, user.id);

            if (response.success && response.data) {
                setLastSavedId(response.data.id);
                if (onSaveComplete) onSaveComplete();
            } else {
                setError(response.error || 'Speichern fehlgeschlagen.');
            }
        } catch (err) {
            console.error('Save failed:', err);
            setError(err instanceof Error ? err.message : 'Speichern fehlgeschlagen.');
        } finally {
            setIsSaving(false);
        }
    };

    const compressImage = (file: File): Promise<string> => {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = (event) => {
                const img = new Image();
                img.src = event.target?.result as string;
                img.onload = () => {
                    const canvas = document.createElement('canvas');
                    const MAX_WIDTH = 1024;
                    let width = img.width;
                    let height = img.height;

                    if (width > MAX_WIDTH) {
                        height = (height * MAX_WIDTH) / width;
                        width = MAX_WIDTH;
                    }

                    canvas.width = width;
                    canvas.height = height;

                    const ctx = canvas.getContext('2d');
                    if (!ctx) {
                        reject(new Error('Canvas context not available'));
                        return;
                    }

                    ctx.drawImage(img, 0, 0, width, height);
                    const base64 = canvas.toDataURL('image/jpeg', 0.8);
                    resolve(base64);
                };
                img.onerror = reject;
            };
            reader.onerror = reject;
        });
    };

    const triggerUpload = () => {
        fileInputRef.current?.click();
    };

    return (
        <div className="flex flex-col items-center gap-4 md:gap-6 w-full max-w-md mx-auto p-4 md:p-6 bg-white dark:bg-zinc-900 rounded-3xl shadow-2xl border border-zinc-200 dark:border-zinc-800 transition-all hover:shadow-whisky-amber/20">
            <h2 className="text-xl md:text-2xl font-bold text-zinc-800 dark:text-zinc-100 italic">Magic Shot</h2>

            <div
                className="relative group cursor-pointer w-full aspect-square rounded-2xl border-2 border-dashed border-zinc-300 dark:border-zinc-700 overflow-hidden flex items-center justify-center bg-zinc-50 dark:bg-zinc-800/50 hover:border-amber-500 transition-colors"
                onClick={triggerUpload}
            >
                {previewUrl ? (
                    <img src={previewUrl} alt="Preview" className="w-full h-full object-cover" />
                ) : (
                    <div className="flex flex-col items-center gap-2 text-zinc-400 group-hover:text-amber-500 transition-colors">
                        <Camera size={48} strokeWidth={1.5} />
                        <span className="text-sm font-medium">Flasche scannen</span>
                    </div>
                )}

                {isProcessing && (
                    <div className="absolute inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center">
                        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-white"></div>
                    </div>
                )}
            </div>

            <input
                type="file"
                accept="image/*"
                capture="environment"
                ref={fileInputRef}
                onChange={handleCapture}
                className="hidden"
            />

            {lastSavedId ? (
                <div className="flex flex-col gap-3 w-full animate-in zoom-in-95 duration-300">
                    <div className="flex items-center gap-2 text-green-600 font-bold justify-center p-2">
                        <CheckCircle2 size={24} className="text-green-500" />
                        Erfolgreich gespeichert!
                    </div>

                    <button
                        onClick={() => {
                            const url = `/bottles/${lastSavedId}${validatedSessionId ? `?session_id=${validatedSessionId}` : ''}`;
                            router.push(url);
                        }}
                        className="w-full py-4 px-6 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 rounded-2xl font-black uppercase tracking-widest flex items-center justify-center gap-2 hover:bg-zinc-800 dark:hover:bg-white transition-all shadow-xl"
                    >
                        Jetzt verkosten
                        <ChevronRight size={20} />
                    </button>

                    <button
                        onClick={() => {
                            setPreviewUrl(null);
                            setAnalysisResult(null);
                            setLastSavedId(null);
                        }}
                        className="w-full py-3 px-6 text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200 font-bold transition-colors"
                    >
                        Später (Zurück zur Liste)
                    </button>
                </div>
            ) : matchingBottle ? (
                <Link
                    href={`/bottles/${matchingBottle.id}${validatedSessionId ? `?session_id=${validatedSessionId}` : ''}`}
                    className="w-full py-4 px-6 bg-amber-600 hover:bg-amber-700 text-white rounded-xl font-semibold flex items-center justify-center gap-2 transition-all active:scale-[0.98] shadow-lg shadow-amber-600/20"
                >
                    <ExternalLink size={20} />
                    Zum Whisky im Vault
                </Link>
            ) : (
                <button
                    onClick={isQueued ? () => setPreviewUrl(null) : (previewUrl && analysisResult ? handleSave : triggerUpload)}
                    disabled={isProcessing || isSaving}
                    className="w-full py-4 px-6 bg-amber-600 hover:bg-amber-700 text-white rounded-xl font-semibold flex items-center justify-center gap-2 transition-all active:scale-[0.98] shadow-lg shadow-amber-600/20 disabled:opacity-50"
                >
                    {isSaving ? (
                        <>
                            <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>
                            Wird gespeichert...
                        </>
                    ) : isQueued ? (
                        <>
                            <CheckCircle2 size={20} />
                            Nächste Flasche
                        </>
                    ) : previewUrl && analysisResult ? (
                        <>
                            <CheckCircle2 size={20} />
                            Im Vault speichern
                        </>
                    ) : previewUrl ? (
                        <>
                            <Upload size={20} />
                            Neu aufnehmen
                        </>
                    ) : (
                        <>
                            <Camera size={20} />
                            Kamera öffnen
                        </>
                    )}
                </button>
            )}

            {error && (
                <div className="flex items-center gap-2 text-red-500 text-sm bg-red-50 dark:bg-red-900/10 p-3 rounded-lg w-full">
                    <AlertCircle size={16} />
                    {error}
                </div>
            )}

            {isQueued && (
                <div className="flex items-center gap-2 text-purple-500 text-sm bg-purple-50 dark:bg-purple-900/10 p-4 rounded-xl w-full border border-purple-100 dark:border-purple-800/30 font-medium">
                    <Sparkles size={16} />
                    Offline! Foto wurde gemerkt – wird automatisch analysiert, sobald du wieder Netz hast. 📡
                </div>
            )}

            {matchingBottle && (
                <div className="flex flex-col gap-2 p-4 bg-blue-50 dark:bg-blue-900/10 border border-blue-200 dark:border-blue-900/30 rounded-xl w-full">
                    <div className="flex items-center gap-2 text-blue-600 dark:text-blue-400 font-bold text-sm">
                        <AlertCircle size={16} />
                        Bereits im Vault!
                    </div>
                    <p className="text-xs text-blue-500/80">
                        Du hast diesen Whisky bereits in deiner Sammlung. Willst du direkt zur Flasche gehen?
                    </p>
                    <button
                        onClick={() => setMatchingBottle(null)}
                        className="text-[10px] text-zinc-400 font-black uppercase text-left hover:text-zinc-600"
                    >
                        Trotzdem als neue Flasche speichern
                    </button>
                </div>
            )}

            {previewUrl && !isProcessing && !error && !isQueued && !matchingBottle && (
                <div className="flex flex-col gap-3 w-full animate-in fade-in slide-in-from-top-4 duration-500">
                    <div className="flex items-center gap-2 text-green-500 text-sm bg-green-50 dark:bg-green-900/10 p-3 rounded-lg w-full">
                        <CheckCircle2 size={16} />
                        Bild erfolgreich analysiert
                    </div>

                    {analysisResult && (
                        <div className="p-3 md:p-4 bg-zinc-50 dark:bg-zinc-800/50 rounded-2xl border border-zinc-200 dark:border-zinc-700">
                            <div className="flex items-center gap-2 mb-2 md:mb-3 text-amber-600 dark:text-amber-500">
                                <Sparkles size={18} />
                                <span className="font-bold text-[10px] md:text-sm uppercase tracking-wider">Ergebnisse</span>
                            </div>
                            <div className="space-y-2">
                                <div className="flex justify-between text-sm">
                                    <span className="text-zinc-500">Name:</span>
                                    <span className="font-semibold">{analysisResult.name || '-'}</span>
                                </div>
                                <div className="flex justify-between text-sm">
                                    <span className="text-zinc-500">Distille:</span>
                                    <span className="font-semibold">{analysisResult.distillery || '-'}</span>
                                </div>
                                <div className="flex justify-between text-sm">
                                    <span className="text-zinc-500">Kategorie:</span>
                                    <span className="font-semibold">{analysisResult.category || '-'}</span>
                                </div>
                                <div className="flex justify-between text-sm">
                                    <span className="text-zinc-500">ABV:</span>
                                    <span className="font-semibold">{analysisResult.abv ? `${analysisResult.abv}%` : '-'}</span>
                                </div>
                            </div>
                        </div>
                    )}
                </div>
            )}
        </div>
    );
}
