import { useState } from 'react'
import { createFileRoute, Link, useNavigate } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import {
  Badge,
  EmptyState,
  LoadingBlock,
  PageHeader,
  Panel,
  QueryErrorState,
  SearchInput,
} from '@/ui'
import { useSearch } from '@/api/queries'

type SearchSearch = { q?: string }

const validateSearch = (raw: Record<string, unknown>): SearchSearch => {
  if (typeof raw.q === 'string' && raw.q.length > 0) return { q: raw.q }
  return {}
}

export const Route = createFileRoute('/search')({
  component: SearchPage,
  validateSearch,
})

/**
 * Smart JSONB search across all dictionaries (CEO plan v1 stretch).
 *
 * <p>Backend: GET /api/v1/search?q=&size&perDict — ILIKE с trigram-индексом
 * на dictionary_records.data::text. Min query length = 3 (trigram threshold).
 *
 * <p>UI: search input → grouped results per dict с per-row link на full
 * record. URL state ?q=… — share-friendly.
 */
function SearchPage() {
  const { t } = useTranslation()
  const urlSearch = Route.useSearch()
  const navigate = useNavigate({ from: Route.fullPath })
  const [input, setInput] = useState(urlSearch.q ?? '')

  const result = useSearch(urlSearch.q)

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    const trimmed = input.trim()
    void navigate({ search: trimmed ? { q: trimmed } : {}, replace: true })
  }

  const tooShort = input.length > 0 && input.length < 3
  const hasQuery = Boolean(urlSearch.q && urlSearch.q.length >= 3)

  return (
    <div className="space-y-4">
      <PageHeader
        title={t('search.title')}
        description={t('search.description')}
      />

      <form onSubmit={handleSubmit} className="flex gap-2">
        <div className="flex-1 max-w-2xl">
          <SearchInput
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder={t('search.placeholder')}
            aria-label={t('search.placeholder')}
            autoFocus
          />
        </div>
      </form>

      {tooShort && (
        <p className="text-cell text-mute">{t('search.tooShort')}</p>
      )}

      {hasQuery && result.isLoading && (
        <LoadingBlock size="md" label={t('loading')} />
      )}

      {hasQuery && result.error && (
        <QueryErrorState error={result.error} onRetry={() => result.refetch()} />
      )}

      {hasQuery && result.data && result.data.total === 0 && (
        <EmptyState title={t('search.empty')} />
      )}

      {hasQuery && result.data && result.data.total > 0 && (
        <>
          <p className="text-cell text-mute">
            {t('search.totalHits', { count: result.data.total })}
          </p>
          <div className="space-y-3">
            {result.data.groups.map((g) => (
              <Panel key={g.dictName}>
                <div className="flex items-center justify-between mb-2">
                  <Link
                    to="/dictionaries/$name"
                    params={{ name: g.dictName }}
                    search={{ q: urlSearch.q }}
                    className="text-body font-sans text-accent hover:underline"
                  >
                    {g.dictDisplayName ?? g.dictName}
                  </Link>
                  <Badge variant="neutral">{g.count}</Badge>
                </div>
                <ul className="divide-y divide-regolith">
                  {g.items.map((it) => (
                    <li
                      key={`${g.dictName}-${it.businessKey}`}
                      className="flex items-center justify-between gap-3 py-2 text-cell"
                    >
                      <Link
                        to="/dictionaries/$name"
                        params={{ name: g.dictName }}
                        search={{ q: it.businessKey }}
                        className="font-mono text-accent hover:underline truncate"
                      >
                        {it.businessKey}
                      </Link>
                      <div className="flex items-center gap-2 shrink-0">
                        <Badge variant="neutral">{it.dataScope}</Badge>
                        <span className="text-mute">
                          {new Date(it.createdAt).toLocaleString()}
                        </span>
                      </div>
                    </li>
                  ))}
                </ul>
              </Panel>
            ))}
          </div>
        </>
      )}

      {!hasQuery && !tooShort && (
        <p className="text-cell text-mute">{t('search.intro')}</p>
      )}
    </div>
  )
}
