import { useQuery } from '@tanstack/react-query'
import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Radio } from 'lucide-react'
import type { ScheduleEntryDto } from '@/shared/api/types'
import { cn } from '@/shared/lib/cn'
import { Badge } from '@/shared/ui/badge'
import { ChannelPlayer } from './ChannelPlayer'
import { getEpg, listChannels, watchChannel } from './api'

function formatTime(iso: string) {
  return new Date(iso).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
}

export function AirPage() {
  const { t } = useTranslation()
  const [selected, setSelected] = useState<string | null>(null)
  const [watchReady, setWatchReady] = useState(false)

  const { data: channels, isLoading } = useQuery({
    queryKey: ['air', 'channels'],
    queryFn: listChannels,
  })

  useEffect(() => {
    if (!selected && channels && channels.length > 0) setSelected(channels[0].slug)
  }, [channels, selected])

  useEffect(() => {
    if (!selected) return
    setWatchReady(false)
    let cancelled = false
    void watchChannel(selected)
      .then(() => {
        if (!cancelled) setWatchReady(true)
      })
      .catch(() => undefined)
    return () => {
      cancelled = true
    }
  }, [selected])

  const { data: epg } = useQuery({
    queryKey: ['air', 'epg', selected],
    queryFn: () =>
      getEpg(
        selected!,
        new Date(Date.now() - 30 * 60_000),
        new Date(Date.now() + 3 * 60 * 60_000),
      ),
    enabled: !!selected,
    refetchInterval: 60_000,
  })

  const { current, upcoming } = useMemo(() => splitEpg(epg ?? []), [epg])

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

  if (!channels || channels.length === 0)
    return (
      <div className="flex flex-col gap-2">
        <h1 className="crt-glow text-2xl font-bold">{t('nav.dashboard')}</h1>
        <p className="text-muted-foreground">{t('air.noChannels')}</p>
      </div>
    )

  return (
    <div className="flex flex-col gap-4">
      <h1 className="crt-glow text-2xl font-bold">{t('nav.dashboard')}</h1>

      <div className="grid gap-4 md:grid-cols-[220px_1fr]">
        <aside className="flex gap-2 overflow-x-auto md:flex-col md:overflow-visible">
          {channels.map((channel) => (
            <button
              key={channel.id}
              onClick={() => setSelected(channel.slug)}
              className={cn(
                'flex shrink-0 items-center gap-2 rounded-sm border border-border px-3 py-2 text-left text-sm hover:bg-muted md:shrink',
                selected === channel.slug && 'border-primary text-primary',
              )}
            >
              <Radio className="h-4 w-4" />
              {channel.name}
            </button>
          ))}
        </aside>

        <div className="flex flex-col gap-4">
          {selected && watchReady ? (
            <ChannelPlayer slug={selected} />
          ) : (
            <div className="aspect-video w-full animate-pulse rounded-md border border-border bg-black" />
          )}

          <div className="flex flex-col gap-3">
            {current && (
              <div className="flex flex-col gap-1">
                <div className="flex items-center gap-2">
                  <Badge>{t('air.now')}</Badge>
                  <span className="font-medium">{programLabel(current, t)}</span>
                </div>
                <span className="text-xs text-muted-foreground">
                  {formatTime(current.startsAtUtc)} – {formatTime(current.endsAtUtc)}
                </span>
              </div>
            )}

            {upcoming.length > 0 && (
              <div className="crt-panel rounded-md">
                <div className="border-b border-border px-4 py-2 text-xs uppercase tracking-wide text-muted-foreground">
                  {t('air.next')}
                </div>
                <ul className="divide-y divide-border">
                  {upcoming.slice(0, 6).map((entry) => (
                    <li key={entry.id} className="flex items-center gap-3 px-4 py-2 text-sm">
                      <span className="w-12 shrink-0 text-muted-foreground">
                        {formatTime(entry.startsAtUtc)}
                      </span>
                      <span>{programLabel(entry, t)}</span>
                    </li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  )
}

function splitEpg(entries: ScheduleEntryDto[]) {
  const now = Date.now()
  const current = entries.find(
    (e) => new Date(e.startsAtUtc).getTime() <= now && new Date(e.endsAtUtc).getTime() > now,
  )
  const upcoming = entries.filter((e) => new Date(e.startsAtUtc).getTime() > now)
  return { current, upcoming }
}

function programLabel(entry: ScheduleEntryDto, t: (key: string) => string) {
  if (entry.kind === 'Ad') return t('air.ad')
  const name = entry.showName ?? '—'
  return entry.episodeIndex != null ? `${name} · ${t('air.episode')} ${entry.episodeIndex + 1}` : name
}
