'use client';

import { useState, useCallback, useRef } from 'react';
import { BottleMetadata } from '@/types/whisky';
import { processImageForAI, ProcessedImage } from '@/utils/image-processing';
import { analyzeBottleLabel } from '@/app/actions/scanner';
import { generateDummyMetadata } from '@/utils/generate-dummy-metadata';
import { db } from '@/lib/db';
import { runCascadeOCR } from '@/services/cascade-ocr';

export type ScanStatus =
    | 'idle'
    | 'compressing'
    | 'editor_ready'  // NEW: Editor opens immediately with placeholder
    | 'analyzing'
    | 'complete'
    | 'queued'
    | 'error';

export interface ScanResult {
    status: ScanStatus;
    cloudResult: BottleMetadata | null;
    mergedResult: BottleMetadata | null;
    processedImage: ProcessedImage | null;
    error: string | null;
    isAnalyzing: boolean;  // NEW: Shows if AI is still working
    perf: {
        compression: number;
        cloudVision: number;
        total: number;
        model?: string;     // NEW: Which AI model was used
        provider?: string;  // NEW: Which provider (openrouter/gemini)
    } | null;
}

export interface UseScannerOptions {
    locale?: string;
    onComplete?: (result: BottleMetadata) => void;
}

/**
 * React hook for AI Vision scanning
 * 
 * Flow:
 * 1. Compress image (browser-side)
 * 2. IMMEDIATELY open editor with placeholder data
 * 3. Run AI Vision in background → update fields when ready
 * 
 * User doesn't wait - editor opens instantly!
 */
export function useScanner(options: UseScannerOptions = {}) {
    const { locale = 'en', onComplete } = options;

    const [result, setResult] = useState<ScanResult>({
        status: 'idle',
        cloudResult: null,
        mergedResult: null,
        processedImage: null,
        error: null,
        isAnalyzing: false,
        perf: null,
    });

    const dirtyFieldsRef = useRef<Set<string>>(new Set());

    const markFieldDirty = useCallback((field: string) => {
        dirtyFieldsRef.current.add(field);
    }, []);

    const clearDirtyFields = useCallback(() => {
        dirtyFieldsRef.current.clear();
    }, []);

    /**
     * Main scan handler - Opens editor immediately!
     */
    const handleScan = useCallback(async (file: File) => {
        const perfStart = performance.now();
        let perfCompression = 0;
        let perfCloudVision = 0;
        let modelUsed = '';
        let providerUsed = '';

        clearDirtyFields();
        setResult({
            status: 'compressing',
            cloudResult: null,
            mergedResult: null,
            processedImage: null,
            error: null,
            isAnalyzing: false,
            perf: null,
        });

        try {
            // Step 1: Compress image
            const compressStart = performance.now();
            const processedImage = await processImageForAI(file);
            perfCompression = performance.now() - compressStart;

            // Step 2: Generate placeholder data
            const placeholder = generateDummyMetadata(file);

            // Step 3: Check if offline → queue
            if (!navigator.onLine) {
                console.log('[useScanner] Offline → queuing for later');
                await db.pending_scans.add({
                    temp_id: `temp_${Date.now()}`,
                    imageBase64: processedImage.base64,
                    timestamp: Date.now(),
                    locale,
                    metadata: placeholder as any,
                });

                setResult({
                    status: 'queued',
                    cloudResult: null,
                    mergedResult: placeholder,
                    processedImage,
                    error: null,
                    isAnalyzing: false,
                    perf: {
                        compression: perfCompression,
                        cloudVision: 0,
                        total: performance.now() - perfStart,
                    },
                });
                return;
            }

            // Step 4: IMMEDIATELY open editor with placeholder!
            setResult({
                status: 'editor_ready',
                cloudResult: null,
                mergedResult: placeholder,
                processedImage,
                error: null,
                isAnalyzing: true,  // Show loading indicator
                perf: {
                    compression: perfCompression,
                    cloudVision: 0,
                    total: performance.now() - perfStart,
                },
            });

            // Step 4.5: Run Cascade OCR in parallel (for comparison/logging only)
            runCascadeOCR(processedImage.file).catch(err => {
                console.warn('[useScanner] Cascade OCR failed:', err);
            });

            // Step 5: Run AI in background (user is already in editor!)
            const cloudStart = performance.now();
            const cloudResponse = await analyzeBottleLabel(processedImage.base64);
            perfCloudVision = performance.now() - cloudStart;

            // Store provider/model info
            providerUsed = cloudResponse.provider || 'openrouter';
            modelUsed = 'gemma-3-27b-it';

            if (cloudResponse.success && cloudResponse.data) {
                const cloudResult = cloudResponse.data;
                onComplete?.(cloudResult);
                console.log(`[useScanner] ${providerUsed} complete:`, cloudResult);

                // Merge AI results with user edits (preserve dirty fields)
                setResult(prev => {
                    const merged = { ...cloudResult };
                    // Keep user-edited fields
                    for (const field of dirtyFieldsRef.current) {
                        if (prev.mergedResult && field in prev.mergedResult) {
                            (merged as any)[field] = (prev.mergedResult as any)[field];
                        }
                    }
                    return {
                        status: 'complete',
                        cloudResult,
                        mergedResult: merged,
                        processedImage,
                        error: null,
                        isAnalyzing: false,
                        perf: {
                            compression: perfCompression,
                            cloudVision: perfCloudVision,
                            total: performance.now() - perfStart,
                            model: modelUsed,
                            provider: providerUsed,
                        },
                    };
                });
            } else {
                // AI failed - keep placeholder, show error
                console.warn(`[useScanner] ${providerUsed} failed:`, cloudResponse.error);

                setResult(prev => ({
                    ...prev,
                    status: 'complete',
                    error: cloudResponse.error || null,
                    isAnalyzing: false,
                    perf: {
                        compression: perfCompression,
                        cloudVision: perfCloudVision,
                        total: performance.now() - perfStart,
                        model: modelUsed,
                        provider: providerUsed,
                    },
                }));
            }

        } catch (error: any) {
            console.error('[useScanner] Scan failed:', error);
            setResult(prev => ({
                ...prev,
                status: 'error',
                error: error.message || 'Scan failed',
                isAnalyzing: false,
                perf: {
                    compression: perfCompression,
                    cloudVision: perfCloudVision,
                    total: performance.now() - perfStart,
                },
            }));
        }
    }, [locale, clearDirtyFields, onComplete]);

    const reset = useCallback(() => {
        clearDirtyFields();
        setResult({
            status: 'idle',
            cloudResult: null,
            mergedResult: null,
            processedImage: null,
            error: null,
            isAnalyzing: false,
            perf: null,
        });
    }, [clearDirtyFields]);

    const updateMergedResult = useCallback((updates: Partial<BottleMetadata>) => {
        Object.keys(updates).forEach(key => {
            dirtyFieldsRef.current.add(key);
        });

        setResult(prev => ({
            ...prev,
            mergedResult: prev.mergedResult ? { ...prev.mergedResult, ...updates } : null,
        }));
    }, []);

    const cleanup = useCallback(() => { }, []);

    return {
        ...result,
        handleScan,
        reset,
        markFieldDirty,
        updateMergedResult,
        cleanup,
    };
}
