/**
 * InputCell Component
 *
 * Editable input cell for text, numbers, and price values.
 * Memoized to prevent unnecessary re-renders when parent table updates.
 *
 * PRICE PRECISION: For price fields, we store FULL precision internally
 * (e.g., "3.625") but display rounded to 2 decimals when not focused.
 * This allows calculations like 2x to use full precision while showing
 * user-friendly rounded values in the UI.
 */

import { useState, useCallback, useEffect, useRef, memo, useMemo } from 'react';
import { Input } from '@/components/ui/input';
import { AlertCircle } from 'lucide-react';
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from '@/components/ui/tooltip';
import { Skeleton } from '@/components/ui/skeleton';
import { cn } from '@/lib/utils';
import type { Field, SelectOption } from '../../../../types';
import type { ValidationError } from '../../store/types';
import { ErrorType } from '../../store/types';
import { useValidationStore } from '../../store/validationStore';

/**
 * Format a price value for display (2 decimal places)
 * Returns the original string if it's not a valid number
 */
const formatPriceForDisplay = (value: string): string => {
  if (!value) return value;
  const num = parseFloat(value);
  if (isNaN(num)) return value;
  return num.toFixed(2);
};

/** Time window (ms) during which this cell should not focus after a popover closes */
const POPOVER_CLOSE_DELAY = 150;

interface InputCellProps {
  value: unknown;
  field: Field<string>;
  options?: SelectOption[];
  rowIndex: number;
  isValidating: boolean;
  errors: ValidationError[];
  onChange: (value: unknown) => void;
  onBlur: (value: unknown) => void;
  onFetchOptions?: () => void;
}

const InputCellComponent = ({
  value,
  field,
  isValidating,
  errors,
  onBlur,
}: InputCellProps) => {
  // Store the full precision value internally
  const [localValue, setLocalValue] = useState(String(value ?? ''));
  const [isFocused, setIsFocused] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  // Check if this is a price field
  const isPriceField = 'price' in field.fieldType && field.fieldType.price;

  // Get store state for coordinating with popover close behavior
  const cellPopoverClosedAt = useValidationStore((s) => s.cellPopoverClosedAt);

  // Sync local value with prop value when not focused
  useEffect(() => {
    if (!isFocused) {
      setLocalValue(String(value ?? ''));
    }
  }, [value, isFocused]);

  // For price fields: show formatted value when not focused, full precision when focused
  const displayValue = useMemo(() => {
    if (isPriceField && !isFocused && localValue) {
      return formatPriceForDisplay(localValue);
    }
    return localValue;
  }, [isPriceField, isFocused, localValue]);

  // PERFORMANCE: Only update local state while typing, NOT the store
  // The store is updated on blur, which prevents thousands of subscription
  // checks per keystroke
  const handleChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      let newValue = e.target.value;

      // Handle price formatting
      if ('price' in field.fieldType && field.fieldType.price) {
        // Allow only numbers and decimal point
        newValue = newValue.replace(/[^0-9.]/g, '');
      }

      // Only update local state - store will be updated on blur
      setLocalValue(newValue);
    },
    [field]
  );

  const handleFocus = useCallback(() => {
    // Block focus if a popover was just closed (click-outside behavior)
    if (Date.now() - cellPopoverClosedAt < POPOVER_CLOSE_DELAY) {
      inputRef.current?.blur();
      return;
    }
    setIsFocused(true);
  }, [cellPopoverClosedAt]);

  // Handle Enter key to blur the field (useful for barcode scanners that send Enter after scan)
  const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      inputRef.current?.blur();
    }
  }, []);

  // Update store only on blur - this is when validation runs too
  // IMPORTANT: We store FULL precision for price fields to allow accurate calculations
  // The display formatting happens separately via displayValue
  const handleBlur = useCallback(() => {
    setIsFocused(false);
    // Store the full precision value - no rounding here
    onBlur(localValue);
  }, [localValue, onBlur]);

  // Process errors - show icon only for non-required errors when field has value
  // Don't show error icon while user is actively editing (focused)
  const hasError = errors.length > 0;
  const isRequiredError = errors.length === 1 && errors[0]?.type === ErrorType.Required;
  const valueIsEmpty = !localValue;
  const showErrorIcon = !isFocused && hasError && !(valueIsEmpty && isRequiredError);
  const errorMessage = errors.filter(e => !(valueIsEmpty && e.type === ErrorType.Required))
    .map(e => e.message).join('\n');

  // Show skeleton while validating
  if (isValidating) {
    return (
      <div className={cn(
        'h-8 w-full flex items-center border rounded-md px-2',
        hasError && 'border-destructive'
      )}>
        <Skeleton className="h-4 w-full" />
      </div>
    );
  }

  return (
    <div className="relative w-full">
      <Input
        ref={inputRef}
        value={displayValue}
        onChange={handleChange}
        onFocus={handleFocus}
        onBlur={handleBlur}
        onKeyDown={handleKeyDown}
        disabled={isValidating}
        className={cn(
          'h-8 text-sm',
          hasError && 'border-destructive focus-visible:ring-destructive',
          isValidating && 'opacity-50',
          showErrorIcon && 'pr-8'
        )}
      />
      
      {/* Error icon with tooltip - only for non-required errors */}
      {showErrorIcon && (
        <div className="absolute right-2 top-1/2 -translate-y-1/2 z-10">
          <TooltipProvider>
            <Tooltip delayDuration={200}>
              <TooltipTrigger asChild>
                <div className="cursor-help">
                  <AlertCircle className="h-4 w-4 text-destructive" />
                </div>
              </TooltipTrigger>
              <TooltipContent className="max-w-[300px]">
                <p className="whitespace-pre-wrap">{errorMessage}</p>
              </TooltipContent>
            </Tooltip>
          </TooltipProvider>
        </div>
      )}
    </div>
  );
};

// Memoize to prevent re-renders when parent table state changes
export const InputCell = memo(InputCellComponent);
