import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { ChevronDown, ChevronRight, Plus, Wand2 } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { qk } from '@/shared/api/query-keys'
import type { CollectionSuggestionDto } from '@/shared/api/types'
import { useApiError } from '@/shared/lib/use-api-error'
import { Badge } from '@/shared/ui/badge'
import { Button } from '@/shared/ui/button'
import { toast } from '@/shared/ui/toast-store'
import { addShowsFromSuggestion, createCollectionFromSuggestion, suggestCollections } from './api'

/**
 * Что стоит собрать во франшизу. Состав виден целиком до создания — по названиям иногда
 * промахивается, и проверить глазами должно быть проще, чем разбирать потом.
 *
 * Уже созданное по умолчанию скрыто: строка без кнопки — шум. Счётчик скрытого остаётся видимым,
 * чтобы предложение не выглядело пропавшим бесследно.
 */
export function CollectionSuggestions() {
  const { t } = useTranslation()
  const queryClient = useQueryClient()
  const onError = useApiError()
  // Свёрнуто по умолчанию: предложения — подсказка, а не главное на экране, и развёрнутый
  // список из десятка строк отодвигал бы сам справочник за нижний край.
  const [collapsed, setCollapsed] = useState(true)
  const [showExisting, setShowExisting] = useState(false)

  const { data, isLoading } = useQuery({
    queryKey: qk.collections.suggestions,
    queryFn: suggestCollections,
  })

  const invalidate = () => {
    void queryClient.invalidateQueries({ queryKey: qk.collections.all })
    void queryClient.invalidateQueries({ queryKey: qk.collections.suggestions })
    void queryClient.invalidateQueries({ queryKey: qk.shows.all })
  }

  const create = useMutation({
    mutationFn: (suggestion: CollectionSuggestionDto) =>
      createCollectionFromSuggestion(suggestion.key),
    onSuccess: () => {
      toast.success(t('admin.collections.suggestions.created'))
      invalidate()
    },
    onError,
  })

  /** Дополнение уже собранной франшизы: коллекцию сервер находит по тому же ключу предложения. */
  const add = useMutation({
    mutationFn: (suggestion: CollectionSuggestionDto) => addShowsFromSuggestion(suggestion.key),
    onSuccess: (added) => {
      toast.success(t('admin.collections.suggestions.added', { count: added }))
      invalidate()
    },
    onError,
  })

  if (isLoading || !data || data.length === 0) return null

  const fresh = data.filter((s) => !s.alreadyExists)
  const existing = data.length - fresh.length
  const visible = showExisting ? data : fresh

  return (
    <div className="flex flex-col gap-2">
      <button
        type="button"
        className="flex items-center gap-2 self-start text-sm font-semibold uppercase tracking-wide text-muted-foreground hover:text-foreground"
        onClick={() => setCollapsed((v) => !v)}
      >
        {collapsed ? <ChevronRight className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
        <Wand2 className="h-4 w-4" />
        {t('admin.collections.suggestions.title')}
        <Badge variant="muted">{fresh.length}</Badge>
      </button>

      {!collapsed && (
        <>
          <p className="text-xs text-muted-foreground">{t('admin.collections.suggestions.hint')}</p>
          {visible.length === 0 && (
            <p className="text-sm text-muted-foreground">
              {t('admin.collections.suggestions.allCreated')}
            </p>
          )}
          <ul
            className={`crt-panel divide-y divide-border rounded-md text-sm ${
              visible.length === 0 ? 'hidden' : ''
            }`}
          >
            {visible.map((suggestion) => (
              <li key={suggestion.key} className="flex flex-col gap-1 px-4 py-2">
                <div className="flex flex-wrap items-center gap-2">
                  <span className="min-w-0 flex-1 truncate font-medium">{suggestion.name}</span>
                  {/* Дополнение и создание в одном списке: без пометки строки неотличимы, а
                      действия у них разные — одна заводит франшизу, другая правит собранную. */}
                  {suggestion.collectionId && (
                    <Badge variant="muted">
                      {t('admin.collections.suggestions.additionBadge')}
                    </Badge>
                  )}
                  <Badge variant={suggestion.source === 'Metadata' ? 'default' : 'muted'}>
                    {t(`admin.collections.suggestions.sources.${suggestion.source}`)}
                  </Badge>
                  <span className="text-muted-foreground">
                    {t('admin.collections.suggestions.parts', { count: suggestion.parts.length })}
                  </span>
                  {suggestion.collectionId ? (
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={add.isPending}
                      onClick={() => add.mutate(suggestion)}
                    >
                      <Plus className="h-4 w-4" />
                      {t('admin.collections.suggestions.add')}
                    </Button>
                  ) : (
                    <>
                      {suggestion.alreadyExists ? (
                        <Badge variant="muted">{t('admin.collections.suggestions.exists')}</Badge>
                      ) : (
                        <Button
                          size="sm"
                          variant="outline"
                          disabled={create.isPending}
                          onClick={() => create.mutate(suggestion)}
                        >
                          <Plus className="h-4 w-4" />
                          {t('common.create')}
                        </Button>
                      )}
                    </>
                  )}
                </div>
                {/* Состав в предлагаемом порядке: по нему и видно, промахнулась ли догадка.
                    У дополнения это только недостающие части — их и добавит кнопка. */}
                <p className="text-xs text-muted-foreground">
                  {suggestion.parts
                    .map((part) => (part.year ? `${part.name} (${part.year})` : part.name))
                    .join(' → ')}
                </p>
              </li>
            ))}
          </ul>
          {existing > 0 && (
            <button
              type="button"
              className="self-start text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
              onClick={() => setShowExisting((v) => !v)}
            >
              {showExisting
                ? t('admin.collections.suggestions.hideExisting')
                : t('admin.collections.suggestions.showExisting', { count: existing })}
            </button>
          )}
        </>
      )}
    </div>
  )
}
