/**
 * NumPad Component
 *
 * On-screen number pad for tablets with large, touch-friendly buttons.
 * Ideal for cash tender entry and custom tip amounts.
 *
 * Features:
 * - Large 60x60px buttons minimum
 * - Visual feedback on press
 * - Decimal point support
 * - Backspace and clear
 * - Keyboard input support
 * - Format as currency ($)
 */

import React, { useState, useEffect, useRef } from 'react';
import { Delete, X } from 'lucide-react';

interface NumPadProps {
  /** Current value in cents */
  value: number;
  /** Callback when value changes (in cents) */
  onChange: (cents: number) => void;
  /** Optional label/title above the display */
  label?: string;
  /** Show currency symbol ($) */
  showCurrency?: boolean;
  /** Maximum value allowed in cents */
  maxCents?: number;
  /** Callback when Enter/OK is pressed */
  onSubmit?: () => void;
  /** Show submit button */
  showSubmit?: boolean;
  /** Submit button text */
  submitText?: string;
  /** Additional CSS classes */
  className?: string;
}

export const NumPad: React.FC<NumPadProps> = ({
  value,
  onChange,
  label,
  showCurrency = true,
  maxCents,
  onSubmit,
  showSubmit = false,
  submitText = 'OK',
  className = '',
}) => {
  const [displayValue, setDisplayValue] = useState<string>('');
  // Track if user is actively inputting (to prevent value prop from overwriting)
  const isInputtingRef = useRef(false);

  // Convert cents to display value (dollars) only when:
  // 1. Value prop changes externally (not from our own onChange)
  // 2. Not currently inputting
  useEffect(() => {
    if (!isInputtingRef.current) {
      const dollars = (value / 100).toFixed(2);
      setDisplayValue(dollars);
    }
  }, [value]);

  /**
   * Handle number button click
   */
  const handleNumber = (num: string) => {
    isInputtingRef.current = true;

    // Remove all non-digit characters except decimal
    const cleanValue = displayValue.replace(/[^\d.]/g, '');

    // Special case: if value is "0.00" (initial zero state), start fresh with the new number
    if (cleanValue === '0.00') {
      setDisplayValue(num);
      updateValue(num);
      return;
    }

    // Split into dollars and cents
    const parts = cleanValue.split('.');

    if (parts.length === 1) {
      // No decimal yet
      const newValue = cleanValue + num;
      setDisplayValue(newValue);
      updateValue(newValue);
    } else if (parts.length === 2) {
      // Already has decimal
      if (parts[1].length < 2) {
        // Can still add cents
        const newValue = parts[0] + '.' + parts[1] + num;
        setDisplayValue(newValue);
        updateValue(newValue);
      }
    }
  };

  /**
   * Handle decimal point
   */
  const handleDecimal = () => {
    isInputtingRef.current = true;
    const cleanValue = displayValue.replace(/[^\d.]/g, '');
    if (!cleanValue.includes('.')) {
      const newValue = (cleanValue || '0') + '.';
      setDisplayValue(newValue);
      updateValue(newValue);
    }
  };

  /**
   * Handle backspace
   */
  const handleBackspace = () => {
    isInputtingRef.current = true;
    const cleanValue = displayValue.replace(/[^\d.]/g, '');
    if (cleanValue.length > 0) {
      const newValue = cleanValue.slice(0, -1) || '0';
      setDisplayValue(newValue);
      updateValue(newValue);
    }
  };

  /**
   * Handle clear
   */
  const handleClear = () => {
    isInputtingRef.current = false; // Reset to allow external value sync
    setDisplayValue('0.00');
    updateValue('0');
  };

  /**
   * Update the value and call onChange with cents
   * Returns the actual cents value used (may be capped)
   */
  const updateValue = (newValue: string): number => {
    let cents = Math.round(parseFloat(newValue || '0') * 100);

    // Cap at max value if specified
    if (maxCents !== undefined && cents > maxCents) {
      cents = maxCents;
      // Update display to show capped value
      const cappedDisplay = (cents / 100).toFixed(2);
      setDisplayValue(cappedDisplay);
    }

    onChange(cents);
    return cents;
  };

  /**
   * Keyboard support
   */
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key >= '0' && e.key <= '9') {
        e.preventDefault();
        handleNumber(e.key);
      } else if (e.key === '.' || e.key === ',') {
        e.preventDefault();
        handleDecimal();
      } else if (e.key === 'Backspace') {
        e.preventDefault();
        handleBackspace();
      } else if (e.key === 'Escape') {
        e.preventDefault();
        handleClear();
      } else if (e.key === 'Enter' && onSubmit) {
        e.preventDefault();
        onSubmit();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [displayValue]);

  /**
   * Format display value with currency symbol
   */
  const formattedDisplay = showCurrency
    ? `$${displayValue}`
    : displayValue;

  return (
    <div className={`flex flex-col ${className}`}>
      {/* Label */}
      {label && (
        <div className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
          {label}
        </div>
      )}

      {/* Display */}
      <div className="bg-gray-100 dark:bg-gray-800 rounded-lg p-4 mb-4">
        <div className="text-4xl font-bold text-gray-900 dark:text-white text-right font-mono">
          {formattedDisplay}
        </div>
      </div>

      {/* Number pad grid */}
      <div className="grid grid-cols-3 gap-2">
        {/* Numbers 1-9 */}
        {[1, 2, 3, 4, 5, 6, 7, 8, 9].map((num) => (
          <button
            key={num}
            onClick={() => handleNumber(num.toString())}
            className="
              h-16 w-full
              bg-white dark:bg-gray-700
              hover:bg-gray-50 dark:hover:bg-gray-600
              active:bg-gray-100 dark:active:bg-gray-500
              border border-gray-300 dark:border-gray-600
              rounded-lg
              text-2xl font-semibold
              text-gray-900 dark:text-white
              transition-colors
              touch-manipulation
              select-none
            "
          >
            {num}
          </button>
        ))}

        {/* Bottom row: Clear, 0, Decimal */}
        <button
          onClick={handleClear}
          className="
            h-16 w-full
            bg-red-100 dark:bg-red-900/30
            hover:bg-red-200 dark:hover:bg-red-900/50
            active:bg-red-300 dark:active:bg-red-900/70
            border border-red-300 dark:border-red-700
            rounded-lg
            text-xl font-semibold
            text-red-700 dark:text-red-400
            transition-colors
            touch-manipulation
            select-none
            flex items-center justify-center
          "
          title="Clear (Esc)"
        >
          <X className="h-6 w-6" />
        </button>

        <button
          onClick={() => handleNumber('0')}
          className="
            h-16 w-full
            bg-white dark:bg-gray-700
            hover:bg-gray-50 dark:hover:bg-gray-600
            active:bg-gray-100 dark:active:bg-gray-500
            border border-gray-300 dark:border-gray-600
            rounded-lg
            text-2xl font-semibold
            text-gray-900 dark:text-white
            transition-colors
            touch-manipulation
            select-none
          "
        >
          0
        </button>

        <button
          onClick={handleDecimal}
          className="
            h-16 w-full
            bg-white dark:bg-gray-700
            hover:bg-gray-50 dark:hover:bg-gray-600
            active:bg-gray-100 dark:active:bg-gray-500
            border border-gray-300 dark:border-gray-600
            rounded-lg
            text-2xl font-semibold
            text-gray-900 dark:text-white
            transition-colors
            touch-manipulation
            select-none
          "
        >
          .
        </button>

        {/* Backspace button - spans column */}
        <button
          onClick={handleBackspace}
          className="
            col-span-3
            h-16 w-full
            bg-gray-200 dark:bg-gray-600
            hover:bg-gray-300 dark:hover:bg-gray-500
            active:bg-gray-400 dark:active:bg-gray-400
            border border-gray-300 dark:border-gray-500
            rounded-lg
            text-xl font-semibold
            text-gray-700 dark:text-gray-200
            transition-colors
            touch-manipulation
            select-none
            flex items-center justify-center gap-2
          "
          title="Backspace"
        >
          <Delete className="h-5 w-5" />
          Backspace
        </button>

        {/* Optional submit button */}
        {showSubmit && onSubmit && (
          <button
            onClick={onSubmit}
            className="
              col-span-3
              h-16 w-full
              bg-brand-600 dark:bg-brand-600
              hover:bg-brand-700 dark:hover:bg-brand-700
              active:bg-brand-800 dark:active:bg-brand-800
              border border-brand-700 dark:border-brand-700
              rounded-lg
              text-xl font-semibold
              text-white
              transition-colors
              touch-manipulation
              select-none
            "
          >
            {submitText}
          </button>
        )}
      </div>

      {/* Keyboard hint */}
      <div className="text-xs text-gray-500 dark:text-gray-400 text-center mt-2">
        Keyboard: 0-9, . (decimal), Backspace, Esc (clear)
        {onSubmit && ', Enter (submit)'}
      </div>
    </div>
  );
};

export default NumPad;
