/**
 * Manual Entry Modal for Ticket Scanner
 * Optimized for gate staff with gloves and stylus input
 */

import { useState, useEffect, useCallback } from 'react';

import { motion, AnimatePresence } from 'framer-motion';
import { 
  X, 
  Delete, 
  Check, 
  Loader2, 
  AlertCircle,
  Hash,
  Eye,
  EyeOff
} from 'lucide-react';

import { Button } from '../../components/ui/Button';
import { Card } from '../../components/ui/Card';
import { formatBackupCode, QRValidator } from '../../lib/qr-validator';

export interface ManualEntryProps {
  isOpen: boolean;
  onClose: () => void;
  onSubmit: (code: string) => Promise<void>;
  isLoading: boolean;
  lastError?: string;
}

const KEYPAD_BUTTONS = [
  ['1', '2', '3'],
  ['4', '5', '6'],  
  ['7', '8', '9'],
  ['clear', '0', 'delete']
] as const;

const LETTER_BUTTONS = [
  ['A', 'B', 'C'],
  ['D', 'E', 'F']
] as const;

export function ManualEntryModal({ 
  isOpen, 
  onClose, 
  onSubmit, 
  isLoading, 
  lastError 
}: ManualEntryProps): JSX.Element {
  const [code, setCode] = useState('');
  const [showLetters, setShowLetters] = useState(false);
  const [validator] = useState(() => new QRValidator());

  // Reset state when modal opens/closes
  useEffect(() => {
    if (isOpen) {
      setCode('');
      setShowLetters(false);
    }
  }, [isOpen]);

  const handleKeyPress = useCallback((key: string) => {
    if (isLoading) {return;}

    switch (key) {
      case 'clear':
        setCode('');
        break;
      
      case 'delete':
        setCode(prev => prev.slice(0, -1));
        break;
      
      default:
        if (code.length < 8) {
          setCode(prev => prev + key);
        }
        break;
    }
  }, [code.length, isLoading]);

  const handleSubmit = useCallback(async () => {
    if (code.length === 0 || isLoading) {return;}

    const validation = validator.validateBackupCode(code);
    if (!validation.valid) {
      // Don't submit invalid codes - let user fix them
      return;
    }

    try {
      await onSubmit(validation.normalizedCode!);
    } catch (error) {
      // Error handling is done in parent component
      console.error('Manual entry submission error:', error);
    }
  }, [code, isLoading, onSubmit, validator]);

  const isCodeValid = validator.validateBackupCode(code).valid;
  const formattedCode = formatBackupCode(code.padEnd(8, '_'));

  // Keyboard event handling
  useEffect(() => {
    if (!isOpen) {return;}

    const handleKeyDown = (event: KeyboardEvent) => {
      if (isLoading) {return;}

      const {key} = event;
      
      // Numbers
      if (/^[0-9]$/.test(key)) {
        event.preventDefault();
        handleKeyPress(key);
      }
      
      // Letters (A-F for hex codes)
      if (/^[A-Fa-f]$/.test(key)) {
        event.preventDefault();
        handleKeyPress(key.toUpperCase());
      }
      
      // Backspace
      if (key === 'Backspace') {
        event.preventDefault();
        handleKeyPress('delete');
      }
      
      // Escape
      if (key === 'Escape') {
        event.preventDefault();
        onClose();
      }
      
      // Enter
      if (key === 'Enter' && isCodeValid) {
        event.preventDefault();
        handleSubmit();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [isOpen, handleKeyPress, handleSubmit, isCodeValid, isLoading, onClose]);

  if (!isOpen) {return <></>;}

  return (
    <AnimatePresence>
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        className="fixed inset-0 z-50 bg-black bg-opacity-75 flex items-center justify-center p-4"
        onClick={onClose}
      >
        <motion.div
          initial={{ scale: 0.95, opacity: 0 }}
          animate={{ scale: 1, opacity: 1 }}
          exit={{ scale: 0.95, opacity: 0 }}
          onClick={(e) => e.stopPropagation()}
          className="w-full max-w-md mx-auto"
        >
          <Card className="bg-glass-bg backdrop-blur-lg border-glass-border p-6">
            {/* Header */}
            <div className="flex items-center justify-between mb-6">
              <div className="flex items-center space-x-3">
                <Hash className="h-6 w-6 text-primary-500" />
                <h2 className="text-lg font-semibold text-primary-text">
                  Manual Entry
                </h2>
              </div>
              
              <Button
                onClick={onClose}
                variant="ghost"
                size="sm"
                className="p-2"
                disabled={isLoading}
              >
                <X className="h-5 w-5" />
              </Button>
            </div>

            {/* Instructions */}
            <div className="mb-6">
              <p className="text-sm text-secondary-text mb-2">
                Enter the last 8 characters from the ticket code
              </p>
              <div className="text-xs text-tertiary-text space-y-1">
                <p>• Found at bottom of physical tickets</p>
                <p>• Use when QR code is damaged or unreadable</p>
                <p>• Numbers and letters A-F only</p>
              </div>
            </div>

            {/* Code Display */}
            <div className="mb-6">
              <div className="relative">
                <div className={`
                  w-full p-4 text-center font-mono text-2xl tracking-wider 
                  bg-input-bg border border-input-border rounded-lg
                  ${isCodeValid ? 'border-success-500 bg-success-50' : ''}
                  ${code.length > 0 && !isCodeValid ? 'border-warning-500 bg-warning-50' : ''}
                `}>
                  {formattedCode}
                </div>
                
                {/* Validation indicator */}
                <div className="absolute right-3 top-1/2 transform -translate-y-1/2">
                  {code.length === 8 && isCodeValid && (
                    <Check className="h-5 w-5 text-success-500" />
                  )}
                  {code.length > 0 && code.length < 8 && (
                    <span className="text-xs text-tertiary-text">
                      {8 - code.length} more
                    </span>
                  )}
                </div>
              </div>

              {/* Error Display */}
              {lastError && (
                <motion.div
                  initial={{ opacity: 0, height: 0 }}
                  animate={{ opacity: 1, height: 'auto' }}
                  className="mt-2 p-3 bg-error-50 border border-error-200 rounded-lg flex items-center space-x-2"
                >
                  <AlertCircle className="h-4 w-4 text-error-500 flex-shrink-0" />
                  <p className="text-sm text-error-600">{lastError}</p>
                </motion.div>
              )}
            </div>

            {/* Letter/Number Toggle */}
            <div className="mb-4 flex items-center justify-center">
              <Button
                onClick={() => setShowLetters(!showLetters)}
                variant="outline"
                size="sm"
                className="flex items-center space-x-2"
                disabled={isLoading}
              >
                {showLetters ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                <span>{showLetters ? 'Hide' : 'Show'} Letters A-F</span>
              </Button>
            </div>

            {/* Keypad */}
            <div className="space-y-3">
              {/* Number Keys */}
              {KEYPAD_BUTTONS.map((row, rowIndex) => (
                <div key={rowIndex} className="grid grid-cols-3 gap-3">
                  {row.map((key) => {
                    let buttonContent: React.ReactNode;
                    let variant: 'primary' | 'outline' | 'secondary' = 'outline';
                    let disabled = isLoading;

                    switch (key) {
                      case 'clear':
                        buttonContent = 'Clear';
                        variant = 'secondary';
                        disabled = disabled || code.length === 0;
                        break;
                      case 'delete':
                        buttonContent = <Delete className="h-5 w-5" />;
                        variant = 'secondary';
                        disabled = disabled || code.length === 0;
                        break;
                      default:
                        buttonContent = key;
                        disabled = disabled || code.length >= 8;
                        break;
                    }

                    return (
                      <Button
                        key={key}
                        onClick={() => handleKeyPress(key)}
                        variant={variant}
                        disabled={disabled}
                        className="h-14 text-lg font-semibold touch-manipulation"
                      >
                        {buttonContent}
                      </Button>
                    );
                  })}
                </div>
              ))}

              {/* Letter Keys (A-F) */}
              {showLetters && (
                <div className="space-y-3 border-t border-glass-border pt-3">
                  {LETTER_BUTTONS.map((row, rowIndex) => (
                    <div key={`letters-${rowIndex}`} className="grid grid-cols-3 gap-3">
                      {row.map((key) => (
                        <Button
                          key={key}
                          onClick={() => handleKeyPress(key)}
                          variant="outline"
                          disabled={isLoading || code.length >= 8}
                          className="h-14 text-lg font-semibold touch-manipulation"
                        >
                          {key}
                        </Button>
                      ))}
                    </div>
                  ))}
                </div>
              )}
            </div>

            {/* Submit Button */}
            <div className="mt-6 flex space-x-3">
              <Button
                onClick={onClose}
                variant="outline"
                disabled={isLoading}
                className="flex-1"
              >
                Cancel
              </Button>
              
              <Button
                onClick={handleSubmit}
                variant="primary"
                disabled={!isCodeValid || isLoading}
                className="flex-1 flex items-center justify-center space-x-2"
              >
                {isLoading ? (
                  <>
                    <Loader2 className="h-4 w-4 animate-spin" />
                    <span>Checking...</span>
                  </>
                ) : (
                  <>
                    <Check className="h-4 w-4" />
                    <span>Submit</span>
                  </>
                )}
              </Button>
            </div>

            {/* Footer Help */}
            <div className="mt-4 text-center">
              <p className="text-xs text-tertiary-text">
                Press Enter to submit • Esc to cancel
              </p>
            </div>
          </Card>
        </motion.div>
      </motion.div>
    </AnimatePresence>
  );
}