import { useState, useRef, useEffect, memo, useCallback } from 'react';
import { Send, Square, Command, History, Paperclip, X, Image, FileText } from 'lucide-react';

// LocalStorage key for input history
const HISTORY_KEY = 'claude-webui-input-history';
const MAX_HISTORY = 100;
const MAX_FILES = 5;
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB

// Allowed file types
const ALLOWED_EXTENSIONS = [
  // Images
  '.png', '.jpg', '.jpeg', '.gif', '.webp',
  // Text/Code
  '.txt', '.md', '.csv', '.html', '.css', '.js', '.ts', '.jsx', '.tsx',
  '.json', '.xml', '.yaml', '.yml', '.py', '.go', '.rs', '.java', '.c',
  '.cpp', '.h', '.sh', '.bash', '.zsh', '.toml', '.ini', '.conf', '.sql',
  '.rb', '.php', '.swift', '.kt', '.scala', '.r', '.lua', '.pl', '.pm'
];

// Load history from localStorage
function loadHistory() {
  try {
    const stored = localStorage.getItem(HISTORY_KEY);
    return stored ? JSON.parse(stored) : [];
  } catch {
    return [];
  }
}

// Save history to localStorage
function saveHistory(history) {
  try {
    localStorage.setItem(HISTORY_KEY, JSON.stringify(history.slice(0, MAX_HISTORY)));
  } catch {}
}

// Available slash commands for autocomplete
const COMMANDS = [
  { name: 'help', description: 'Show available commands' },
  { name: 'clear', description: 'Clear chat history' },
  { name: 'export', description: 'Export chat as Markdown' },
  { name: 'scroll', description: 'Scroll to top or bottom' },
  { name: 'new', description: 'Start a new session' },
  { name: 'info', description: 'Show session info' },
  { name: 'history', description: 'Search input history (/history <term>)' },
];

export const ChatInput = memo(function ChatInput({ onSend, onStop, disabled, isProcessing, placeholder, sessionId }) {
  const [message, setMessage] = useState('');
  const [showCommands, setShowCommands] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(0);
  const [filteredCommands, setFilteredCommands] = useState(COMMANDS);
  const [inputHistory, setInputHistory] = useState(() => loadHistory());
  const [historyIndex, setHistoryIndex] = useState(-1);
  const [savedInput, setSavedInput] = useState('');
  const [showHistorySearch, setShowHistorySearch] = useState(false);
  const [historySearchResults, setHistorySearchResults] = useState([]);
  const [attachedFiles, setAttachedFiles] = useState([]);
  const [isDragOver, setIsDragOver] = useState(false);
  const [uploadError, setUploadError] = useState(null);
  const textareaRef = useRef(null);
  const fileInputRef = useRef(null);

  // Auto-resize textarea
  useEffect(() => {
    const textarea = textareaRef.current;
    if (textarea) {
      textarea.style.height = 'auto';
      textarea.style.height = Math.min(textarea.scrollHeight, 200) + 'px';
    }
  }, [message]);

  // Handle command filtering
  useEffect(() => {
    if (message.startsWith('/')) {
      const query = message.slice(1).toLowerCase();
      const filtered = COMMANDS.filter(cmd =>
        cmd.name.toLowerCase().startsWith(query)
      );
      setFilteredCommands(filtered);
      setShowCommands(filtered.length > 0 && message.length > 0);
      setSelectedIndex(0);
    } else {
      setShowCommands(false);
    }
  }, [message]);

  // Add message to history
  const addToHistory = useCallback((msg) => {
    const trimmed = msg.trim();
    if (!trimmed) return;

    setInputHistory(prev => {
      // Remove duplicate if exists
      const filtered = prev.filter(h => h !== trimmed);
      const newHistory = [trimmed, ...filtered].slice(0, MAX_HISTORY);
      saveHistory(newHistory);
      return newHistory;
    });
  }, []);

  // Validate file
  const validateFile = useCallback((file) => {
    const ext = '.' + file.name.split('.').pop().toLowerCase();
    if (!ALLOWED_EXTENSIONS.includes(ext) && !file.type.startsWith('image/')) {
      return `File type not allowed: ${ext}`;
    }
    if (file.size > MAX_FILE_SIZE) {
      return `File too large: ${(file.size / 1024 / 1024).toFixed(1)}MB (max 10MB)`;
    }
    return null;
  }, []);

  // Process and add files
  const processFiles = useCallback((files) => {
    setUploadError(null);
    const fileArray = Array.from(files);
    const remaining = MAX_FILES - attachedFiles.length;

    if (fileArray.length > remaining) {
      setUploadError(`Only ${remaining} more file(s) can be added (max ${MAX_FILES})`);
      return;
    }

    const newFiles = [];
    for (const file of fileArray) {
      const error = validateFile(file);
      if (error) {
        setUploadError(error);
        return;
      }

      // Create preview for images
      const isImage = file.type.startsWith('image/');
      const fileData = {
        file,
        name: file.name,
        size: file.size,
        type: file.type,
        isImage,
        preview: isImage ? URL.createObjectURL(file) : null,
        id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
      };
      newFiles.push(fileData);
    }

    setAttachedFiles(prev => [...prev, ...newFiles]);
  }, [attachedFiles.length, validateFile]);

  // Remove attached file
  const removeFile = useCallback((id) => {
    setAttachedFiles(prev => {
      const file = prev.find(f => f.id === id);
      if (file?.preview) {
        URL.revokeObjectURL(file.preview);
      }
      return prev.filter(f => f.id !== id);
    });
  }, []);

  // Handle paste event
  const handlePaste = useCallback((e) => {
    const items = e.clipboardData?.items;
    if (!items) return;

    const files = [];
    for (const item of items) {
      if (item.kind === 'file') {
        const file = item.getAsFile();
        if (file) files.push(file);
      }
    }

    if (files.length > 0) {
      e.preventDefault();
      processFiles(files);
    }
  }, [processFiles]);

  // Handle drag and drop
  const handleDragOver = useCallback((e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(true);
  }, []);

  const handleDragLeave = useCallback((e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(false);
  }, []);

  const handleDrop = useCallback((e) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(false);

    const files = e.dataTransfer?.files;
    if (files && files.length > 0) {
      processFiles(files);
    }
  }, [processFiles]);

  // Handle file input change
  const handleFileSelect = useCallback((e) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      processFiles(files);
    }
    // Reset input so same file can be selected again
    e.target.value = '';
  }, [processFiles]);

  // Cleanup previews on unmount
  useEffect(() => {
    return () => {
      attachedFiles.forEach(f => {
        if (f.preview) URL.revokeObjectURL(f.preview);
      });
    };
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    if (message.trim() || attachedFiles.length > 0) {
      addToHistory(message);
      // Pass both message and files to onSend
      onSend(message, attachedFiles);
      setMessage('');
      setAttachedFiles([]);
      setShowCommands(false);
      setHistoryIndex(-1);
      setSavedInput('');
      setUploadError(null);
    }
  };

  const selectCommand = (cmdName) => {
    setMessage(`/${cmdName} `);
    setShowCommands(false);
    textareaRef.current?.focus();
  };

  // Select from history search
  const selectHistoryItem = (item) => {
    setMessage(item);
    setShowHistorySearch(false);
    setHistorySearchResults([]);
    textareaRef.current?.focus();
  };

  const handleKeyDown = (e) => {
    // ESC to stop generation
    if (e.key === 'Escape') {
      if (isProcessing && onStop) {
        e.preventDefault();
        onStop();
        return;
      }
      if (showCommands) {
        setShowCommands(false);
        return;
      }
      if (showHistorySearch) {
        setShowHistorySearch(false);
        return;
      }
    }

    // Handle history search results navigation
    if (showHistorySearch && historySearchResults.length > 0) {
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        setSelectedIndex(i => Math.min(i + 1, historySearchResults.length - 1));
        return;
      }
      if (e.key === 'ArrowUp') {
        e.preventDefault();
        setSelectedIndex(i => Math.max(i - 1, 0));
        return;
      }
      if (e.key === 'Enter') {
        e.preventDefault();
        selectHistoryItem(historySearchResults[selectedIndex]);
        return;
      }
    }

    // Handle command selection
    if (showCommands) {
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        setSelectedIndex(i => Math.min(i + 1, filteredCommands.length - 1));
        return;
      }
      if (e.key === 'ArrowUp') {
        e.preventDefault();
        setSelectedIndex(i => Math.max(i - 1, 0));
        return;
      }
      if (e.key === 'Tab' || (e.key === 'Enter' && filteredCommands.length > 0)) {
        e.preventDefault();
        selectCommand(filteredCommands[selectedIndex].name);
        return;
      }
    }

    // Arrow up/down for history navigation (only when not in command/search mode)
    if (!showCommands && !showHistorySearch && inputHistory.length > 0) {
      if (e.key === 'ArrowUp') {
        // Only navigate history if at start of input or input is empty
        const textarea = textareaRef.current;
        if (textarea && (textarea.selectionStart === 0 || message === '')) {
          e.preventDefault();
          if (historyIndex === -1) {
            setSavedInput(message);
          }
          const newIndex = Math.min(historyIndex + 1, inputHistory.length - 1);
          setHistoryIndex(newIndex);
          setMessage(inputHistory[newIndex]);
          return;
        }
      }
      if (e.key === 'ArrowDown' && historyIndex >= 0) {
        e.preventDefault();
        const newIndex = historyIndex - 1;
        setHistoryIndex(newIndex);
        if (newIndex === -1) {
          setMessage(savedInput);
        } else {
          setMessage(inputHistory[newIndex]);
        }
        return;
      }
    }

    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSubmit(e);
    }
  };

  return (
    <form
      onSubmit={handleSubmit}
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
      className={`p-4 border-t border-dark-800 bg-dark-900 transition-colors ${isDragOver ? 'bg-orange-900/20 border-orange-500/50' : ''}`}
    >
      {/* Drag overlay */}
      {isDragOver && (
        <div className="absolute inset-0 bg-orange-900/30 border-2 border-dashed border-orange-500 rounded-lg flex items-center justify-center z-20 pointer-events-none">
          <div className="text-orange-400 text-lg font-medium">Drop files here</div>
        </div>
      )}

      {/* Upload error */}
      {uploadError && (
        <div className="max-w-4xl mx-auto mb-2 px-3 py-2 bg-red-900/30 border border-red-700 rounded-lg text-red-400 text-sm flex justify-between items-center">
          <span>{uploadError}</span>
          <button type="button" onClick={() => setUploadError(null)} className="text-red-500 hover:text-red-400">
            <X className="w-4 h-4" />
          </button>
        </div>
      )}

      {/* Attached files preview */}
      {attachedFiles.length > 0 && (
        <div className="max-w-4xl mx-auto mb-3 flex gap-2 flex-wrap">
          {attachedFiles.map((file) => (
            <div
              key={file.id}
              className="relative group bg-dark-800 border border-dark-700 rounded-lg overflow-hidden"
            >
              {file.isImage ? (
                <div className="w-16 h-16 relative">
                  <img
                    src={file.preview}
                    alt={file.name}
                    className="w-full h-full object-cover"
                  />
                  <div className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
                    <button
                      type="button"
                      onClick={() => removeFile(file.id)}
                      className="p-1 bg-red-600 rounded-full text-white hover:bg-red-500"
                    >
                      <X className="w-3 h-3" />
                    </button>
                  </div>
                </div>
              ) : (
                <div className="px-3 py-2 flex items-center gap-2 max-w-48">
                  <FileText className="w-4 h-4 text-dark-400 flex-shrink-0" />
                  <span className="text-dark-300 text-xs truncate">{file.name}</span>
                  <button
                    type="button"
                    onClick={() => removeFile(file.id)}
                    className="p-0.5 text-dark-500 hover:text-red-400 flex-shrink-0"
                  >
                    <X className="w-3 h-3" />
                  </button>
                </div>
              )}
            </div>
          ))}
          {attachedFiles.length < MAX_FILES && (
            <button
              type="button"
              onClick={() => fileInputRef.current?.click()}
              className="w-16 h-16 border border-dashed border-dark-600 rounded-lg flex items-center justify-center text-dark-500 hover:text-dark-400 hover:border-dark-500 transition-colors"
              title="Add more files"
            >
              <Paperclip className="w-5 h-5" />
            </button>
          )}
        </div>
      )}

      <div className="flex gap-3 items-end max-w-4xl mx-auto">
        {/* File input (hidden) */}
        <input
          ref={fileInputRef}
          type="file"
          multiple
          accept={ALLOWED_EXTENSIONS.join(',')}
          onChange={handleFileSelect}
          className="hidden"
        />

        {/* Attach button */}
        <button
          type="button"
          onClick={() => fileInputRef.current?.click()}
          disabled={disabled || attachedFiles.length >= MAX_FILES}
          className={`p-3 rounded-xl transition-all ${
            disabled || attachedFiles.length >= MAX_FILES
              ? 'bg-dark-800 text-dark-600 cursor-not-allowed'
              : 'bg-dark-800 text-dark-400 hover:text-orange-400 hover:bg-dark-700'
          }`}
          title={attachedFiles.length >= MAX_FILES ? `Max ${MAX_FILES} files` : 'Attach files (or paste/drag)'}
        >
          <Paperclip className="w-5 h-5" />
        </button>

        <div className="flex-1 relative">
          {/* Command autocomplete dropdown */}
          {showCommands && (
            <div className="absolute bottom-full left-0 right-0 mb-2 bg-dark-800 border border-dark-700 rounded-lg shadow-xl overflow-hidden z-10">
              {filteredCommands.map((cmd, index) => (
                <button
                  key={cmd.name}
                  type="button"
                  onClick={() => selectCommand(cmd.name)}
                  className={`w-full px-4 py-2.5 flex items-center gap-3 text-left transition-colors
                    ${index === selectedIndex ? 'bg-orange-600/20 text-orange-400' : 'hover:bg-dark-700 text-dark-200'}`}
                >
                  <Command className="w-4 h-4 text-dark-500" />
                  <span className="font-medium">/{cmd.name}</span>
                  <span className="text-dark-500 text-sm">{cmd.description}</span>
                </button>
              ))}
            </div>
          )}

          {/* History search results dropdown */}
          {showHistorySearch && historySearchResults.length > 0 && (
            <div className="absolute bottom-full left-0 right-0 mb-2 bg-dark-800 border border-dark-700 rounded-lg shadow-xl overflow-hidden z-10 max-h-64 overflow-y-auto">
              <div className="px-3 py-2 text-xs text-dark-500 border-b border-dark-700 flex items-center gap-2">
                <History className="w-3 h-3" />
                History search results ({historySearchResults.length})
              </div>
              {historySearchResults.map((item, index) => (
                <button
                  key={index}
                  type="button"
                  onClick={() => selectHistoryItem(item)}
                  className={`w-full px-4 py-2.5 text-left transition-colors text-sm truncate
                    ${index === selectedIndex ? 'bg-orange-600/20 text-orange-400' : 'hover:bg-dark-700 text-dark-200'}`}
                >
                  {item.length > 100 ? item.slice(0, 100) + '...' : item}
                </button>
              ))}
            </div>
          )}

          <textarea
            ref={textareaRef}
            value={message}
            onChange={(e) => {
              setMessage(e.target.value);
              setHistoryIndex(-1); // Reset history navigation on manual edit
            }}
            onKeyDown={handleKeyDown}
            onPaste={handlePaste}
            placeholder={isProcessing ? 'Type to send a follow-up message...' : placeholder}
            disabled={disabled}
            rows={1}
            className={`
              w-full bg-dark-800 border border-dark-700 rounded-xl
              px-4 py-3 pr-12 text-dark-100 placeholder-dark-500
              focus:outline-none focus:border-orange-500/50 focus:ring-1 focus:ring-orange-500/20
              resize-none transition-colors
              ${disabled ? 'opacity-50 cursor-not-allowed' : ''}
            `}
          />
          <div className="absolute right-2 bottom-2 text-xs text-dark-600">
            {isProcessing ? 'ESC to stop' : attachedFiles.length > 0 ? `${attachedFiles.length} file(s)` : message.startsWith('/') ? 'Tab to complete' : '↑↓ history'}
          </div>
        </div>

        {isProcessing ? (
          <button
            type="button"
            onClick={onStop}
            className="p-3 rounded-xl transition-all bg-red-600 hover:bg-red-500 text-white shadow-lg shadow-red-600/20"
            title="Stop generation (ESC)"
          >
            <Square className="w-5 h-5" />
          </button>
        ) : (
          <button
            type="submit"
            disabled={disabled || (!message.trim() && attachedFiles.length === 0)}
            className={`
              p-3 rounded-xl transition-all
              ${disabled || (!message.trim() && attachedFiles.length === 0)
                ? 'bg-dark-800 text-dark-600 cursor-not-allowed'
                : 'bg-orange-600 hover:bg-orange-500 text-white shadow-lg shadow-orange-600/20'
              }
            `}
          >
            <Send className="w-5 h-5" />
          </button>
        )}
      </div>

      <div className="text-center mt-2 text-xs text-dark-600">
        {isProcessing ? 'Generating... Press Enter to send follow-up, ESC to stop' : 'Paste, drag & drop, or click clip to attach files'}
      </div>
    </form>
  );
});
