import { useEffect, useRef, useState } from 'react'
import { api, splitSnippet, type SearchResult } from '../../api/client'

interface Props {
  // Called when a result is chosen — opens that document.
  onSelect: (id: string) => void
}

const DEBOUNCE_MS = 220

// SearchBox is the cross-document finder at the top of the sidebar. Typing
// debounces a full-text query; results drop in below with a highlighted snippet.
// Clearing (× or empty) returns the sidebar to the normal document list.
export function SearchBox({ onSelect }: Props) {
  const [q, setQ] = useState('')
  const [results, setResults] = useState<SearchResult[] | null>(null)
  const [busy, setBusy] = useState(false)
  const runRef = useRef(0)
  const debounceRef = useRef<ReturnType<typeof setTimeout>>(undefined)

  useEffect(() => {
    clearTimeout(debounceRef.current)
    const term = q.trim()
    if (!term) {
      setResults(null)
      setBusy(false)
      return
    }
    setBusy(true)
    const run = ++runRef.current
    debounceRef.current = setTimeout(async () => {
      try {
        const hits = await api.search(term)
        if (run === runRef.current) setResults(hits)
      } catch (err) {
        console.error('search failed', err)
        if (run === runRef.current) setResults([])
      } finally {
        if (run === runRef.current) setBusy(false)
      }
    }, DEBOUNCE_MS)
    return () => clearTimeout(debounceRef.current)
  }, [q])

  const clear = () => {
    setQ('')
    setResults(null)
  }

  return (
    <div className="flex flex-col gap-1.5">
      <div className="relative">
        <span
          aria-hidden
          className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm"
          style={{ color: 'var(--color-muted)' }}
        >
          🔍
        </span>
        <input
          value={q}
          onChange={(e) => setQ(e.target.value)}
          placeholder="搜索 · Search"
          aria-label="Search documents"
          className="petal-tap w-full bg-transparent pl-9 pr-8 text-sm focus:outline-none"
          style={{
            height: 40,
            borderRadius: 'var(--radius-pill)',
            border: '1px solid var(--color-border)',
            background: 'var(--color-surface)',
            color: 'var(--color-plum)',
          }}
        />
        {q && (
          <button
            type="button"
            aria-label="Clear search"
            onClick={clear}
            className="absolute right-2 top-1/2 flex h-6 w-6 -translate-y-1/2 items-center justify-center"
            style={{ borderRadius: 'var(--radius-pill)', color: 'var(--color-muted)' }}
          >
            ×
          </button>
        )}
      </div>

      {results !== null && (
        <div className="petal-search-results flex flex-col gap-0.5">
          {busy && results.length === 0 ? (
            <p className="px-2 py-3 text-center text-xs" style={{ color: 'var(--color-muted)' }}>
              查找中… · Searching…
            </p>
          ) : results.length === 0 ? (
            <p className="px-2 py-3 text-center text-xs" style={{ color: 'var(--color-muted)' }}>
              没有找到 · No matches
            </p>
          ) : (
            results.map((r) => (
              <button
                key={r.id}
                type="button"
                onClick={() => onSelect(r.id)}
                className="petal-tap flex flex-col items-start gap-0.5 px-3 py-2 text-left"
                style={{ borderRadius: 'var(--radius-card)' }}
                onMouseEnter={(e) => (e.currentTarget.style.background = 'var(--color-surface-alt)')}
                onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}
              >
                <span
                  className="w-full truncate text-sm font-bold"
                  style={{ color: 'var(--color-plum)' }}
                >
                  {r.title || 'Untitled'}
                </span>
                {r.snippet && (
                  <span
                    className="line-clamp-2 text-xs"
                    style={{ color: 'var(--color-muted)', lineHeight: 1.4 }}
                  >
                    {splitSnippet(r.snippet).map((seg, i) =>
                      seg.hit ? (
                        <mark
                          key={i}
                          style={{
                            background: 'color-mix(in srgb, var(--color-accent) 35%, white)',
                            color: 'var(--color-plum)',
                            borderRadius: 3,
                            padding: '0 1px',
                          }}
                        >
                          {seg.text}
                        </mark>
                      ) : (
                        <span key={i}>{seg.text}</span>
                      ),
                    )}
                  </span>
                )}
              </button>
            ))
          )}
        </div>
      )}
    </div>
  )
}
