/**
 * useAiValidation - Main AI Validation Orchestrator
 *
 * Coordinates AI validation flow using sub-hooks for API, progress, and transformation.
 * This is the public interface for AI validation functionality.
 *
 * PERFORMANCE NOTE: This hook must NOT subscribe to the rows array!
 * Subscribing to rows causes re-render on EVERY cell change.
 * Instead, use getState() to read rows at action time.
 */

import { useCallback, useState } from 'react';
import { useValidationStore } from '../../store/validationStore';
import { useAiValidation, useIsAiValidating } from '../../store/selectors';
import { useAiProgress } from './useAiProgress';
import { useAiTransform } from './useAiTransform';
import { useValidationActions } from '../useValidationActions';
import {
  runAiValidation,
  getAiDebugPrompt,
  getAiTimeEstimate,
  prepareProductsForAi,
  extractAiSupplementalColumns,
  type AiDebugPromptResponse,
} from './useAiApi';
import { toast } from 'sonner';
import type { AiValidationChange } from '../../store/types';

export { useAiProgress } from './useAiProgress';
export { useAiTransform } from './useAiTransform';
export * from './useAiApi';

/**
 * Main hook for AI validation operations
 */
export const useAiValidationFlow = () => {
  // PERFORMANCE: Only subscribe to AI-specific state, NOT rows or fields
  // Rows and fields are read via getState() at action time
  const aiValidation = useAiValidation();
  const isValidating = useIsAiValidating();

  // Sub-hooks
  const { startProgress, updateProgress, completeProgress, setError, clearProgress } = useAiProgress();
  const { applyAiChanges, buildResults, saveResults } = useAiTransform();
  const { validateAllRows } = useValidationActions();

  // Store actions
  const revertAiChange = useValidationStore((state) => state.revertAiChange);
  const acceptAiChange = useValidationStore((state) => state.acceptAiChange);
  const clearAiValidation = useValidationStore((state) => state.clearAiValidation);

  // Local state for debug prompt preview
  const [debugPrompt, setDebugPrompt] = useState<AiDebugPromptResponse | null>(null);
  const [showDebugDialog, setShowDebugDialog] = useState(false);

  /**
   * Run AI validation on all rows
   * PERFORMANCE: Uses getState() to read rows/fields at action time
   */
  const validate = useCallback(async () => {
    if (isValidating) {
      toast.error('AI validation is already running');
      return;
    }

    // Get rows and fields at action time
    const { rows, fields } = useValidationStore.getState();

    if (rows.length === 0) {
      toast.error('No products to validate');
      return;
    }

    const startTime = Date.now();

    try {
      // Prepare data for API first (needed for time estimate)
      const products = prepareProductsForAi(rows, fields);
      const aiSupplementalColumns = extractAiSupplementalColumns(rows);

      // Fetch time estimate from server before starting
      // This provides accurate "time remaining" based on historical data
      const { estimatedSeconds, promptLength } = await getAiTimeEstimate(
        products,
        aiSupplementalColumns
      );

      console.log('AI validation time estimate:', { estimatedSeconds, promptLength });

      // Start progress tracking with server estimate
      startProgress(rows.length, estimatedSeconds ?? undefined, promptLength ?? undefined);

      // Update status
      updateProgress(0, rows.length, 'preparing', 'Preparing data...');

      // Call AI validation API
      updateProgress(0, rows.length, 'validating', 'Running AI validation...');
      const response = await runAiValidation({
        products,
        aiSupplementalColumns,
      });

      if (!response.success) {
        throw new Error(response.error || 'AI validation failed');
      }

      // Process results
      updateProgress(rows.length, rows.length, 'processing', 'Processing results...');

      // Handle both response formats:
      // - Nested: response.results.products, response.results.changes
      // - Top-level: response.correctedData, response.changeDetails
      const aiProducts = response.results?.products || response.correctedData || [];
      const rawChanges = response.results?.changes || response.changeDetails || [];

      // Normalize changes to AiValidationChange format
      const changes: AiValidationChange[] = rawChanges.map((change: any) => ({
        productIndex: change.productIndex,
        fieldKey: change.fieldKey,
        originalValue: change.originalValue,
        correctedValue: change.correctedValue,
        confidence: change.confidence,
      }));

      // Apply changes to rows
      if (changes.length > 0) {
        applyAiChanges(aiProducts, changes);
      }

      // Revalidate all rows after AI changes to update error state
      // This ensures validation errors are refreshed based on the new data
      updateProgress(rows.length, rows.length, 'processing', 'Revalidating fields...');
      await validateAllRows();

      // Build and save results with all metadata
      const processingTime = Date.now() - startTime;

      // Extract token usage from response - could be in results or top-level or performanceMetrics
      const tokenUsageSource =
        response.results?.tokenUsage ||
        response.tokenUsage ||
        response.performanceMetrics?.tokenUsage;

      const results = buildResults(changes, tokenUsageSource, processingTime, {
        model: response.model || response.performanceMetrics?.model,
        reasoningEffort: response.reasoningEffort || response.performanceMetrics?.reasoningEffort,
        summary: response.summary,
        warnings: response.warnings,
        changesSummary: response.changes, // Top-level changes array is human-readable summaries
      });
      saveResults(results);

      // Complete progress
      completeProgress();

      // Show summary toast
      if (changes.length > 0) {
        toast.success(`AI made ${changes.length} corrections across ${results.productsWithChanges} products`);
      } else {
        toast.info('AI validation complete - no corrections needed');
      }
    } catch (error) {
      console.error('AI validation error:', error);
      const message = error instanceof Error ? error.message : 'Unknown error';
      setError(message);
      toast.error(`AI validation failed: ${message}`);
    }
  }, [
    isValidating,
    startProgress,
    updateProgress,
    completeProgress,
    setError,
    applyAiChanges,
    buildResults,
    saveResults,
    validateAllRows,
  ]);

  /**
   * Revert a specific AI change
   */
  const revertChange = useCallback(
    (productIndex: number, fieldKey: string) => {
      revertAiChange(productIndex, fieldKey);
      toast.success('Change reverted');
    },
    [revertAiChange]
  );

  /**
   * Accept (re-apply) a previously reverted AI change
   */
  const acceptChange = useCallback(
    (productIndex: number, fieldKey: string) => {
      acceptAiChange(productIndex, fieldKey);
      toast.success('Change accepted');
    },
    [acceptAiChange]
  );

  /**
   * Dismiss AI validation results
   */
  const dismissResults = useCallback(() => {
    clearAiValidation();
  }, [clearAiValidation]);

  /**
   * Show debug prompt dialog
   * PERFORMANCE: Uses getState() to read rows/fields at action time
   */
  const showPromptPreview = useCallback(async () => {
    const { rows, fields } = useValidationStore.getState();
    const products = prepareProductsForAi(rows, fields);
    const aiSupplementalColumns = extractAiSupplementalColumns(rows);

    // Use previewOnly to only send first 5 products for the preview dialog
    const prompt = await getAiDebugPrompt(products, aiSupplementalColumns, { previewOnly: true });
    if (prompt) {
      setDebugPrompt(prompt);
      setShowDebugDialog(true);
    } else {
      toast.error('Failed to load prompt preview');
    }
  }, []);

  /**
   * Close debug prompt dialog
   */
  const closePromptPreview = useCallback(() => {
    setShowDebugDialog(false);
    setDebugPrompt(null);
  }, []);

  /**
   * Cancel ongoing validation
   */
  const cancel = useCallback(() => {
    clearProgress();
    toast.info('AI validation cancelled');
  }, [clearProgress]);

  return {
    // State
    isValidating,
    progress: aiValidation.progress,
    results: aiValidation.results,
    revertedChanges: aiValidation.revertedChanges,

    // Debug dialog
    debugPrompt,
    showDebugDialog,

    // Actions
    validate,
    revertChange,
    acceptChange,
    dismissResults,
    cancel,
    showPromptPreview,
    closePromptPreview,
  };
};
