import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Layers, Sparkles, Tags } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { listGenres } from '@/features/admin/genres/api'
import { qk } from '@/shared/api/query-keys'
import { AUDIENCE_UNSET, SHOW_AUDIENCES, type ShowAudience } from '@/shared/api/types'
import { useApiError } from '@/shared/lib/use-api-error'
import { Button } from '@/shared/ui/button'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/shared/ui/select'
import { toast } from '@/shared/ui/toast-store'
import { bulkEnrichShows, bulkTagShows, getMetadataProviders } from './api'
import { AddToCollectionDialog } from './AddToCollectionDialog'

/** Значение «не трогать рейтинг» в селекте — отдельное от «снять рейтинг» (AUDIENCE_UNSET). */
const KEEP = 'keep'

/**
 * Массовые действия над отмеченными шоу. Появляется, только когда что-то отмечено, — в обычном
 * просмотре списка не мешает.
 *
 * Жанры дописываются, а не заменяют: у шоу уже есть жанры из метаданных, и разметка «это ещё и
 * детское» не должна их стирать. Замену при необходимости делают на карточке шоу.
 */
export function BulkTagBar({
  showIds,
  onDone,
}: Readonly<{ showIds: string[]; onDone: () => void }>) {
  const { t } = useTranslation()
  const queryClient = useQueryClient()
  const onError = useApiError()
  const [genreId, setGenreId] = useState('')
  const [audience, setAudience] = useState<string>(KEEP)
  const [collectionOpen, setCollectionOpen] = useState(false)

  const { data: genres } = useQuery({ queryKey: qk.genres.all, queryFn: listGenres })
  const { data: providers } = useQuery({
    queryKey: qk.metadata.providers,
    queryFn: getMetadataProviders,
  })

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

  const tag = useMutation({
    mutationFn: () =>
      bulkTagShows({
        showIds,
        genreIds: genreId ? [genreId] : undefined,
        audience: audience === AUDIENCE_UNSET ? null : (audience as ShowAudience),
        setAudience: audience !== KEEP,
      }),
    onSuccess: (result) => {
      toast.success(t('admin.shows.bulk.tagged', { count: result.updated }))
      setGenreId('')
      setAudience(KEEP)
      invalidate()
    },
    onError,
  })

  const enrich = useMutation({
    mutationFn: () => bulkEnrichShows(showIds, providers?.[0] ?? ''),
    onSuccess: (result) => {
      toast.success(t('admin.shows.bulk.enriched', { count: result.applied }))
      // Пропущенное показываем по одному: у каждого своя причина, и это подсказка, что делать руками.
      for (const skip of result.skipped.slice(0, 5)) toast.error(`${skip.showName}: ${skip.reason}`)
      if (result.skipped.length > 5)
        toast.error(t('admin.shows.bulk.moreSkipped', { count: result.skipped.length - 5 }))
      invalidate()
    },
    onError,
  })

  const nothingToApply = !genreId && audience === KEEP

  return (
    <div className="crt-panel flex flex-wrap items-center gap-2 rounded-md px-3 py-2 text-sm">
      <span className="font-medium">
        {t('admin.shows.bulk.selected', { count: showIds.length })}
      </span>

      <Select value={genreId || 'none'} onValueChange={(v) => setGenreId(v === 'none' ? '' : v)}>
        <SelectTrigger className="h-8 w-48">
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="none">{t('admin.shows.bulk.noGenre')}</SelectItem>
          {(genres ?? []).map((genre) => (
            <SelectItem key={genre.id} value={genre.id}>
              {genre.name}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>

      <Select value={audience} onValueChange={setAudience}>
        <SelectTrigger className="h-8 w-64 whitespace-nowrap">
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value={KEEP}>{t('admin.shows.bulk.keepAudience')}</SelectItem>
          <SelectItem value={AUDIENCE_UNSET}>{t('admin.shows.audienceUnset')}</SelectItem>
          {SHOW_AUDIENCES.map((value) => (
            <SelectItem key={value} value={value}>
              {t(`admin.shows.audiences.${value}`)}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>

      <Button size="sm" disabled={nothingToApply || tag.isPending} onClick={() => tag.mutate()}>
        <Tags className="h-4 w-4" />
        {t('admin.shows.bulk.apply')}
      </Button>

      {providers && providers.length > 0 && (
        <Button
          size="sm"
          variant="outline"
          disabled={enrich.isPending}
          title={t('admin.shows.bulk.enrichHint')}
          onClick={() => enrich.mutate()}
        >
          <Sparkles className="h-4 w-4" />
          {enrich.isPending
            ? t('admin.shows.bulk.enriching')
            : t('admin.shows.bulk.enrich', { provider: providers[0].toUpperCase() })}
        </Button>
      )}

      <Button size="sm" variant="outline" onClick={() => setCollectionOpen(true)}>
        <Layers className="h-4 w-4" />
        {t('admin.shows.bulk.toCollection')}
      </Button>

      <Button size="sm" variant="ghost" onClick={onDone}>
        {t('admin.shows.bulk.clear')}
      </Button>

      {collectionOpen && (
        <AddToCollectionDialog
          showIds={showIds}
          onClose={() => setCollectionOpen(false)}
          onAdded={invalidate}
        />
      )}
    </div>
  )
}
