import { useMutation } from '@tanstack/react-query'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { imageUrl } from '@/features/admin/images/api'
import { ImageGallery } from '@/features/admin/images/ImageGallery'
import type { ChannelDto, LogoCorner, ViewerSettings } from '@/shared/api/types'
import { Button } from '@/shared/ui/button'
import { Input } from '@/shared/ui/input'
import { Label } from '@/shared/ui/label'
import { updateViewerSettings } from '../api'
import { CollapsibleCard } from './CollapsibleCard'

const CORNERS: LogoCorner[] = ['TopLeft', 'TopRight', 'BottomLeft', 'BottomRight']

/**
 * Как канал выглядит у зрителя (см. 6.8): логотип, часы, аналоговый фильтр. Всё рисуется на клиенте
 * поверх видео и по умолчанию выключено — канал без логотипа и без шума остаётся нормальным каналом.
 */
export function ViewerCard({
  channel,
  bare,
  onSaved,
  onError,
}: Readonly<{
  channel: ChannelDto
  bare?: boolean
  onSaved: () => void
  onError: (error: unknown) => void
}>) {
  const { t } = useTranslation()
  const [viewer, setViewer] = useState<ViewerSettings>(channel.viewer)
  const [galleryOpen, setGalleryOpen] = useState(false)

  useEffect(() => setViewer(channel.viewer), [channel])

  const patch = (part: Partial<ViewerSettings>) => setViewer((prev) => ({ ...prev, ...part }))

  const save = useMutation({
    mutationFn: () => updateViewerSettings(channel.id, viewer),
    onSuccess: onSaved,
    onError,
  })

  return (
    <CollapsibleCard title={t('admin.channels.viewer')} bare={bare}>
      <div className="flex flex-col gap-4 text-sm">
        <p className="text-xs text-muted-foreground">{t('admin.channels.viewerHint')}</p>

        <div className="flex flex-wrap items-end gap-3">
          <div className="flex flex-col gap-1.5">
            <Label>{t('admin.channels.logo')}</Label>
            <div className="flex h-16 w-24 items-center justify-center rounded-md border border-border bg-muted/30">
              {viewer.logoImageId ? (
                <img
                  src={imageUrl(viewer.logoImageId)}
                  alt=""
                  className="h-full w-full object-contain"
                />
              ) : (
                <span className="text-xs text-muted-foreground">{t('admin.channels.noLogo')}</span>
              )}
            </div>
          </div>
          <Button size="sm" variant="outline" onClick={() => setGalleryOpen(true)}>
            {t('admin.channels.pickLogo')}
          </Button>
          {viewer.logoImageId && (
            <Button size="sm" variant="ghost" onClick={() => patch({ logoImageId: null })}>
              {t('common.delete')}
            </Button>
          )}
          <ImageGallery
            open={galleryOpen}
            onOpenChange={setGalleryOpen}
            category="Library"
            onSelect={(image) => patch({ logoImageId: image.id })}
          />
        </div>

        {viewer.logoImageId && (
          <div className="flex flex-wrap items-end gap-3">
            <div className="flex flex-col gap-1.5">
              <Label>{t('admin.channels.logoCorner')}</Label>
              <select
                className="h-9 rounded-md border border-border bg-transparent px-2"
                value={viewer.logoCorner}
                onChange={(e) => patch({ logoCorner: e.target.value as LogoCorner })}
              >
                {CORNERS.map((corner) => (
                  <option key={corner} value={corner}>
                    {t(`admin.channels.corners.${corner}`)}
                  </option>
                ))}
              </select>
            </div>
            <div className="flex flex-col gap-1.5">
              <Label>{t('admin.channels.logoOpacity')}</Label>
              <Input
                type="number"
                min={0}
                max={1}
                step={0.05}
                className="w-28"
                value={viewer.logoOpacity}
                onChange={(e) => patch({ logoOpacity: clamp01(e.target.value) })}
              />
            </div>
          </div>
        )}

        <label className="flex items-center gap-2">
          <input
            type="checkbox"
            checked={viewer.showClock}
            onChange={(e) => patch({ showClock: e.target.checked })}
          />
          {t('admin.channels.showClock')}
        </label>

        <div className="flex flex-col gap-1.5">
          <Label>{t('admin.channels.analogFilter')}</Label>
          <Input
            type="number"
            min={0}
            max={1}
            step={0.1}
            className="w-28"
            value={viewer.analogFilterStrength}
            onChange={(e) => patch({ analogFilterStrength: clamp01(e.target.value) })}
          />
          <p className="text-xs text-muted-foreground">{t('admin.channels.analogFilterHint')}</p>
        </div>

        <div className="flex justify-end">
          <Button size="sm" disabled={save.isPending} onClick={() => save.mutate()}>
            {t('common.save')}
          </Button>
        </div>
      </div>
    </CollapsibleCard>
  )
}

/** Сила и прозрачность живут в 0..1: пустой ввод трактуем как ноль, а не как NaN. */
function clamp01(value: string): number {
  const n = Number(value)
  return Number.isNaN(n) ? 0 : Math.min(1, Math.max(0, n))
}
