/**
 * @ai-summary Hook to orchestrate VIN OCR extraction and NHTSA decode
 * @ai-context Handles camera capture -> OCR extraction -> VIN decode flow
 */

import { useState, useCallback } from 'react';
import { apiClient } from '../../../core/api/client';
import { vehiclesApi } from '../api/vehicles.api';
import { DecodedVehicleData } from '../types/vehicles.types';

/** OCR extraction result for VIN */
export interface VinOcrResult {
  vin: string;
  confidence: number;
  rawText: string;
}

/** Combined OCR + decode result */
export interface VinCaptureResult {
  ocrResult: VinOcrResult;
  decodedVehicle: DecodedVehicleData | null;
  decodeError: string | null;
}

/** Hook state */
export interface UseVinOcrState {
  isCapturing: boolean;
  isProcessing: boolean;
  processingStep: 'idle' | 'extracting' | 'decoding';
  result: VinCaptureResult | null;
  error: string | null;
}

/** Hook return type */
export interface UseVinOcrReturn extends UseVinOcrState {
  startCapture: () => void;
  cancelCapture: () => void;
  processImage: (file: File, croppedFile?: File) => Promise<void>;
  acceptResult: () => VinCaptureResult | null;
  reset: () => void;
}

/**
 * Extract VIN from image using OCR service
 */
async function extractVinFromImage(file: File): Promise<VinOcrResult> {
  const formData = new FormData();
  formData.append('file', file);

  const response = await apiClient.post('/ocr/extract', formData, {
    headers: { 'Content-Type': 'multipart/form-data' },
    timeout: 30000, // 30 seconds for OCR processing
  });

  const data = response.data;

  if (!data.success) {
    throw new Error('OCR extraction failed');
  }

  // Extract VIN from the response
  const vinField = data.extractedFields?.vin;
  if (!vinField?.value) {
    throw new Error('No VIN found in image. Please ensure the VIN is clearly visible.');
  }

  return {
    vin: vinField.value.toUpperCase().replace(/[^A-HJ-NPR-Z0-9]/g, ''),
    confidence: vinField.confidence,
    rawText: data.rawText,
  };
}

/**
 * Hook to orchestrate VIN photo capture, OCR, and decode
 */
export function useVinOcr(): UseVinOcrReturn {
  const [isCapturing, setIsCapturing] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [processingStep, setProcessingStep] = useState<'idle' | 'extracting' | 'decoding'>('idle');
  const [result, setResult] = useState<VinCaptureResult | null>(null);
  const [error, setError] = useState<string | null>(null);

  const startCapture = useCallback(() => {
    setIsCapturing(true);
    setError(null);
    setResult(null);
  }, []);

  const cancelCapture = useCallback(() => {
    setIsCapturing(false);
    setError(null);
  }, []);

  const processImage = useCallback(async (file: File, croppedFile?: File) => {
    setIsCapturing(false);
    setIsProcessing(true);
    setError(null);
    setResult(null);

    try {
      // Step 1: Extract VIN from image
      setProcessingStep('extracting');
      const imageToProcess = croppedFile || file;
      const ocrResult = await extractVinFromImage(imageToProcess);

      // Validate VIN format
      if (ocrResult.vin.length !== 17) {
        throw new Error(
          `Extracted VIN "${ocrResult.vin}" is ${ocrResult.vin.length} characters. VIN must be exactly 17 characters.`
        );
      }

      // Step 2: Decode VIN using NHTSA
      setProcessingStep('decoding');
      let decodedVehicle: DecodedVehicleData | null = null;
      let decodeError: string | null = null;

      try {
        decodedVehicle = await vehiclesApi.decodeVin(ocrResult.vin);
      } catch (err: any) {
        // VIN decode failure is not fatal - we still have the VIN
        if (err.response?.data?.error === 'TIER_REQUIRED') {
          decodeError = 'VIN decode requires Pro or Enterprise subscription';
        } else if (err.response?.data?.error === 'INVALID_VIN') {
          decodeError = 'VIN format is not recognized by NHTSA';
        } else {
          decodeError = 'Unable to decode vehicle information';
        }
        console.warn('VIN decode failed:', err);
      }

      setResult({
        ocrResult,
        decodedVehicle,
        decodeError,
      });
    } catch (err: any) {
      console.error('VIN OCR processing failed:', err);
      const message = err.response?.data?.message || err.message || 'Failed to process image';
      setError(message);
    } finally {
      setIsProcessing(false);
      setProcessingStep('idle');
    }
  }, []);

  const acceptResult = useCallback(() => {
    const currentResult = result;
    setResult(null);
    return currentResult;
  }, [result]);

  const reset = useCallback(() => {
    setIsCapturing(false);
    setIsProcessing(false);
    setProcessingStep('idle');
    setResult(null);
    setError(null);
  }, []);

  return {
    isCapturing,
    isProcessing,
    processingStep,
    result,
    error,
    startCapture,
    cancelCapture,
    processImage,
    acceptResult,
    reset,
  };
}
