/**
 * ValidationContainer Component
 *
 * Main orchestrator component for the validation step.
 * Coordinates sub-components once initialization is complete.
 * Note: Initialization effects are in index.tsx so they run before this mounts.
 */

import { useCallback, useMemo, useRef, useState, useEffect } from 'react';
import { useValidationStore } from '../store/validationStore';
import {
  useTotalErrorCount,
  useRowsWithErrorsCount,
  useIsTemplateFormOpen,
  useTemplateFormData,
} from '../store/selectors';
import { ValidationTable } from './ValidationTable';
import { ValidationToolbar } from './ValidationToolbar';
import { ValidationFooter } from './ValidationFooter';
import { FloatingSelectionBar } from './FloatingSelectionBar';
import { useAiValidationFlow } from '../hooks/useAiValidation';
import { useFieldOptions } from '../hooks/useFieldOptions';
import { useTemplateManagement } from '../hooks/useTemplateManagement';
import { useCopyDownValidation } from '../hooks/useCopyDownValidation';
import { useSanityCheck } from '../hooks/useSanityCheck';
import { AiValidationProgressDialog } from '../dialogs/AiValidationProgress';
import { AiValidationResultsDialog } from '../dialogs/AiValidationResults';
import { AiDebugDialog } from '../dialogs/AiDebugDialog';
import { SanityCheckDialog } from '../dialogs/SanityCheckDialog';
import { TemplateForm } from '@/components/templates/TemplateForm';
import { AiSuggestionsProvider } from '../contexts/AiSuggestionsContext';
import { useImportAutosave } from '@/hooks/useImportAutosave';
import { useImportSession } from '@/contexts/ImportSessionContext';
import type { CleanRowData, RowData } from '../store/types';
import type { ProductForSanityCheck } from '../hooks/useSanityCheck';
import type { ImportSessionData, SerializedValidationState } from '@/types/importSession';

interface ValidationContainerProps {
  onBack?: () => void;
  onNext?: (data: CleanRowData[]) => void;
  isFromScratch?: boolean;
}

export const ValidationContainer = ({
  onBack,
  onNext,
  isFromScratch: _isFromScratch,
}: ValidationContainerProps) => {
  // PERFORMANCE: Only subscribe to row COUNT, not the full rows array
  // Subscribing to rows causes re-render on EVERY cell change!
  const rowCount = useValidationStore((state) => state.rows.length);
  const totalErrorCount = useTotalErrorCount();
  const rowsWithErrorsCount = useRowsWithErrorsCount();

  // Template form dialog state
  const isTemplateFormOpen = useIsTemplateFormOpen();
  const templateFormData = useTemplateFormData();

  // Store actions
  const getCleanedData = useValidationStore((state) => state.getCleanedData);
  const closeTemplateForm = useValidationStore((state) => state.closeTemplateForm);

  // Hooks
  const aiValidation = useAiValidationFlow();
  const { data: fieldOptionsData } = useFieldOptions();
  const { loadTemplates } = useTemplateManagement();
  const sanityCheck = useSanityCheck();

  // Sanity check dialog state
  const [sanityCheckDialogOpen, setSanityCheckDialogOpen] = useState(false);
  // Debug: skip sanity check toggle (admin:debug only)
  const [skipSanityCheck, setSkipSanityCheck] = useState(false);

  // Handle UPC validation after copy-down operations on supplier/upc fields
  useCopyDownValidation();

  // Import session context for global selections
  const { getGlobalSelections } = useImportSession();

  // Import session autosave
  const { markDirty } = useImportAutosave({
    enabled: true,
    step: 'validation',
    getSessionData: useCallback((): ImportSessionData => {
      const state = useValidationStore.getState();

      // Serialize Maps to plain objects for JSON storage
      const serializedValidationState: SerializedValidationState = {
        errors: Object.fromEntries(
          Array.from(state.errors.entries()).map(([k, v]) => [k, v])
        ),
        upcStatus: Object.fromEntries(
          Array.from(state.upcStatus.entries()).map(([k, v]) => [k, v])
        ),
        generatedItemNumbers: Object.fromEntries(
          Array.from(state.generatedItemNumbers.entries()).map(([k, v]) => [k, v])
        ),
      };

      return {
        current_step: 'validation',
        data: state.rows,
        global_selections: getGlobalSelections(),
        validation_state: serializedValidationState,
      };
    }, [getGlobalSelections]),
  });

  // Subscribe to store changes to trigger autosave
  useEffect(() => {
    // Subscribe to row changes to mark session as dirty
    const unsubscribe = useValidationStore.subscribe(
      (state) => state.rows,
      () => {
        markDirty();
      }
    );
    return () => unsubscribe();
  }, [markDirty]);

  // Get initial products for AI suggestions (read once via ref to avoid re-fetching)
  const initialProductsRef = useRef<RowData[] | null>(null);
  if (initialProductsRef.current === null) {
    initialProductsRef.current = useValidationStore.getState().rows;
  }

  // Create stable lookup functions for company/line names
  const getCompanyName = useCallback((id: string): string | undefined => {
    const companies = fieldOptionsData?.companies || [];
    const company = companies.find(c => c.value === id);
    return company?.label;
  }, [fieldOptionsData?.companies]);

  const getLineName = useCallback((id: string): string | undefined => {
    // Lines are fetched dynamically per company, check the cache
    const cache = useValidationStore.getState().productLinesCache;
    for (const lines of cache.values()) {
      const line = lines.find(l => l.value === id);
      if (line) return line.label;
    }
    return undefined;
  }, []);

  // Convert field options to TemplateForm format
  const templateFormFieldOptions = useMemo(() => {
    if (!fieldOptionsData) return null;
    return {
      companies: fieldOptionsData.companies || [],
      artists: fieldOptionsData.artists || [],
      sizes: fieldOptionsData.sizes || [],  // API returns 'sizes'
      themes: fieldOptionsData.themes || [],
      categories: fieldOptionsData.categories || [],
      colors: fieldOptionsData.colors || [],
      suppliers: fieldOptionsData.suppliers || [],
      taxCategories: fieldOptionsData.taxCategories || [],
      shippingRestrictions: fieldOptionsData.shippingRestrictions || [],  // API returns 'shippingRestrictions'
    };
  }, [fieldOptionsData]);

  // Handle template form success - refresh templates
  const handleTemplateFormSuccess = useCallback(() => {
    loadTemplates();
  }, [loadTemplates]);

  // Handle proceeding to next step
  const handleNext = useCallback(() => {
    if (onNext) {
      const cleanedData = getCleanedData();
      onNext(cleanedData);
    }
  }, [onNext, getCleanedData]);

  // Handle going back
  const handleBack = useCallback(() => {
    if (onBack) {
      onBack();
    }
  }, [onBack]);

  // Build products array for sanity check
  const buildProductsForSanityCheck = useCallback((): ProductForSanityCheck[] => {
    const rows = useValidationStore.getState().rows;
    const fields = useValidationStore.getState().fields;

    // Build lookup for field options (for display names)
    const getFieldLabel = (fieldKey: string, value: unknown): string | undefined => {
      const field = fields.find(f => f.key === fieldKey);
      if (field && field.fieldType.type === 'select' && 'options' in field.fieldType) {
        const option = field.fieldType.options?.find(o => o.value === String(value));
        return option?.label;
      }
      return undefined;
    };

    // Convert rows to sanity check format
    return rows.map((row) => {
      const product: ProductForSanityCheck = {
        name: row.name as string | undefined,
        supplier: row.supplier as string | undefined,
        supplier_name: getFieldLabel('supplier', row.supplier),
        company: row.company as string | undefined,
        company_name: getFieldLabel('company', row.company),
        supplier_no: row.supplier_no as string | undefined,
        msrp: row.msrp as string | number | undefined,
        cost_each: row.cost_each as string | number | undefined,
        qty_per_unit: row.qty_per_unit as string | number | undefined,
        case_qty: row.case_qty as string | number | undefined,
        tax_cat: row.tax_cat as string | number | undefined,
        tax_cat_name: getFieldLabel('tax_cat', row.tax_cat),
        size_cat: row.size_cat as string | number | undefined,
        size_cat_name: getFieldLabel('size_cat', row.size_cat),
        themes: row.themes as string | undefined,
        categories: row.categories as string | undefined,
        weight: row.weight as string | number | undefined,
        length: row.length as string | number | undefined,
        width: row.width as string | number | undefined,
        height: row.height as string | number | undefined,
      };

      // Add AI supplemental context if present (from MatchColumnsStep "AI context only" columns)
      if (row.__aiSupplemental && typeof row.__aiSupplemental === 'object') {
        product.additional_context = row.__aiSupplemental;
      }

      return product;
    });
  }, []);

  // Handle viewing cached sanity check results
  const handleViewResults = useCallback(() => {
    setSanityCheckDialogOpen(true);
  }, []);

  // Handle running a fresh sanity check
  const handleRunCheck = useCallback(() => {
    const products = buildProductsForSanityCheck();
    setSanityCheckDialogOpen(true);
    sanityCheck.runCheck(products);
  }, [sanityCheck, buildProductsForSanityCheck]);

  // Handle proceeding directly to next step (skipping sanity check)
  const handleProceedDirect = useCallback(() => {
    handleNext();
  }, [handleNext]);

  // Force a new sanity check (refresh button in dialog)
  const handleRefreshSanityCheck = useCallback(() => {
    const products = buildProductsForSanityCheck();
    sanityCheck.runCheck(products);
  }, [sanityCheck, buildProductsForSanityCheck]);

  // Handle proceeding after sanity check
  const handleSanityCheckProceed = useCallback(() => {
    setSanityCheckDialogOpen(false);
    sanityCheck.clearResults();
    handleNext();
  }, [handleNext, sanityCheck]);

  // Handle going back from sanity check dialog (keeps results cached)
  const handleSanityCheckGoBack = useCallback(() => {
    setSanityCheckDialogOpen(false);
    // Don't clear results - keep them cached for next time
  }, []);

  // Handle scrolling to a specific product from sanity check issue
  const handleScrollToProduct = useCallback((productIndex: number) => {
    // Find the row element and scroll to it
    const rowElement = document.querySelector(`[data-row-index="${productIndex}"]`);
    if (rowElement) {
      rowElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
      // Briefly highlight the row
      rowElement.classList.add('ring-2', 'ring-purple-500');
      setTimeout(() => {
        rowElement.classList.remove('ring-2', 'ring-purple-500');
      }, 2000);
    }
  }, []);

  // Build product names lookup for sanity check dialog
  // Rebuild fresh whenever dialog opens to ensure names are current after AI suggestions
  const buildProductNames = useCallback(() => {
    const rows = useValidationStore.getState().rows;
    const names: Record<number, string> = {};
    rows.forEach((row, index) => {
      names[index] = (row.name as string) || `Product ${index + 1}`;
    });
    return names;
  }, []);

  const productNames = useMemo(() => buildProductNames(), [sanityCheckDialogOpen, buildProductNames]);

  return (
    <AiSuggestionsProvider
      getCompanyName={getCompanyName}
      getLineName={getLineName}
      initialProducts={initialProductsRef.current || undefined}
      autoInitialize={!!fieldOptionsData}
    >
      <div className="flex flex-col h-[calc(100vh-9.5rem)] overflow-hidden">
        {/* Toolbar */}
        <ValidationToolbar
          rowCount={rowCount}
          errorCount={totalErrorCount}
          rowsWithErrors={rowsWithErrorsCount}
        />

        {/* Main table area */}
        <div className="flex-1 overflow-hidden">
          <ValidationTable />
        </div>

        {/* Footer with navigation */}
        <ValidationFooter
          onBack={handleBack}
          onProceedDirect={handleProceedDirect}
          onViewResults={handleViewResults}
          onRunCheck={handleRunCheck}
          canGoBack={!!onBack}
          canProceed={totalErrorCount === 0}
          errorCount={totalErrorCount}
          rowCount={rowCount}
          isSanityChecking={sanityCheck.isChecking}
          hasRunSanityCheck={sanityCheck.hasRun}
          skipSanityCheck={skipSanityCheck}
          onSkipSanityCheckChange={setSkipSanityCheck}
        />

        {/* Floating selection bar - appears when rows selected */}
        <FloatingSelectionBar />

        {/* AI Validation dialogs */}
        {aiValidation.isValidating && aiValidation.progress && (
          <AiValidationProgressDialog
            progress={aiValidation.progress}
            onCancel={aiValidation.cancel}
          />
        )}

        {aiValidation.results && !aiValidation.isValidating && (
          <AiValidationResultsDialog
            results={aiValidation.results}
            revertedChanges={aiValidation.revertedChanges}
            onRevert={aiValidation.revertChange}
            onAccept={aiValidation.acceptChange}
            onDismiss={aiValidation.dismissResults}
          />
        )}

        {/* AI Debug Dialog - for viewing prompt */}
        <AiDebugDialog
          open={aiValidation.showDebugDialog}
          onClose={aiValidation.closePromptPreview}
          debugData={aiValidation.debugPrompt}
        />

        {/* Sanity Check Dialog - shows cached results or runs new check */}
        <SanityCheckDialog
          open={sanityCheckDialogOpen}
          onOpenChange={setSanityCheckDialogOpen}
          isChecking={sanityCheck.isChecking}
          error={sanityCheck.error}
          result={sanityCheck.result}
          onProceed={handleSanityCheckProceed}
          onGoBack={handleSanityCheckGoBack}
          onRefresh={handleRefreshSanityCheck}
          onScrollToProduct={handleScrollToProduct}
          productNames={productNames}
          validationErrorCount={totalErrorCount}
        />

        {/* Template form dialog - for saving row as template */}
        <TemplateForm
          isOpen={isTemplateFormOpen}
          onClose={closeTemplateForm}
          onSuccess={handleTemplateFormSuccess}
          initialData={templateFormData as Parameters<typeof TemplateForm>[0]['initialData']}
          mode="create"
          fieldOptions={templateFormFieldOptions}
        />
      </div>
    </AiSuggestionsProvider>
  );
};
