import { useDeferredValue, useMemo, useState } from 'react'
import { createFileRoute, Link, useNavigate } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import {
  Alert,
  Badge,
  Button,
  EmptyState,
  LoadingBlock,
  PageHeader,
  SearchInput,
} from '@nstart/ui'
import { PlusIcon } from '@phosphor-icons/react'
import { useDictionaries } from '@/api/queries'
import type { DictionaryDefinition } from '@/api/client'
import { DictionaryEditorDialog } from '@/components/schema/DictionaryEditorDialog'

export const Route = createFileRoute('/dictionaries/')({
  component: DictionariesPage,
})

const matchesQuery = (d: DictionaryDefinition, q: string): boolean => {
  if (!q) return true
  const haystack = [d.name, d.displayName ?? '', d.description ?? '']
    .join(' ')
    .toLowerCase()
  return haystack.includes(q)
}

function DictionariesPage() {
  const { t } = useTranslation()
  const navigate = useNavigate()
  const { data, isLoading, error } = useDictionaries()
  const [createOpen, setCreateOpen] = useState(false)
  const [query, setQuery] = useState('')
  const deferredQuery = useDeferredValue(query)

  const filtered = useMemo(() => {
    if (!data) return []
    const q = deferredQuery.trim().toLowerCase()
    return data.filter((d) => matchesQuery(d, q))
  }, [data, deferredQuery])

  const createButton = (
    <Button
      type="button"
      variant="primary"
      leftIcon={<PlusIcon weight="bold" size={16} />}
      onClick={() => setCreateOpen(true)}
    >
      {t('schema.action.create')}
    </Button>
  )

  if (isLoading) {
    return <LoadingBlock size="md" label={t('loading')} />
  }

  if (error) {
    return (
      <Alert variant="error" title={t('error.failed')}>
        {String(error)}
      </Alert>
    )
  }

  if (!data || data.length === 0) {
    return (
      <div className="space-y-6">
        <PageHeader
          title={t('nav.dictionaries')}
          description={t('dict.list.subtitle')}
          actions={createButton}
        />
        <EmptyState title={t('dict.empty')} />
        <DictionaryEditorDialog
          open={createOpen}
          mode={{ kind: 'create' }}
          onClose={() => setCreateOpen(false)}
          onSuccess={(name) => {
            setCreateOpen(false)
            navigate({ to: '/dictionaries/$name', params: { name } })
          }}
        />
      </div>
    )
  }

  return (
    <div className="space-y-6">
      <PageHeader
        title={t('nav.dictionaries')}
        description={t('dict.list.subtitle')}
        actions={createButton}
      />

      <div className="flex flex-col sm:flex-row sm:items-center gap-3">
        <div className="flex-1 max-w-md">
          <SearchInput
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder={t('dict.list.search.placeholder')}
            aria-label={t('dict.list.search.placeholder')}
          />
        </div>
        <span className="text-sm text-carbon/70">
          {t('dict.list.found', { shown: filtered.length, total: data.length })}
        </span>
      </div>

      {filtered.length === 0 ? (
        <EmptyState title={t('dict.list.search.empty')} />
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {filtered.map((d) => (
            <Link
              key={d.id}
              to="/dictionaries/$name"
              params={{ name: d.name }}
              className="block bg-white border border-regolith rounded-lg p-4 transition shadow-card hover:shadow-hover hover:border-ultramarain/40"
            >
              <div className="flex items-start justify-between mb-2 gap-2">
                <h2 className="font-primary text-base text-ultramarain">
                  {d.displayName ?? d.name}
                </h2>
                <Badge variant="info">{d.scope}</Badge>
              </div>
              {d.description && (
                <p className="text-sm text-carbon line-clamp-2 mb-3">{d.description}</p>
              )}
              <div className="flex items-center justify-between gap-2 text-2xs uppercase tracking-label text-carbon/60">
                <div className="flex gap-2 min-w-0">
                  <span className="truncate">v{d.schemaVersion}</span>
                  <span>·</span>
                  <span className="truncate">{d.bundle}</span>
                  <span>·</span>
                  <span className="truncate">{d.supportedLocales.join(', ')}</span>
                </div>
                {typeof d.recordCount === 'number' && (
                  <Badge variant="neutral">
                    {t('dict.list.recordCount', { count: d.recordCount })}
                  </Badge>
                )}
              </div>
            </Link>
          ))}
        </div>
      )}

      <DictionaryEditorDialog
        open={createOpen}
        mode={{ kind: 'create' }}
        onClose={() => setCreateOpen(false)}
        onSuccess={(name) => {
          setCreateOpen(false)
          navigate({ to: '/dictionaries/$name', params: { name } })
        }}
      />
    </div>
  )
}
