import { useEffect, useState, useRef } from 'react'
import type { Article } from '@/types/nostr'
import { objectCache } from '@/lib/objectCache'
import { getSearchHistory } from '@/lib/searchHistory'
import { Card, Button } from './ui'
import { t } from '@/lib/i18n'

interface SearchSuggestionsProps {
  query: string
  onSelect: (query: string) => void
  onClose: () => void
}

interface SuggestionItem {
  type: 'article' | 'author' | 'history'
  title: string
  query: string
  subtitle?: string
  timestamp?: number
}

const loadHistorySuggestions = async (): Promise<SuggestionItem[]> => {
  try {
    const history = await getSearchHistory()
    return history.slice(0, 5).map((item) => ({
      type: 'history' as const,
      title: item.query,
      query: item.query,
      timestamp: item.timestamp,
    }))
  } catch (error) {
    console.error('Error loading search history:', error)
    return []
  }
}

const loadSuggestions = async (searchQuery: string): Promise<SuggestionItem[]> => {
  try {
    const allArticles = (await objectCache.getAll('publication')) as Article[]
    const allAuthors = (await objectCache.getAll('author')) as Article[]
    const queryLower = searchQuery.toLowerCase()

    const articleSuggestions: SuggestionItem[] = allArticles
      .filter((article) => article.title.toLowerCase().includes(queryLower))
      .slice(0, 5)
      .map((article) => ({
        type: 'article' as const,
        title: article.title,
        query: article.title,
        subtitle: article.preview?.substring(0, 60),
      }))

    const authorSuggestions: SuggestionItem[] = allAuthors
      .filter((author) => {
        const name = extractAuthorName(author)
        return name.toLowerCase().includes(queryLower)
      })
      .slice(0, 3)
      .map((author) => ({
        type: 'author' as const,
        title: extractAuthorName(author),
        query: extractAuthorName(author),
        subtitle: author.description?.substring(0, 60),
      }))

    return [...articleSuggestions, ...authorSuggestions].slice(0, 8)
  } catch (error) {
    console.error('Error loading suggestions:', error)
    return []
  }
}

function useSuggestionsLoader(query: string): { suggestions: SuggestionItem[]; loading: boolean } {
  const [suggestions, setSuggestions] = useState<SuggestionItem[]>([])
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    const updateSuggestions = async (): Promise<void> => {
      if (!query.trim()) {
        const historySuggestions = await loadHistorySuggestions()
        setSuggestions(historySuggestions)
        return
      }
      setLoading(true)
      try {
        const loadedSuggestions = await loadSuggestions(query)
        setSuggestions(loadedSuggestions)
      } finally {
        setLoading(false)
      }
    }
    void updateSuggestions()
  }, [query])

  return { suggestions, loading }
}

function useClickOutsideHandler(containerRef: React.RefObject<HTMLDivElement | null>, onClose: () => void): void {
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent): void => {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        onClose()
      }
    }
    document.addEventListener('mousedown', handleClickOutside)
    return () => {
      document.removeEventListener('mousedown', handleClickOutside)
    }
  }, [containerRef, onClose])
}

export function SearchSuggestions({ query, onSelect, onClose }: SearchSuggestionsProps): React.ReactElement | null {
  const containerRef = useRef<HTMLDivElement>(null)
  const { suggestions, loading } = useSuggestionsLoader(query)
  useClickOutsideHandler(containerRef, onClose)

  if (suggestions.length === 0 && !loading) {
    return null
  }

  return (
    <div ref={containerRef} className="absolute top-full left-0 right-0 mt-1 z-50">
      <Card variant="default" className="bg-cyber-dark border-neon-cyan/30 max-h-96 overflow-y-auto">
        {loading && (
          <div className="p-4 text-center text-cyber-accent/70">
            <p>{t('common.loading')}</p>
          </div>
        )}
        {!loading && suggestions.length > 0 && (
          <div className="divide-y divide-neon-cyan/20">
            {suggestions.map((suggestion, index) => (
              <SuggestionItemComponent
                key={`${suggestion.type}-${suggestion.query}-${suggestion.timestamp ?? index}`}
                suggestion={suggestion}
                onSelect={onSelect}
              />
            ))}
          </div>
        )}
      </Card>
    </div>
  )
}

function getSuggestionIcon(type: SuggestionItem['type']): React.ReactElement {
  if (type === 'article') {
    return (
      <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
      </svg>
    )
  }
  if (type === 'author') {
    return (
      <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
      </svg>
    )
  }
  return (
    <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
    </svg>
  )
}

function getSuggestionAriaLabel(type: SuggestionItem['type'], title: string): string {
  if (type === 'article') {
    return `${t('search.suggestion.article')}: ${title}`
  }
  if (type === 'author') {
    return `${t('search.suggestion.author')}: ${title}`
  }
  return `${t('search.suggestion.history')}: ${title}`
}

function SuggestionItemComponent({
  suggestion,
  onSelect,
}: {
  suggestion: SuggestionItem
  onSelect: (query: string) => void
}): React.ReactElement {
  return (
    <Button
      variant="ghost"
      onClick={() => {
        onSelect(suggestion.query)
      }}
      className="w-full justify-start text-left p-3 h-auto"
      aria-label={getSuggestionAriaLabel(suggestion.type, suggestion.title)}
    >
      <div className="flex items-start gap-3 flex-1">
        <div className="text-neon-cyan mt-0.5 flex-shrink-0">{getSuggestionIcon(suggestion.type)}</div>
        <div className="flex-1 min-w-0">
          <div className="text-sm font-medium text-cyber-accent truncate">{suggestion.title}</div>
          {suggestion.subtitle && (
            <div className="text-xs text-cyber-accent/70 mt-1 truncate">{suggestion.subtitle}</div>
          )}
        </div>
      </div>
    </Button>
  )
}

function extractAuthorName(author: Article): string {
  if (author.isPresentation) {
    return author.title
  }
  return author.title
}
