import React, { useState, useEffect, useCallback } from 'react';
import { Box, Text, useInput } from 'ink';
import TextInput from 'ink-text-input';
import fs from 'fs';
import path from 'path';
import os from 'os';

interface FilePickerProps {
  onSubmit: (filePath: string) => void;
  onCancel: () => void;
  placeholder?: string;
  title?: string;
  fileFilter?: (filename: string) => boolean;
}

export const FilePicker: React.FC<FilePickerProps> = ({
  onSubmit,
  onCancel,
  placeholder = "Enter file path...",
  title = "Select File",
  fileFilter = (filename) => filename.endsWith('.csv')
}) => {
  const [inputValue, setInputValue] = useState('');
  const [completions, setCompletions] = useState<string[]>([]);
  const [currentCompletionIndex, setCurrentCompletionIndex] = useState(0);
  const [showCompletions, setShowCompletions] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');

  // Expand home directory and resolve relative paths
  const expandPath = useCallback((inputPath: string): string => {
    if (inputPath.startsWith('~/')) {
      return path.join(os.homedir(), inputPath.slice(2));
    }
    if (inputPath.startsWith('~')) {
      return path.join(os.homedir(), inputPath.slice(1));
    }
    return path.resolve(inputPath);
  }, []);

  // Get directory contents for tab completion
  const getCompletions = useCallback((inputPath: string): string[] => {
    try {
      const expandedPath = expandPath(inputPath);
      const dir = path.dirname(expandedPath);
      const basename = path.basename(expandedPath);
      
      // Check if directory exists
      if (!fs.existsSync(dir)) {
        return [];
      }

      const entries = fs.readdirSync(dir);
      const completions: string[] = [];

      for (const entry of entries) {
        const fullPath = path.join(dir, entry);
        const stat = fs.lstatSync(fullPath);
        
        // Skip hidden files unless explicitly typed
        if (entry.startsWith('.') && !basename.startsWith('.')) {
          continue;
        }

        // For directories, add trailing slash
        if (stat.isDirectory()) {
          if (entry.startsWith(basename)) {
            completions.push(entry + '/');
          }
        } else {
          // For files, check if it matches the filter
          if (entry.startsWith(basename) && fileFilter(entry)) {
            completions.push(entry);
          }
        }
      }

      return completions.sort();
    } catch (error) {
      return [];
    }
  }, [expandPath, fileFilter]);

  // Handle tab completion
  const handleTabCompletion = useCallback(() => {
    if (inputValue.trim() === '') {
      // If empty input, show current directory contents
      const completions = getCompletions('./');
      setCompletions(completions);
      setCurrentCompletionIndex(0);
      setShowCompletions(completions.length > 0);
      return;
    }

    const completions = getCompletions(inputValue);
    
    if (completions.length === 0) {
      setShowCompletions(false);
      return;
    }

    if (completions.length === 1) {
      // Single completion - auto-complete
      const expandedPath = expandPath(inputValue);
      const dir = path.dirname(expandedPath);
      const newPath = path.join(dir, completions[0]);
      
      // Convert back to relative path if it was relative
      let finalPath = newPath;
      if (inputValue.startsWith('~/')) {
        finalPath = '~/' + path.relative(os.homedir(), newPath);
      } else if (!path.isAbsolute(inputValue)) {
        finalPath = path.relative(process.cwd(), newPath);
      }
      
      setInputValue(finalPath);
      setShowCompletions(false);
      setErrorMessage('');
    } else {
      // Multiple completions - show list
      setCompletions(completions);
      setCurrentCompletionIndex(0);
      setShowCompletions(true);
    }
  }, [inputValue, getCompletions, expandPath]);

  // Handle completion selection
  const selectCompletion = useCallback((index: number) => {
    const completion = completions[index];
    if (!completion) return;

    const expandedPath = expandPath(inputValue);
    const dir = path.dirname(expandedPath);
    const newPath = path.join(dir, completion);
    
    // Convert back to relative path if it was relative
    let finalPath = newPath;
    if (inputValue.startsWith('~/')) {
      finalPath = '~/' + path.relative(os.homedir(), newPath);
    } else if (!path.isAbsolute(inputValue)) {
      finalPath = path.relative(process.cwd(), newPath);
    }
    
    setInputValue(finalPath);
    setShowCompletions(false);
    setErrorMessage('');
  }, [inputValue, completions, expandPath]);

  // Handle input changes
  const handleInputChange = useCallback((value: string) => {
    setInputValue(value);
    setShowCompletions(false);
    setErrorMessage('');
  }, []);

  // Handle file submission
  const handleSubmit = useCallback(() => {
    if (!inputValue.trim()) {
      setErrorMessage('Please enter a file path');
      return;
    }

    const expandedPath = expandPath(inputValue);
    
    // Check if file exists
    if (!fs.existsSync(expandedPath)) {
      setErrorMessage('File does not exist');
      return;
    }

    // Check if it's a file (not directory)
    const stat = fs.lstatSync(expandedPath);
    if (!stat.isFile()) {
      setErrorMessage('Path is not a file');
      return;
    }

    // Check if file matches filter
    if (!fileFilter(path.basename(expandedPath))) {
      setErrorMessage('File does not match required format');
      return;
    }

    onSubmit(expandedPath);
  }, [inputValue, expandPath, fileFilter, onSubmit]);

  // Handle keyboard input
  useInput((input, key) => {
    if (key.tab) {
      handleTabCompletion();
    } else if (key.escape) {
      if (showCompletions) {
        setShowCompletions(false);
      } else {
        onCancel();
      }
    } else if (key.upArrow && showCompletions) {
      setCurrentCompletionIndex(Math.max(0, currentCompletionIndex - 1));
    } else if (key.downArrow && showCompletions) {
      setCurrentCompletionIndex(Math.min(completions.length - 1, currentCompletionIndex + 1));
    } else if (key.return && showCompletions) {
      selectCompletion(currentCompletionIndex);
    }
  });

  return (
    <Box flexDirection="column" padding={2}>
      <Box marginBottom={2}>
        <Text bold color="blue">
          {title}
        </Text>
      </Box>
      
      <Box marginBottom={1}>
        <Text color="gray">
          Enter file path. Use Tab for completion, arrows to navigate, Enter to select.
        </Text>
      </Box>
      
      <Box flexDirection="column" marginBottom={1}>
        <Box marginBottom={1}>
          <Text color="cyan">
            File Path:
          </Text>
        </Box>
        <Box>
          <TextInput
            value={inputValue}
            onChange={handleInputChange}
            onSubmit={handleSubmit}
            placeholder={placeholder}
          />
        </Box>
      </Box>

      {errorMessage && (
        <Box marginBottom={1}>
          <Text color="red">
            Error: {errorMessage}
          </Text>
        </Box>
      )}

      {showCompletions && completions.length > 0 && (
        <Box flexDirection="column" marginBottom={1}>
          <Text color="gray">
            Completions:
          </Text>
          <Box flexDirection="column" paddingLeft={2}>
            {completions.slice(0, 10).map((completion, index) => (
              <Text
                key={completion}
                color={index === currentCompletionIndex ? 'cyan' : 'gray'}
                bold={index === currentCompletionIndex}
              >
                {index === currentCompletionIndex ? '> ' : '  '}
                {completion}
              </Text>
            ))}
            {completions.length > 10 && (
              <Text color="gray">
                ... and {completions.length - 10} more
              </Text>
            )}
          </Box>
        </Box>
      )}
      
      <Box flexDirection="column" gap={1}>
        <Box flexDirection="row" gap={2}>
          <Text color="gray">
            [Tab] Complete
          </Text>
          <Text color="gray">
            [↑↓] Navigate
          </Text>
          <Text color="gray">
            [Enter] Select
          </Text>
          <Text color="gray">
            [Esc] Cancel
          </Text>
        </Box>
        <Box>
          <Text color="gray">
            Supports ~/home-folder paths and tab completion
          </Text>
        </Box>
      </Box>
    </Box>
  );
}; 