import { useQuery } from '@tanstack/react-query'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { qk } from '@/shared/api/query-keys'
import { Button } from '@/shared/ui/button'
import { Pager } from '@/shared/ui/pager'
import { getSchedule } from '../api'
import { SchedulePreview } from './SchedulePreview'

/** Сколько вещательных суток показываем: столько же, на сколько по умолчанию строится лента. */
const DAYS = 7

const PAGE_SIZE = 50

/** «06:00:00» → минуты от полуночи. */
function minutesOf(time: string): number {
  const [hours, minutes] = time.split(':').map(Number)
  return (hours || 0) * 60 + (minutes || 0)
}

/**
 * Начало вещательных суток номер `index`, считая от текущих, в UTC. Сутки канала начинаются
 * не в полночь, поэтому «сегодня» до `dayStartTime` — это ещё вчерашний эфир.
 */
function dayStartUtc(index: number, utcOffsetMinutes: number, dayStartTime: string): Date {
  const offset = utcOffsetMinutes * 60_000
  const local = new Date(Date.now() + offset)

  const midnight = Date.UTC(local.getUTCFullYear(), local.getUTCMonth(), local.getUTCDate())
  const start = midnight + minutesOf(dayStartTime) * 60_000
  const today = local.getTime() >= start ? start : start - 24 * 3_600_000

  return new Date(today + index * 24 * 3_600_000 - offset)
}

/**
 * Эфир канала: вещательные сутки выбираются кнопками, внутри суток лента листается страницами.
 *
 * Грузим сутки, а не всю неделю разом: неделя эфира — это тысячи записей вместе с рекламой
 * и заставками, а смотрят их всегда по дням, как программу передач.
 */
export function AirSchedule({
  channelId,
  utcOffsetMinutes,
  dayStartTime,
  onShowTrace,
}: Readonly<{
  channelId: string
  utcOffsetMinutes: number
  /** Начало вещательных суток во времени канала («06:00:00»). */
  dayStartTime: string
  onShowTrace: (entryId: string) => void
}>) {
  const { t } = useTranslation()
  const [day, setDay] = useState(0)
  const [page, setPage] = useState(1)
  // По умолчанию прошедшее скрыто: эфир смотрят, чтобы понять, что будет, а вчерашние страницы
  // приходилось пролистывать каждый раз заново.
  const [hidePast, setHidePast] = useState(true)
  // Врезки тоже скрыты: между двумя сериями их бывает вчетверо больше, чем программ, и лента
  // из реклам с заставками перестаёт читаться как программа передач. Снятая галочка показывает
  // ленту как есть — ровно то, что уйдёт в эфир.
  const [hideBreaks, setHideBreaks] = useState(true)

  const range = useMemo(() => {
    const from = dayStartUtc(day, utcOffsetMinutes, dayStartTime)
    return { from, to: new Date(from.getTime() + 24 * 3_600_000) }
  }, [day, utcOffsetMinutes, dayStartTime])

  const { data, isLoading } = useQuery({
    queryKey: qk.channels.scheduleDay(channelId, range.from.toISOString()),
    queryFn: () => getSchedule(channelId, range.from, range.to),
  })

  const entries = useMemo(() => data ?? [], [data])
  const visible = useMemo(() => {
    // Идущая запись остаётся: то, что сейчас в эфире, — ещё не история. Аварийный запас не врезка
    // и не скрывается никогда: он и есть то, ради чего в эту ленту заглядывают.
    const now = Date.now()
    return entries.filter(
      (entry) =>
        (!hidePast || new Date(entry.endsAtUtc).getTime() > now) &&
        (!hideBreaks || (entry.kind !== 'Ad' && entry.kind !== 'Bumper')),
    )
  }, [entries, hidePast, hideBreaks])

  const totalPages = Math.max(1, Math.ceil(visible.length / PAGE_SIZE))
  const pageItems = visible.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE)

  return (
    <div className="flex flex-col gap-3">
      <div className="flex flex-wrap items-center gap-2">
        {Array.from({ length: DAYS }, (_, index) => {
          const start = dayStartUtc(index, utcOffsetMinutes, dayStartTime)
          // Подпись — дата во времени канала: сетка задаётся в нём, и часовой пояс админа тут
          // только сбивал бы.
          const label = new Date(start.getTime() + utcOffsetMinutes * 60_000).toLocaleDateString(
            [],
            { weekday: 'short', day: '2-digit', month: '2-digit', timeZone: 'UTC' },
          )

          return (
            <Button
              key={index}
              size="sm"
              variant={index === day ? 'default' : 'outline'}
              onClick={() => {
                setDay(index)
                setPage(1)
              }}
            >
              {index === 0 ? t('admin.channels.airToday') : label}
            </Button>
          )
        })}

        <div className="ml-auto flex items-center gap-4 text-xs text-muted-foreground">
          <label className="flex items-center gap-2">
            <input
              type="checkbox"
              checked={hidePast}
              onChange={(e) => {
                setHidePast(e.target.checked)
                setPage(1)
              }}
            />
            {t('admin.channels.airHidePast')}
          </label>
          <label className="flex items-center gap-2">
            <input
              type="checkbox"
              checked={hideBreaks}
              onChange={(e) => {
                setHideBreaks(e.target.checked)
                setPage(1)
              }}
            />
            {t('admin.channels.airHideBreaks')}
          </label>
        </div>
      </div>

      {isLoading ? (
        <p className="text-muted-foreground">{t('common.loading')}</p>
      ) : (
        <>
          <SchedulePreview entries={pageItems} onShowTrace={onShowTrace} />
          <div className="flex items-center justify-between gap-2 text-xs text-muted-foreground">
            <span>{t('admin.channels.airCount', { count: visible.length })}</span>
            <Pager page={page} totalPages={totalPages} onChange={setPage} />
          </div>
        </>
      )}
    </div>
  )
}
