import { useState } from 'react'
import { fetchAPI, postAPI } from '../api/client'
import { useToast } from '../components/Toast'
import ErrorBanner from '../components/ErrorBanner'

interface SemanticResult {
  id: number
  title: string
  media_type: string
  year: number | null
  score: number
  overview: string
}

function scorePercent(score: number): string {
  return `${Math.round(score * 100)}%`
}

function mediaTypeBadge(type: string): string {
  const colors: Record<string, string> = {
    movie: 'bg-blue-600',
    series: 'bg-green-600',
    music: 'bg-purple-600',
    book: 'bg-orange-600',
    audiobook: 'bg-yellow-600',
    podcast: 'bg-pink-600',
  }
  return colors[type] ?? 'bg-gray-600'
}

export default function SemanticSearch() {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState<SemanticResult[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [hasSearched, setHasSearched] = useState(false)
  const [addingToQueue, setAddingToQueue] = useState<Set<number>>(new Set())
  const { showToast } = useToast()

  async function doSearch() {
    const trimmed = query.trim()
    if (!trimmed) return
    setLoading(true)
    setHasSearched(true)
    setError(null)
    try {
      const res = await fetchAPI<{ results: SemanticResult[] }>(
        '/api/search/semantic?q=' + encodeURIComponent(trimmed) + '&k=5'
      )
      setResults(res.results ?? [])
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Semantic search failed'
      setError(message)
    } finally {
      setLoading(false)
    }
  }

  function handleSearchSubmit(e: React.FormEvent) {
    e.preventDefault()
    doSearch()
  }

  async function handleAddToQueue(item: SemanticResult) {
    setAddingToQueue(prev => new Set(prev).add(item.id))
    try {
      await postAPI<{ id: number }>('/api/queue', { media_id: item.id })
      showToast(`Added "${item.title}" to queue`)
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Failed to add to queue'
      showToast(`Error: ${message}`)
    } finally {
      setAddingToQueue(prev => {
        const next = new Set(prev)
        next.delete(item.id)
        return next
      })
    }
  }

  return (
    <div>
      <h2 className="text-2xl font-semibold text-gray-100 mb-6">Semantic Search</h2>

      <form onSubmit={handleSearchSubmit} className="mb-6">
        <div className="flex gap-3 max-w-2xl">
          <input
            type="text"
            value={query}
            onChange={e => setQuery(e.target.value)}
            placeholder="Describe what you're looking for..."
            className="bg-gray-800 border border-gray-700 focus:border-indigo-500 text-white rounded-lg px-4 py-3 w-full outline-none transition-colors"
          />
          <button
            type="submit"
            disabled={loading || !query.trim()}
            className="bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed text-white px-6 py-3 rounded-lg font-semibold transition-colors"
          >
            {loading ? 'Searching...' : 'Search'}
          </button>
        </div>
        <p className="text-gray-500 text-xs mt-2">AI-powered search using natural language descriptions</p>
      </form>

      {!hasSearched && (
        <div className="text-center py-20 text-gray-500">
          <p className="text-lg">Enter a natural language query to find media</p>
        </div>
      )}

      {hasSearched && loading && (
        <div className="animate-pulse space-y-4">
          {[1, 2, 3].map(i => (
            <div key={i} className="h-24 bg-gray-800 rounded-lg" />
          ))}
        </div>
      )}

      {hasSearched && error && !loading && <ErrorBanner error={error} onRetry={doSearch} />}

      {hasSearched && !loading && !error && results.length === 0 && (
        <div className="text-gray-500 text-center py-12">No results found</div>
      )}

      {hasSearched && !loading && !error && results.length > 0 && (
        <div className="space-y-3">
          <p className="text-gray-400 text-sm mb-3">{results.length} result{results.length !== 1 ? 's' : ''}</p>
          {results.map(item => {
            const isAdding = addingToQueue.has(item.id)
            return (
              <div key={item.id} className="bg-gray-900 border border-gray-800 rounded-lg p-4 hover:border-gray-700 transition-colors">
                <div className="flex items-start justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 mb-1">
                      <span className={`${mediaTypeBadge(item.media_type)} text-white text-xs font-semibold px-2 py-0.5 rounded`}>
                        {item.media_type}
                      </span>
                      <h3 className="text-gray-100 font-medium truncate">{item.title}</h3>
                      {item.year && <span className="text-gray-500 text-sm">{item.year}</span>}
                    </div>
                    <div className="flex items-center gap-3 mb-2">
                      <span className="text-indigo-400 text-sm font-medium">{scorePercent(item.score)} match</span>
                    </div>
                    {item.overview && (
                      <p className="text-gray-400 text-sm line-clamp-2">{item.overview}</p>
                    )}
                  </div>
                  <button
                    disabled={isAdding}
                    onClick={() => handleAddToQueue(item)}
                    className="px-3 py-1.5 text-xs font-semibold rounded bg-indigo-600 hover:bg-indigo-500 text-white disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap transition-colors"
                  >
                    {isAdding ? 'Adding...' : 'Add to Queue'}
                  </button>
                </div>
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}
