import { useMutation, useQuery } from '@tanstack/react-query'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { HttpError } from '@/shared/api/client'
import type { MetadataCandidate, ShowDto } from '@/shared/api/types'
import { Button } from '@/shared/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/shared/ui/card'
import { Input } from '@/shared/ui/input'
import { Label } from '@/shared/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/shared/ui/select'
import { toast } from '@/shared/ui/toast-store'
import { imageUrl } from '@/features/admin/images/api'
import { ImageGallery } from '@/features/admin/images/ImageGallery'
import {
  applyMetadata,
  clearMetadata,
  getMetadataProviders,
  refreshEpisodesMetadata,
  renameShow,
  searchMetadata,
  setShowOriginalName,
  setShowPoster,
  updateMetadata,
} from './api'

export function ShowMetadataCard({ show, onChanged }: { show: ShowDto; onChanged: () => void }) {
  const { t } = useTranslation()
  const [galleryOpen, setGalleryOpen] = useState(false)
  const [provider, setProvider] = useState('')
  const [name, setName] = useState(show.name)
  const [originalName, setOriginalName] = useState(show.originalName ?? '')
  const [results, setResults] = useState<MetadataCandidate[]>([])
  const [searched, setSearched] = useState(false)
  const [description, setDescription] = useState(show.description ?? '')
  const [year, setYear] = useState(show.year != null ? String(show.year) : '')

  const { data: providers } = useQuery({
    queryKey: ['admin', 'metadata', 'providers'],
    queryFn: getMetadataProviders,
  })

  const onError = (error: unknown) =>
    toast.error(error instanceof HttpError ? error.detail : t('common.error'))
  const changed = () => onChanged()

  const setPoster = useMutation({
    mutationFn: (imageId: string) => setShowPoster(show.id, imageId),
    onSuccess: () => {
      toast.success(t('settings.saved'))
      changed()
    },
    onError,
  })

  const effectiveProvider = provider || providers?.[0] || ''
  // Метаданные ищем по оригинальному названию (иначе — по обычному).
  const searchTerm = originalName.trim() || name.trim()

  const search = useMutation({
    mutationFn: () => searchMetadata(effectiveProvider, searchTerm),
    onSuccess: (data) => {
      setResults(data)
      setSearched(true)
    },
    onError,
  })
  const apply = useMutation({
    mutationFn: (externalId: string) => applyMetadata(show.id, effectiveProvider, externalId),
    onSuccess: () => {
      setResults([])
      setSearched(false)
      toast.success(t('admin.metadata.applied'))
      changed()
    },
    onError,
  })
  // Одна кнопка «Сохранить»: пишем только изменённое. Оригинальное название идёт своим эндпоинтом
  // (не трогает привязку к источнику), описание/год — ручной правкой метаданных.
  const save = useMutation({
    mutationFn: async () => {
      const yearNum = year.trim() ? Number(year) : null
      const infoChanged =
        (description.trim() || null) !== (show.description ?? null) || yearNum !== (show.year ?? null)
      if (name.trim() && name.trim() !== show.name) await renameShow(show.id, name.trim())
      if (originalName.trim() !== (show.originalName ?? ''))
        await setShowOriginalName(show.id, originalName.trim() || null)
      if (infoChanged)
        await updateMetadata(show.id, { description: description.trim() || null, year: yearNum })
    },
    onSuccess: () => {
      toast.success(t('settings.saved'))
      changed()
    },
    onError,
  })
  const clear = useMutation({
    mutationFn: () => clearMetadata(show.id),
    onSuccess: () => {
      setDescription('')
      setYear('')
      changed()
    },
    onError,
  })
  const refreshEpisodes = useMutation({
    mutationFn: () => refreshEpisodesMetadata(show.id),
    onSuccess: (count) => {
      toast.success(t('admin.metadata.refreshedCount', { count }))
      onChanged()
    },
    onError,
  })

  const linked =
    !!show.metadataExternalId && !!show.metadataProvider && show.metadataProvider !== 'manual'

  return (
    <Card>
      <CardHeader>
        <CardTitle>{t('admin.metadata.title')}</CardTitle>
      </CardHeader>
      <CardContent className="flex flex-col gap-4 sm:flex-row">
        {/* Постер */}
        <div className="flex w-40 shrink-0 flex-col gap-2">
          <div className="flex aspect-[2/3] items-center justify-center overflow-hidden rounded-md border border-border bg-muted/30">
            {show.posterImageId ? (
              <img
                src={imageUrl(show.posterImageId)}
                alt=""
                className="h-full w-full object-cover"
              />
            ) : (
              <span className="text-xs text-muted-foreground">{t('admin.metadata.noPoster')}</span>
            )}
          </div>
          <Button size="sm" variant="outline" onClick={() => setGalleryOpen(true)}>
            {t('admin.metadata.pickPoster')}
          </Button>
          <ImageGallery
            open={galleryOpen}
            onOpenChange={setGalleryOpen}
            category="ShowPoster"
            onSelect={(img) => setPoster.mutate(img.id)}
          />
        </div>

        {/* Название + поиск + ручная правка */}
        <div className="flex min-w-0 flex-1 flex-col gap-4">
          <div className="flex flex-col gap-1.5">
            <Label>{t('admin.metadata.name')}</Label>
            <Input value={name} maxLength={256} onChange={(e) => setName(e.target.value)} />
          </div>

          <div className="flex flex-col gap-1.5">
            <Label>{t('admin.metadata.originalName')}</Label>
            <Input
              value={originalName}
              maxLength={256}
              placeholder={t('admin.metadata.originalNamePlaceholder')}
              onChange={(e) => {
                setOriginalName(e.target.value)
                setSearched(false)
              }}
            />
            <p className="text-xs text-muted-foreground">{t('admin.metadata.originalNameHint')}</p>
          </div>

          {providers && providers.length > 0 && (searched || results.length > 0) && (
            <div className="flex flex-col gap-2">
              {searched && results.length === 0 && (
                <p className="text-xs text-muted-foreground">{t('admin.metadata.nothingFound')}</p>
              )}

              {results.length > 0 && (
                <ul className="crt-panel max-h-72 divide-y divide-border overflow-y-auto rounded-md">
                  {results.map((r) => (
                    <li key={r.externalId} className="flex items-start gap-3 p-2">
                      {r.posterUrl ? (
                        <img src={r.posterUrl} alt="" className="h-16 w-11 shrink-0 rounded object-cover" />
                      ) : (
                        <div className="h-16 w-11 shrink-0 rounded bg-muted/40" />
                      )}
                      <div className="min-w-0 flex-1">
                        <div className="text-sm font-medium">
                          {r.title}
                          {r.year != null && (
                            <span className="text-muted-foreground"> ({r.year})</span>
                          )}
                        </div>
                        {r.overview && (
                          <p className="line-clamp-2 text-xs text-muted-foreground">{r.overview}</p>
                        )}
                      </div>
                      <Button
                        size="sm"
                        variant="outline"
                        disabled={apply.isPending}
                        onClick={() => apply.mutate(r.externalId)}
                      >
                        {t('admin.metadata.apply')}
                      </Button>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          )}

          <div className="flex flex-col gap-2">
            <div className="flex items-end gap-2">
              <div className="flex flex-1 flex-col gap-1.5">
                <Label>{t('admin.metadata.overview')}</Label>
                <textarea
                  className="min-h-20 w-full rounded-sm border border-border bg-transparent px-3 py-2 text-sm"
                  value={description}
                  onChange={(e) => setDescription(e.target.value)}
                />
              </div>
              <div className="flex w-24 flex-col gap-1.5">
                <Label>{t('admin.metadata.year')}</Label>
                <Input
                  type="number"
                  value={year}
                  onChange={(e) => setYear(e.target.value)}
                />
              </div>
            </div>
            <div className="flex flex-wrap items-center gap-2">
              {providers && providers.length > 0 && (
                <>
                  <Select value={effectiveProvider} onValueChange={setProvider}>
                    <SelectTrigger className="h-9 w-24">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {providers.map((p) => (
                        <SelectItem key={p} value={p}>
                          {p.toUpperCase()}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <Button
                    size="sm"
                    variant="outline"
                    disabled={search.isPending || !searchTerm}
                    onClick={() => search.mutate()}
                  >
                    {t('admin.metadata.searchBtn')}
                  </Button>
                </>
              )}
              <Button size="sm" disabled={save.isPending || !name.trim()} onClick={() => save.mutate()}>
                {t('common.save')}
              </Button>
              {linked && (
                <Button
                  size="sm"
                  variant="outline"
                  disabled={refreshEpisodes.isPending}
                  onClick={() => refreshEpisodes.mutate()}
                >
                  {refreshEpisodes.isPending
                    ? t('admin.metadata.refreshing')
                    : t('admin.metadata.refreshEpisodes')}
                </Button>
              )}
              {(show.metadataProvider || show.posterImageId) && (
                <Button
                  size="sm"
                  variant="ghost"
                  disabled={clear.isPending}
                  onClick={() => clear.mutate()}
                >
                  {t('admin.metadata.clear')}
                </Button>
              )}
              {show.metadataProvider && (
                <span className="text-xs text-muted-foreground">
                  {t('admin.metadata.sourceLabel')}: {show.metadataProvider}
                </span>
              )}
            </div>
          </div>
        </div>
      </CardContent>
    </Card>
  )
}
