/**
 * useSanityCheck Hook
 *
 * Runs batch sanity check on products before proceeding to next step.
 * Checks for consistency and appropriateness across products.
 *
 * Results are cached locally - clicking "Sanity Check" again shows cached
 * results without making a new API call. Use "Refresh" to force a new check.
 */

import { useState, useCallback, useRef } from 'react';
import { apiFetch } from '@/utils/api';

// Types for sanity check results
export interface SanityIssue {
  productIndex: number;
  field: string;
  issue: string;
  suggestion?: string;
}

export interface SanityCheckResult {
  issues: SanityIssue[];
  summary: string;
  latencyMs?: number;
  totalProducts?: number;
  issueCount?: number;
  /** Timestamp when check was run */
  checkedAt?: number;
}

export interface SanityCheckState {
  isChecking: boolean;
  error: string | null;
  result: SanityCheckResult | null;
  hasRun: boolean;
}

// Product data for sanity check (simplified structure)
export interface ProductForSanityCheck {
  name?: string;
  supplier?: string;
  supplier_name?: string;
  company?: string;
  company_name?: string;
  supplier_no?: string;
  msrp?: string | number;
  cost_each?: string | number;
  qty_per_unit?: string | number;
  case_qty?: string | number;
  tax_cat?: string | number;
  tax_cat_name?: string;
  size_cat?: string | number;
  size_cat_name?: string;
  themes?: string;
  theme_names?: string;
  categories?: string;
  category_names?: string;
  weight?: string | number;
  length?: string | number;
  width?: string | number;
  height?: string | number;
  additional_context?: Record<string, string>;  // AI supplemental columns from MatchColumnsStep
}

/**
 * Hook for batch sanity check of products
 */
export function useSanityCheck() {
  const [state, setState] = useState<SanityCheckState>({
    isChecking: false,
    error: null,
    result: null,
    hasRun: false
  });

  // Track pending request for cancellation
  const abortControllerRef = useRef<AbortController | null>(null);

  /**
   * Run sanity check on products
   */
  const runCheck = useCallback(async (products: ProductForSanityCheck[]): Promise<SanityCheckResult | null> => {
    if (!products || products.length === 0) {
      return {
        issues: [],
        summary: 'No products to check'
      };
    }

    // Cancel any pending request
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }

    const controller = new AbortController();
    abortControllerRef.current = controller;

    setState(prev => ({
      ...prev,
      isChecking: true,
      error: null,
      hasRun: true
    }));

    try {
      const response = await apiFetch('/api/ai/validate/sanity-check', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ products }),
        signal: controller.signal
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(errorData.error || `Sanity check failed: ${response.status}`);
      }

      const data = await response.json();

      const result: SanityCheckResult = {
        issues: data.issues || [],
        summary: data.summary || 'Check complete',
        latencyMs: data.latencyMs,
        totalProducts: products.length,
        issueCount: data.issues?.length || 0,
        checkedAt: Date.now()
      };

      setState(prev => ({
        ...prev,
        isChecking: false,
        result,
        error: null
      }));

      return result;
    } catch (error) {
      if ((error as Error).name === 'AbortError') {
        // Request was cancelled
        return null;
      }

      const message = (error as Error).message || 'Sanity check failed';
      setState(prev => ({
        ...prev,
        isChecking: false,
        error: message
      }));

      return null;
    }
  }, []);

  /**
   * Cancel the current check
   */
  const cancelCheck = useCallback(() => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }

    setState(prev => ({
      ...prev,
      isChecking: false
    }));
  }, []);

  /**
   * Clear results and reset state
   */
  const clearResults = useCallback(() => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }

    setState({
      isChecking: false,
      error: null,
      result: null,
      hasRun: false
    });
  }, []);

  /**
   * Get issues for a specific product index
   */
  const getIssuesForProduct = useCallback((productIndex: number): SanityIssue[] => {
    if (!state.result?.issues) return [];
    return state.result.issues.filter(issue => issue.productIndex === productIndex);
  }, [state.result]);

  /**
   * Get issues grouped by field
   */
  const getIssuesByField = useCallback((): Record<string, SanityIssue[]> => {
    if (!state.result?.issues) return {};

    return state.result.issues.reduce((acc, issue) => {
      const field = issue.field;
      if (!acc[field]) {
        acc[field] = [];
      }
      acc[field].push(issue);
      return acc;
    }, {} as Record<string, SanityIssue[]>);
  }, [state.result]);

  /**
   * Check if there are any issues
   */
  const hasIssues = state.result?.issues && state.result.issues.length > 0;

  /**
   * Check if the sanity check passed (ran with no issues)
   */
  const passed = state.hasRun && !state.isChecking && !state.error && !hasIssues;

  /**
   * Check if we have cached results that can be displayed
   */
  const hasCachedResults = state.hasRun && state.result !== null && !state.isChecking;

  return {
    // State
    isChecking: state.isChecking,
    error: state.error,
    result: state.result,
    hasRun: state.hasRun,
    hasIssues,
    passed,
    hasCachedResults,

    // Computed
    issues: state.result?.issues || [],
    summary: state.result?.summary || null,
    issueCount: state.result?.issueCount || 0,
    checkedAt: state.result?.checkedAt || null,

    // Actions
    runCheck,
    cancelCheck,
    clearResults,

    // Helpers
    getIssuesForProduct,
    getIssuesByField
  };
}
