import { useQuery } from '@tanstack/react-query'
import { AlertTriangle, ChevronDown, ChevronRight, CircleAlert } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { qk } from '@/shared/api/query-keys'
import type { SlotDto, TemplateIssueDto } from '@/shared/api/types'
import { cn } from '@/shared/lib/cn'
import { getTemplateIssues } from '../api'

/**
 * Проверки по правилам (см. 5.1). Считаются на сервере по шаблону, без прогона генератора, поэтому
 * показываются прямо в редакторе и обновляются вместе с сеткой.
 *
 * По умолчанию свёрнуты в одну строку со счётчиками: семь дыр в сетке — обычное состояние
 * недособранного канала, и занимать ими пол-экрана над самой сеткой значит прятать то, ради чего
 * экран открывали. Разворачиваются по клику и скроллятся, не растягивая страницу.
 */
export function TemplateIssues({
  channelId,
  slotsById,
  onGoToSlot,
}: Readonly<{
  channelId: string
  slotsById: Map<string, SlotDto>
  onGoToSlot: (slot: SlotDto) => void
}>) {
  const { t } = useTranslation()
  const [open, setOpen] = useState(false)
  const { data: issues } = useQuery({
    queryKey: qk.channels.issues(channelId),
    queryFn: () => getTemplateIssues(channelId),
  })

  if (!issues || issues.length === 0) return null

  const errors = issues.filter((i) => i.severity === 'Error')
  const warnings = issues.filter((i) => i.severity === 'Warning')

  return (
    <div className="flex min-w-0 flex-col gap-1 text-xs">
      <button
        type="button"
        className={cn(
          'flex items-center gap-1.5 self-start rounded-md border px-2 py-1 font-semibold uppercase tracking-wide',
          errors.length > 0
            ? 'border-red-700/50 text-red-500'
            : 'border-amber-600/50 text-amber-500',
        )}
        onClick={() => setOpen((v) => !v)}
      >
        {open ? <ChevronDown className="h-3 w-3" /> : <ChevronRight className="h-3 w-3" />}
        {errors.length > 0 ? (
          <CircleAlert className="h-3 w-3" />
        ) : (
          <AlertTriangle className="h-3 w-3" />
        )}
        {t('admin.channels.issues', { errors: errors.length, warnings: warnings.length })}
      </button>

      {open && (
        <ul className="crt-panel flex max-h-48 flex-col gap-0.5 overflow-y-auto rounded-md px-3 py-2">
          {[...errors, ...warnings].map((issue, index) => (
            <IssueRow
              key={`${issue.kind}-${index}`}
              issue={issue}
              slot={issue.slotId ? slotsById.get(issue.slotId) : undefined}
              onGoToSlot={onGoToSlot}
            />
          ))}
        </ul>
      )}
    </div>
  )
}

function IssueRow({
  issue,
  slot,
  onGoToSlot,
}: Readonly<{
  issue: TemplateIssueDto
  slot: SlotDto | undefined
  onGoToSlot: (slot: SlotDto) => void
}>) {
  const { t } = useTranslation()
  const Icon = issue.severity === 'Error' ? CircleAlert : AlertTriangle

  return (
    <li className="flex items-start gap-1.5">
      <Icon
        className={cn(
          'mt-0.5 h-3 w-3 shrink-0',
          issue.severity === 'Error' ? 'text-red-500' : 'text-amber-500',
        )}
      />
      <span className="min-w-0 flex-1">
        <span className="text-muted-foreground">
          {t(`admin.channels.issueKinds.${issue.kind}`)}:{' '}
        </span>
        {issue.details}
      </span>
      {slot && (
        <button
          type="button"
          className="shrink-0 text-primary hover:underline"
          onClick={() => onGoToSlot(slot)}
        >
          {t('admin.channels.goToSlot')}
        </button>
      )}
    </li>
  )
}
