/**
 * ValidationStep Store Types
 *
 * Comprehensive type definitions for the Zustand-based validation store.
 * These types define the shape of all state and actions in the validation flow.
 */

import type { Field, SelectOption, ErrorLevel } from '../../../types';
import type { MappingSignature } from '../utils/mappingSignature';

// =============================================================================
// Core Data Types
// =============================================================================

/**
 * Extended row data with metadata fields used during validation.
 * The __ prefixed fields are internal and stripped before output.
 */
export interface RowData {
  __index: string;           // Unique row identifier (UUID)
  __template?: string;       // Applied template ID
  __original?: Record<string, unknown>;  // Original values before AI changes
  __corrected?: Record<string, unknown>; // AI-corrected values
  __changes?: Record<string, boolean>;   // Fields changed by AI
  __aiSupplemental?: Record<string, string>;  // AI supplemental columns from MatchColumnsStep (header -> value)
  __sourceRow?: number;      // Stable positional id from the raw spreadsheet (for back-nav merge)

  // Standard fields (from config.ts)
  supplier?: string;
  company?: string;
  line?: string;
  subline?: string;
  upc?: string;
  item_number?: string;
  supplier_no?: string;
  notions_no?: string;
  name?: string;
  msrp?: string;
  qty_per_unit?: string;
  cost_each?: string;
  case_qty?: string;
  tax_cat?: string;
  artist?: string;
  eta?: string;
  weight?: string;
  length?: string;
  width?: string;
  height?: string;
  ship_restrictions?: string;
  coo?: string;
  hts_code?: string;
  size_cat?: string;
  description?: string;
  priv_notes?: string;
  categories?: string | string[];
  themes?: string | string[];
  colors?: string | string[];
  product_images?: string;

  // Allow dynamic field access
  [key: string]: unknown;
}

/**
 * Clean row data without metadata (output format for ImageUploadStep)
 */
export type CleanRowData = Omit<RowData, '__index' | '__template' | '__original' | '__corrected' | '__changes' | '__aiSupplemental'>;

// =============================================================================
// Validation Types
// =============================================================================

export enum ErrorSource {
  Row = 'row',
  Table = 'table',
  Api = 'api',
  Upc = 'upc'
}

export enum ErrorType {
  Required = 'required',
  Regex = 'regex',
  Unique = 'unique',
  Custom = 'custom',
  Api = 'api'
}

export interface ValidationError {
  message: string;
  level: ErrorLevel;
  source: ErrorSource;
  type: ErrorType;
}

/**
 * Validation errors organized by row and field
 * Structure: Map<rowIndex, Record<fieldKey, ValidationError[]>>
 */
export type ValidationErrors = Map<number, Record<string, ValidationError[]>>;

export type RowValidationStatus = 'pending' | 'validating' | 'validated' | 'error';

// =============================================================================
// UPC Validation Types
// =============================================================================

export type UpcValidationStatus = 'idle' | 'validating' | 'done' | 'error';

export interface UpcValidationResult {
  success: boolean;
  itemNumber?: string;
  error?: string;
  code?: 'conflict' | 'http_error' | 'invalid_response' | 'network_error';
}

// =============================================================================
// Template Types
// =============================================================================

export interface Template {
  id: number;
  company: string;
  product_type: string;
  [key: string]: string | number | boolean | undefined;
}

export interface TemplateState {
  selectedTemplateId: string | null;
  showSaveDialog: boolean;
  newTemplateName: string;
  newTemplateType: string;
}

// =============================================================================
// Filter Types
// =============================================================================

export interface FilterState {
  searchText: string;
  showErrorsOnly: boolean;
  filterField: string | null;
  filterValue: string | null;
}

// =============================================================================
// Copy-Down Mode Types
// =============================================================================

export interface CopyDownState {
  isActive: boolean;
  sourceRowIndex: number | null;
  sourceFieldKey: string | null;
  targetRowIndex: number | null;  // Hover preview - which row the user is hovering on
}

/**
 * Tracks rows that need UPC validation after copy-down completes.
 * This allows reusing the existing validateUpc logic instead of duplicating it.
 */
export interface PendingCopyDownValidation {
  fieldKey: string;
  affectedRows: number[];
}

/**
 * Tracks rows that need inline AI validation after line copy-down.
 * When line is copied to rows that already have company + name/description,
 * those rows now have sufficient context for validation.
 */
export interface PendingInlineAiValidation {
  /** Row indices that need name validation */
  nameRows: number[];
  /** Row indices that need description validation */
  descriptionRows: number[];
}

// =============================================================================
// Dialog State Types
// =============================================================================

export interface DialogState {
  templateFormOpen: boolean;
  templateFormData: Record<string, unknown> | null;
  createCategoryOpen: boolean;
}

// =============================================================================
// AI Validation Types
// =============================================================================

export interface AiValidationProgress {
  current: number;
  total: number;
  status: 'preparing' | 'validating' | 'processing' | 'complete' | 'error';
  message?: string;
  startTime: number;
  estimatedTimeRemaining?: number;
  estimatedTotalSeconds?: number;  // Server-provided estimate
  promptLength?: number;           // For cost calculation
  elapsedSeconds?: number;         // Tracked by timer
  progressPercent?: number;        // Calculated progress
}

export interface AiValidationChange {
  productIndex: number;
  fieldKey: string;
  originalValue: unknown;
  correctedValue: unknown;
  confidence?: number;
}

/**
 * Token usage with all available metrics
 */
export interface AiTokenUsage {
  prompt: number | null;
  completion: number | null;
  total: number | null;
  reasoning?: number | null;
  cachedPrompt?: number | null;
}

export interface AiValidationResults {
  totalProducts: number;
  productsWithChanges: number;
  changes: AiValidationChange[];
  tokenUsage?: AiTokenUsage;
  processingTime: number;
  // Additional metadata from AI response
  model?: string;
  reasoningEffort?: string;
  summary?: string;
  warnings?: string[];
  changesSummary?: string[];  // High-level change descriptions
}

export interface AiValidationState {
  isRunning: boolean;
  progress: AiValidationProgress | null;
  results: AiValidationResults | null;
  revertedChanges: Set<string>;  // Format: "productIndex:fieldKey"
}

// =============================================================================
// AI Suggestions Types (Embedding-based)
// =============================================================================

export interface TaxonomySuggestion {
  id: number;
  name: string;
  fullPath?: string;
  similarity: number;
}

export interface ProductSuggestions {
  categories: TaxonomySuggestion[];
  themes: TaxonomySuggestion[];
  colors: TaxonomySuggestion[];
  latencyMs?: number;
}

export interface AiSuggestionsState {
  initialized: boolean;
  initializing: boolean;
  /** Map of product __index to their embedding */
  embeddings: Map<string, number[]>;
  /** Map of product __index to their suggestions */
  suggestions: Map<string, ProductSuggestions>;
  /** Products currently being processed */
  processing: Set<string>;
  /** Last error if any */
  error: string | null;
}

// =============================================================================
// Inline AI Validation Types (Groq-powered)
// =============================================================================

/**
 * Result from inline AI validation (name or description)
 */
export interface InlineAiValidationResult {
  isValid: boolean;
  suggestion?: string;
  issues: string[];
  latencyMs?: number;
}

/**
 * Per-product inline AI suggestions (keyed by product __index)
 */
export interface InlineAiSuggestion {
  name?: InlineAiValidationResult;
  description?: InlineAiValidationResult;
  /** Whether the suggestion has been dismissed by the user */
  dismissed?: {
    name?: boolean;
    description?: boolean;
  };
}

/**
 * State for inline AI validation
 */
export interface InlineAiState {
  /** Map of product __index to their inline suggestions */
  suggestions: Map<string, InlineAiSuggestion>;
  /** Products currently being validated (format: "productIndex-field") */
  validating: Set<string>;
  /**
   * Fields that have been auto-validated on load (format: "productIndex-field")
   * This prevents re-validation when blur fires for a field that was just auto-validated,
   * and prevents auto-validation from firing for fields that were manually edited.
   */
  autoValidated: Set<string>;
}

// =============================================================================
// Initialization Types
// =============================================================================

export type InitPhase =
  | 'idle'
  | 'loading-options'
  | 'loading-templates'
  | 'validating-upcs'
  | 'validating-fields'
  | 'ready';

// =============================================================================
// Field Options Types (from API)
// =============================================================================

export interface FieldOptionsData {
  suppliers: SelectOption[];
  companies: SelectOption[];
  taxCategories: SelectOption[];
  artists: SelectOption[];
  shipRestrictions: SelectOption[];
  sizeCategories: SelectOption[];
  categories: SelectOption[];
  themes: SelectOption[];
  colors: SelectOption[];
}

// =============================================================================
// Store State Interface
// =============================================================================

export interface ValidationState {
  // === Core Data ===
  rows: RowData[];
  originalRows: RowData[];  // For AI revert functionality

  // === Field Configuration ===
  fields: Field<string>[];
  fieldOptionsLoaded: boolean;

  // === Validation ===
  errors: ValidationErrors;
  rowValidationStatus: Map<number, RowValidationStatus>;

  // === Cell States ===
  validatingCells: Set<string>;  // Format: "rowIndex-fieldKey"
  editingCells: Set<string>;

  // === UPC Validation ===
  upcStatus: Map<number, UpcValidationStatus>;
  generatedItemNumbers: Map<number, string>;
  upcCache: Map<string, string>;  // Format: "supplierId-upc" -> itemNumber
  initialUpcValidationDone: boolean;

  // === Product Lines (hierarchical) ===
  productLinesCache: Map<string, SelectOption[]>;  // companyId -> lines
  sublinesCache: Map<string, SelectOption[]>;      // lineId -> sublines
  loadingProductLines: Set<string>;  // companyIds being loaded
  loadingSublines: Set<string>;      // lineIds being loaded

  // === Templates ===
  templates: Template[];
  templatesLoading: boolean;
  templateState: TemplateState;

  // === Filters ===
  filters: FilterState;

  // === Row Selection ===
  selectedRows: Set<string>;  // Uses __index as key

  // === Copy-Down Mode ===
  copyDownMode: CopyDownState;
  pendingCopyDownValidation: PendingCopyDownValidation | null;
  pendingInlineAiValidation: PendingInlineAiValidation | null;

  // === Dialogs ===
  dialogs: DialogState;

  // === Initialization ===
  initPhase: InitPhase;
  /** Mapping signature that produced the current rows (for back-nav merge decisions) */
  mappingSignature: MappingSignature | null;

  // === AI Validation ===
  aiValidation: AiValidationState;

  // === Inline AI Validation (Groq) ===
  inlineAi: InlineAiState;

  // === File (for output) ===
  file: File | null;

  // === UI State ===
  /** Timestamp when a MultilineInput popover was last closed (for click-outside behavior) */
  cellPopoverClosedAt: number;
}

// =============================================================================
// Store Actions Interface
// =============================================================================

export interface ValidationActions {
  // === Initialization ===
  initialize: (data: RowData[], fields: Field<string>[], file?: File) => Promise<void>;
  setFields: (fields: Field<string>[]) => void;
  setFieldOptionsLoaded: (loaded: boolean) => void;
  setMappingSignature: (signature: MappingSignature | null) => void;
  /**
   * Merge freshly-mapped rows into the existing edited rows on back-nav re-entry.
   * Only `changedFieldKeys` are overwritten (from the matching __sourceRow), and
   * `clearedFieldKeys` are removed; all other fields keep their edits.
   */
  reconcileMappedData: (
    freshRows: RowData[],
    changedFieldKeys: string[],
    clearedFieldKeys: string[],
  ) => void;

  // === Row Operations ===
  updateCell: (rowIndex: number, field: string, value: unknown) => void;
  updateRow: (rowIndex: number, updates: Partial<RowData>) => void;
  deleteRows: (rowIndexes: number[]) => void;
  addRow: (rowData?: Partial<RowData>) => void;
  copyDown: (fromRowIndex: number, fieldKey: string, toRowIndex?: number) => void;
  setRows: (rows: RowData[]) => void;

  // === Validation ===
  setError: (rowIndex: number, field: string, error: ValidationError | null) => void;
  setErrors: (rowIndex: number, errors: Record<string, ValidationError[]>) => void;
  setBulkValidationResults: (
    allErrors: Map<number, Record<string, ValidationError[]>>,
    allStatuses: Map<number, RowValidationStatus>
  ) => void;
  clearRowErrors: (rowIndex: number) => void;
  clearFieldError: (rowIndex: number, field: string) => void;
  setRowValidationStatus: (rowIndex: number, status: RowValidationStatus) => void;

  // === Cell States ===
  startValidatingCell: (rowIndex: number, field: string) => void;
  stopValidatingCell: (rowIndex: number, field: string) => void;
  startEditingCell: (rowIndex: number, field: string) => void;
  stopEditingCell: (rowIndex: number, field: string) => void;

  // === UPC ===
  setUpcStatus: (rowIndex: number, status: UpcValidationStatus) => void;
  setGeneratedItemNumber: (rowIndex: number, itemNumber: string) => void;
  cacheUpcResult: (supplierId: string, upc: string, itemNumber: string) => void;
  getCachedItemNumber: (supplierId: string, upc: string) => string | undefined;
  setInitialUpcValidationDone: (done: boolean) => void;

  // === Product Lines ===
  setProductLines: (companyId: string, lines: SelectOption[]) => void;
  setSublines: (lineId: string, sublines: SelectOption[]) => void;
  setLoadingProductLines: (companyId: string, loading: boolean) => void;
  setLoadingSublines: (lineId: string, loading: boolean) => void;

  // === Templates ===
  setTemplates: (templates: Template[]) => void;
  setTemplatesLoading: (loading: boolean) => void;
  setTemplateState: (state: Partial<TemplateState>) => void;

  // === Filters ===
  setSearchText: (text: string) => void;
  setShowErrorsOnly: (value: boolean) => void;
  setFilters: (filters: Partial<FilterState>) => void;

  // === Row Selection ===
  setSelectedRows: (rows: Set<string>) => void;
  toggleRowSelection: (rowId: string) => void;
  selectAllRows: () => void;
  clearSelection: () => void;

  // === Copy-Down Mode ===
  setCopyDownMode: (mode: Partial<CopyDownState>) => void;
  startCopyDown: (rowIndex: number, fieldKey: string) => void;
  cancelCopyDown: () => void;
  completeCopyDown: (targetRowIndex: number) => void;
  setTargetRowHover: (rowIndex: number | null) => void;
  clearPendingCopyDownValidation: () => void;
  clearPendingInlineAiValidation: () => void;

  // === Dialogs ===
  setDialogs: (updates: Partial<DialogState>) => void;
  openTemplateForm: (initialData: Record<string, unknown>) => void;
  closeTemplateForm: () => void;

  // === Initialization Phase ===
  setInitPhase: (phase: InitPhase) => void;

  // === AI Validation ===
  setAiValidationRunning: (running: boolean) => void;
  setAiValidationProgress: (
    progress: AiValidationProgress | null | ((prev: AiValidationProgress | null) => AiValidationProgress | null)
  ) => void;
  setAiValidationResults: (results: AiValidationResults | null) => void;
  revertAiChange: (productIndex: number, fieldKey: string) => void;
  acceptAiChange: (productIndex: number, fieldKey: string) => void;
  clearAiValidation: () => void;
  storeOriginalValues: () => void;

  // === Inline AI Validation ===
  setInlineAiSuggestion: (productIndex: string, field: 'name' | 'description', result: InlineAiValidationResult) => void;
  dismissInlineAiSuggestion: (productIndex: string, field: 'name' | 'description') => void;
  acceptInlineAiSuggestion: (productIndex: string, field: 'name' | 'description') => void;
  clearInlineAiSuggestion: (productIndex: string, field?: 'name' | 'description') => void;
  setInlineAiValidating: (productIndex: string, validating: boolean) => void;
  markInlineAiAutoValidated: (productIndex: string, field: 'name' | 'description') => void;
  isInlineAiAutoValidated: (productIndex: string, field: 'name' | 'description') => boolean;

  // === Output ===
  getCleanedData: () => CleanRowData[];

  // === UI State ===
  /** Called when a MultilineInput popover closes to prevent immediate focus on other cells */
  setCellPopoverClosed: () => void;

  // === Reset ===
  reset: () => void;
}

// =============================================================================
// Combined Store Type
// =============================================================================

export type ValidationStore = ValidationState & ValidationActions;

// =============================================================================
// Component Props Types
// =============================================================================

export interface ValidationStepProps {
  initialData: RowData[];
  file?: File;
  onBack?: () => void;
  onNext?: (data: CleanRowData[]) => void;
  isFromScratch?: boolean;
  /**
   * Signature describing how columns were mapped. Used on back-nav re-entry to decide
   * whether to preserve edits (merge changed fields only) vs. fully re-initialize, and
   * whether UPC validation needs to re-run. Undefined for from-scratch / restored flows.
   */
  mappingSignature?: MappingSignature;
}
