'use client'; import React, { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { X, Loader2, Sparkles, AlertCircle } from 'lucide-react'; import TastingEditor from './TastingEditor'; import SessionBottomSheet from './SessionBottomSheet'; import ResultCard from './ResultCard'; import { useSession } from '@/context/SessionContext'; import { magicScan } from '@/services/magic-scan'; import { saveBottle } from '@/services/save-bottle'; import { saveTasting } from '@/services/save-tasting'; import { BottleMetadata } from '@/types/whisky'; import { useI18n } from '@/i18n/I18nContext'; import { createClient } from '@/lib/supabase/client'; type FlowState = 'IDLE' | 'SCANNING' | 'EDITOR' | 'RESULT' | 'ERROR'; interface ScanAndTasteFlowProps { isOpen: boolean; onClose: () => void; base64Image: string | null; } export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanAndTasteFlowProps) { const [state, setState] = useState('IDLE'); const [isSessionsOpen, setIsSessionsOpen] = useState(false); const { activeSession } = useSession(); const [tastingData, setTastingData] = useState(null); const [bottleMetadata, setBottleMetadata] = useState(null); const [error, setError] = useState(null); const [isSaving, setIsSaving] = useState(false); const { locale } = useI18n(); const supabase = createClient(); // Trigger scan when open and image provided useEffect(() => { if (isOpen && base64Image) { console.log('[ScanFlow] Starting handleScan...'); handleScan(base64Image); } else if (!isOpen) { setState('IDLE'); setTastingData(null); setBottleMetadata(null); setError(null); setIsSaving(false); } }, [isOpen, base64Image]); const handleScan = async (image: string) => { setState('SCANNING'); setError(null); try { const cleanBase64 = image.split(',')[1] || image; console.log('[ScanFlow] Calling magicScan service...'); const result = await magicScan(cleanBase64, 'gemini', locale); if (result.success && result.data) { console.log('[ScanFlow] magicScan success'); setBottleMetadata(result.data); setState('EDITOR'); } else { console.error('[ScanFlow] magicScan failure:', result.error); throw new Error(result.error || 'Flasche konnte nicht erkannt werden.'); } } catch (err: any) { console.error('[ScanFlow] handleScan error:', err); setError(err.message); setState('ERROR'); } }; const handleSaveTasting = async (formData: any) => { if (!bottleMetadata || !base64Image) return; setIsSaving(true); setError(null); try { const { data: { user } = {} } = await supabase.auth.getUser(); if (!user) throw new Error('Nicht autorisiert'); // 1. Save Bottle const bottleResult = await saveBottle(bottleMetadata, base64Image, user.id); if (!bottleResult.success || !bottleResult.data) { throw new Error(bottleResult.error || 'Fehler beim Speichern der Flasche'); } const bottleId = bottleResult.data.id; // 2. Save Tasting const tastingNote = { ...formData, bottle_id: bottleId, }; const tastingResult = await saveTasting(tastingNote); if (!tastingResult.success) { throw new Error(tastingResult.error || 'Fehler beim Speichern des Tastings'); } setTastingData(tastingNote); setState('RESULT'); } catch (err: any) { setError(err.message); setState('ERROR'); } finally { setIsSaving(false); } }; const handleShare = async () => { if (navigator.share) { try { await navigator.share({ title: `My Tasting: ${bottleMetadata?.name || 'Whisky'}`, text: `Check out my tasting results for ${bottleMetadata?.distillery} ${bottleMetadata?.name}!`, url: window.location.href, }); } catch (err) { console.error('Share failed:', err); } } else { alert('Sharing is not supported on this browser.'); } }; return ( {isOpen && ( {/* Close Button */}
{/* Robust state check: If we are IDLE but have an image, we are essentially SCANNING (or about to be). If we have no image, we shouldn't really be here, but show error just in case. */} {(state === 'SCANNING' || (state === 'IDLE' && base64Image)) && (

Analysiere Etikett...

KI-gestütztes Scanning

)} {state === 'ERROR' && (

Ups! Da lief was schief.

{error || 'Wir konnten die Flasche leider nicht erkennen. Bitte versuch es mit einem anderen Foto.'}

)} {state === 'EDITOR' && bottleMetadata && ( setIsSessionsOpen(true)} activeSessionName={activeSession?.name} activeSessionId={activeSession?.id} /> )} {(isSaving) && (

Speichere Tasting...

)} {state === 'RESULT' && tastingData && bottleMetadata && (
)}
setIsSessionsOpen(false)} />
)}
); }