import React, { useState } from 'react';
import { Box, Text, useInput } from 'ink';
import Spinner from 'ink-spinner';
import { SearchForm } from './SearchForm.js';
import { ResultsTable } from './ResultsTable.js';
import { searchLibGen } from '../search';
import { SearchResult } from '../types.js';

interface SearchScreenProps {
  onBack: () => void;
}

type ScreenState = 'form' | 'searching' | 'results';

export const SearchScreen: React.FC<SearchScreenProps> = ({ onBack }) => {
  const [screenState, setScreenState] = useState<ScreenState>('form');
  const [results, setResults] = useState<SearchResult[]>([]);
  const [searchQuery, setSearchQuery] = useState('');
  const [lastSearchAuthor, setLastSearchAuthor] = useState('');
  const [lastSearchTitle, setLastSearchTitle] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [abortController, setAbortController] = useState<AbortController | null>(null);

  useInput((input, key) => {
    if (key.escape && screenState === 'form') {
      onBack();
    }
  });

  const handleSearch = async (author: string, title: string) => {
    // Store the search parameters for potential reuse
    setLastSearchAuthor(author);
    setLastSearchTitle(title);
    
    setIsLoading(true);
    setScreenState('searching');
    
    // Create new AbortController for this search
    const controller = new AbortController();
    setAbortController(controller);
    
    // Build search query
    let query = '';
    if (author && title) {
      query = `${author} ${title}`;
    } else if (author) {
      query = author;
    } else if (title) {
      query = title;
    }
    
    setSearchQuery(query);
    
    try {
      const searchResults = await searchLibGen(query, {
        maxResults: 50,
        topics: ['l', 'f'], // libgen + fiction
        objects: ['f', 'e'], // files + editions
        language: 'eng' // English by default
      }, controller.signal);
      
      setResults(searchResults);
      setScreenState('results');
    } catch (error: unknown) {
      if (error instanceof Error && (error.name === 'AbortError' || error.name === 'CanceledError')) {
        console.log('Search cancelled');
        setScreenState('form');
      } else {
        console.error('Search error:', error);
        setResults([]);
        setScreenState('results');
      }
    } finally {
      setIsLoading(false);
      setAbortController(null);
    }
  };

  const handleBackToForm = () => {
    setScreenState('form');
    setResults([]);
    setSearchQuery('');
    // Note: We intentionally keep lastSearchAuthor and lastSearchTitle
    // so they can be passed to SearchForm as initial values
  };

  const handleCancel = () => {
    if (screenState === 'searching') {
      // Cancel the ongoing search request
      if (abortController) {
        abortController.abort();
      }
      setScreenState('form');
      setIsLoading(false);
      setAbortController(null);
    } else {
      onBack();
    }
  };

  if (screenState === 'searching') {
    return (
      <Box flexDirection="column" alignItems="center" justifyContent="center" padding={2}>
        <Box marginBottom={2}>
          <Text color="blue">
            <Spinner type="dots" />
            {' '}Searching for: {searchQuery}
          </Text>
        </Box>
        <Text color="gray">
          This may take a moment...
        </Text>
        <Box marginTop={2}>
          <Text color="gray">
            Press [Esc] to cancel
          </Text>
        </Box>
      </Box>
    );
  }

  if (screenState === 'results') {
    return (
      <ResultsTable
        results={results}
        onBack={handleBackToForm}
      />
    );
  }

  return (
    <SearchForm
      onSubmit={handleSearch}
      onCancel={handleCancel}
      initialAuthor={lastSearchAuthor}
      initialTitle={lastSearchTitle}
    />
  );
}; 