import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Link } from '@tanstack/react-router'
import { ChevronLeft, GripVertical, Trash2 } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { imageUrl } from '@/features/admin/images/api'
import { ImageGallery } from '@/features/admin/images/ImageGallery'
import { listShows } from '@/features/admin/shows/api'
import { ShowPicker } from '@/features/admin/shows/ShowPicker'
import { qk } from '@/shared/api/query-keys'
import { useApiError } from '@/shared/lib/use-api-error'
import { Badge } from '@/shared/ui/badge'
import { Button } from '@/shared/ui/button'
import { Input } from '@/shared/ui/input'
import { Label } from '@/shared/ui/label'
import {
  addCollectionShow,
  getCollection,
  removeCollectionShow,
  reorderCollection,
  setCollectionPoster,
  updateCollection,
} from './api'

export function CollectionDetail({ collectionId }: Readonly<{ collectionId: string }>) {
  const { t } = useTranslation()
  const queryClient = useQueryClient()
  const [galleryOpen, setGalleryOpen] = useState(false)
  const [dragged, setDragged] = useState<string | null>(null)
  const [pendingShow, setPendingShow] = useState('')
  const [name, setName] = useState<string | null>(null)
  const [description, setDescription] = useState<string | null>(null)

  const { data: collection, isLoading } = useQuery({
    queryKey: qk.collections.detail(collectionId),
    queryFn: () => getCollection(collectionId),
  })
  const { data: shows } = useQuery({ queryKey: qk.shows.all, queryFn: () => listShows() })

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

  const saveMutation = useMutation({
    mutationFn: () =>
      updateCollection(collectionId, {
        name: (name ?? collection?.name ?? '').trim(),
        description: description ?? collection?.description ?? null,
      }),
    onSuccess: invalidate,
    onError,
  })
  const posterMutation = useMutation({
    mutationFn: (imageId: string | null) => setCollectionPoster(collectionId, imageId),
    onSuccess: invalidate,
    onError,
  })
  const addMutation = useMutation({
    mutationFn: (showId: string) => addCollectionShow(collectionId, showId),
    onSuccess: () => {
      setPendingShow('')
      invalidate()
    },
    onError,
  })
  const removeMutation = useMutation({
    mutationFn: (showId: string) => removeCollectionShow(collectionId, showId),
    onSuccess: invalidate,
    onError,
  })
  const reorderMutation = useMutation({
    mutationFn: (order: string[]) => reorderCollection(collectionId, order),
    onSuccess: invalidate,
    onError,
  })

  if (isLoading || !collection)
    return <p className="text-muted-foreground">{t('common.loading')}</p>

  const memberIds = new Set(collection.items.map((i) => i.showId))
  const available = (shows ?? []).filter((s) => !memberIds.has(s.id))

  /** Порядок пересобирается целиком и уходит одним запросом — сервер сам расставит позиции. */
  const dropOn = (targetShowId: string) => {
    if (!dragged || dragged === targetShowId) return
    const order = collection.items.map((i) => i.showId).filter((id) => id !== dragged)
    const at = order.indexOf(targetShowId)
    order.splice(at, 0, dragged)
    setDragged(null)
    reorderMutation.mutate(order)
  }

  return (
    <div className="flex flex-col gap-6">
      <div>
        <Button asChild size="sm" variant="ghost">
          <Link to="/admin/collections">
            <ChevronLeft className="h-4 w-4" />
            {t('admin.collections.title')}
          </Link>
        </Button>
      </div>

      <div 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">
            {collection.posterImageId ? (
              <img
                src={imageUrl(collection.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>
          {collection.posterImageId && (
            <Button size="sm" variant="ghost" onClick={() => posterMutation.mutate(null)}>
              {t('common.delete')}
            </Button>
          )}
          <ImageGallery
            open={galleryOpen}
            onOpenChange={setGalleryOpen}
            category="ShowPoster"
            onSelect={(img) => posterMutation.mutate(img.id)}
          />
        </div>

        <div className="flex min-w-0 flex-1 flex-col gap-3">
          <div className="flex flex-col gap-1.5">
            <Label>{t('admin.collections.name')}</Label>
            <Input
              value={name ?? collection.name}
              maxLength={256}
              onChange={(e) => setName(e.target.value)}
            />
          </div>
          <div className="flex flex-col gap-1.5">
            <Label>{t('admin.collections.description')}</Label>
            <Input
              value={description ?? collection.description ?? ''}
              maxLength={2048}
              onChange={(e) => setDescription(e.target.value)}
            />
          </div>
          <div>
            <Button
              size="sm"
              disabled={saveMutation.isPending}
              onClick={() => saveMutation.mutate()}
            >
              {t('common.save')}
            </Button>
          </div>
        </div>
      </div>

      <div className="flex flex-col gap-2">
        <div className="flex flex-wrap items-center gap-2">
          <h3 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
            {t('admin.collections.parts')}
          </h3>
          {/* Только те, кого в коллекции ещё нет: повторно добавлять некого. */}
          <ShowPicker
            value={pendingShow}
            shows={available}
            placeholder={t('admin.collections.pickShow')}
            className="h-9 w-64"
            onChange={setPendingShow}
          />
          <Button
            size="sm"
            disabled={!pendingShow || addMutation.isPending}
            onClick={() => addMutation.mutate(pendingShow)}
          >
            {t('admin.collections.addShow')}
          </Button>
        </div>

        <p className="text-xs text-muted-foreground">{t('admin.collections.orderHint')}</p>

        <div className="crt-panel rounded-md">
          {collection.items.length === 0 ? (
            <p className="px-4 py-3 text-sm text-muted-foreground">
              {t('admin.collections.empty')}
            </p>
          ) : (
            <ul className="divide-y divide-border text-sm">
              {collection.items.map((item, index) => (
                <li
                  key={item.showId}
                  draggable
                  onDragStart={() => setDragged(item.showId)}
                  onDragOver={(e) => e.preventDefault()}
                  onDrop={() => dropOn(item.showId)}
                  className="flex items-center gap-3 px-4 py-2"
                >
                  <GripVertical className="h-4 w-4 shrink-0 cursor-grab text-muted-foreground" />
                  <span className="w-6 shrink-0 text-muted-foreground">{index + 1}</span>
                  <Link
                    to="/admin/shows/$showId"
                    params={{ showId: item.showId }}
                    className="min-w-0 flex-1 truncate text-primary hover:underline"
                  >
                    {item.showName}
                  </Link>
                  {item.year && <span className="text-muted-foreground">{item.year}</span>}
                  <Badge variant="muted">{t(`admin.shows.kinds.${item.showKind}`)}</Badge>
                  <span className="text-muted-foreground">
                    {t('admin.shows.episodes')}: {item.episodeCount}
                  </span>
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={() => removeMutation.mutate(item.showId)}
                  >
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </li>
              ))}
            </ul>
          )}
        </div>
      </div>
    </div>
  )
}
