import { useQuery } from '@tanstack/react-query'
import { qk } from '@/shared/api/query-keys'
import { useTranslation } from 'react-i18next'
import type { EntryTraceDto } from '@/shared/api/types'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/shared/ui/dialog'
import { getEntryTrace } from '../api'
import { formatChannelTime } from '../lib/format'

/**
 * «Почему это здесь» (см. 6.5): цепочка происхождения записи. Трейс пишется в момент генерации —
 * восстановить его потом нельзя, поэтому у старых записей часть строк будет пустой.
 */
export function EntryTraceDialog({
  entryId,
  utcOffsetMinutes,
  onClose,
}: Readonly<{
  entryId: string
  utcOffsetMinutes: number
  onClose: () => void
}>) {
  const { t } = useTranslation()
  const { data } = useQuery({
    queryKey: qk.entries.trace(entryId),
    queryFn: () => getEntryTrace(entryId),
  })

  return (
    <Dialog open onOpenChange={(open) => !open && onClose()}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>
            {data
              ? `${data.showName ?? '—'} · ${formatChannelTime(data.startsAtUtc, utcOffsetMinutes)}`
              : t('common.loading')}
          </DialogTitle>
        </DialogHeader>

        {data && (
          <dl className="grid grid-cols-[110px_1fr] gap-x-3 gap-y-1.5 text-sm">
            <Row label={t('admin.channels.traceLayer')}>{layerSummary(data, t)}</Row>
            <Row label={t('admin.channels.traceSlot')}>{slotSummary(data, t)}</Row>
            <Row label={t('admin.channels.traceGroup')}>{groupSummary(data)}</Row>
            <Row label={t('admin.channels.traceCollection')}>{data.collectionName}</Row>
            <Row label={t('admin.channels.traceStrategy')}>{strategySummary(data, t)}</Row>
            <Row label={t('admin.channels.traceJunction')}>{data.junctionName}</Row>
          </dl>
        )}
      </DialogContent>
    </Dialog>
  )
}

type Translate = ReturnType<typeof useTranslation>['t']

/** Склейка непустых частей строки трейса; пусто — значит строка не заполнена (покажем «—»). */
const joinParts = (parts: (string | null | undefined)[]) =>
  parts.filter(Boolean).join(' · ') || null

function layerSummary(data: EntryTraceDto, t: Translate) {
  if (!data.layerName) return null
  const priority =
    data.layerPriority !== null ? ` (${t('admin.channels.priority')} ${data.layerPriority})` : ''
  return `${data.layerName}${priority}`
}

function slotSummary(data: EntryTraceDto, t: Translate) {
  if (!data.slotTitle) return null
  return joinParts([
    data.slotTitle,
    data.slotWeekday === null
      ? t('admin.channels.everyDay')
      : t(`admin.channels.weekdays.${data.slotWeekday}`),
    data.slotTargetStart?.slice(0, 5),
    data.slotDurationMinutes ? `${data.slotDurationMinutes} мин` : null,
    data.driftMinutes !== 0 ? t('admin.channels.traceDrift', { minutes: data.driftMinutes }) : null,
    data.snapped ? t('admin.channels.traceSnapped') : null,
  ])
}

function groupSummary(data: EntryTraceDto) {
  if (!data.groupName) return null
  const count = data.groupItemCount !== null ? ` (${data.groupItemCount})` : ''
  return `${data.groupName}${count}`
}

function strategySummary(data: EntryTraceDto, t: Translate) {
  if (!data.strategy) return null
  return joinParts([
    t(`admin.channels.strategies.${data.strategy}`),
    data.cooldownDays ? t('admin.channels.traceCooldown', { days: data.cooldownDays }) : null,
    data.candidatesAfterCooldown !== null
      ? t('admin.channels.traceCandidates', { count: data.candidatesAfterCooldown })
      : null,
  ])
}

function Row({ label, children }: Readonly<{ label: string; children: React.ReactNode }>) {
  return (
    <>
      <dt className="text-muted-foreground">{label}</dt>
      <dd>{children || '—'}</dd>
    </>
  )
}
