import { useMemo, type CSSProperties } from 'react'
import { createPortal } from 'react-dom'
import { useQuery } from '@tanstack/react-query'
import { Repeat, Users as UsersIcon } from 'lucide-react'
import { getConference } from '@/api/conferences'
import { Avatar } from '@/components/ui/Avatar'

interface ConferenceHoverCardProps {
  /** `null` — карточка скрыта. */
  conferenceId: string | null
  /** Элемент, от которого позиционируется поповер (чип календаря, карточка «Моих конференций»). */
  anchorEl: HTMLElement | null
}

const CARD_WIDTH = 300

/** Позиция карточки — чистая функция от уже смонтированного `anchorEl` (без DOM-эффекта: `getBoundingClientRect` доступен и во время рендера). */
function computeStyle(anchorEl: HTMLElement): CSSProperties {
  const rect = anchorEl.getBoundingClientRect()
  const left = Math.min(rect.left, window.innerWidth - CARD_WIDTH - 12)
  const spaceBelow = window.innerHeight - rect.bottom
  const openUpwards = spaceBelow < 220
  return {
    position: 'fixed',
    left: Math.max(12, left),
    top: openUpwards ? undefined : rect.bottom + 8,
    bottom: openUpwards ? window.innerHeight - rect.top + 8 : undefined,
    width: CARD_WIDTH,
  }
}

/**
 * Ховер-карточка конференции — новый элемент без
 * готового макета: собрана из утверждённых паттернов (карточка `--shadow-lg`
 * как у поповеров/модалок §6, бейдж закреплённости — иконка `Repeat` как в
 * §4.6). Данные — ленивый `GET /conferences/{id}` (доступен только owner|admin
 * — для конференций без прав на просмотр карточка тихо не показывается,
 * см. `isError`), закэшированы react-query по `conferenceId`.
 *
 * Рендерится через портал в `document.body` с `position: fixed`, чтобы не
 * обрезаться `overflow` ячеек календаря/грида карточек. `pointer-events: none`
 * на самой карточке — не должна перехватывать клики по чипу/карточке под ней.
 */
export function ConferenceHoverCard({ conferenceId, anchorEl }: ConferenceHoverCardProps) {
  const { data, isLoading, isError } = useQuery({
    queryKey: ['conferences', 'detail', conferenceId],
    queryFn: () => getConference(conferenceId!),
    enabled: !!conferenceId,
    staleTime: 60_000,
    retry: false,
  })

  // getBoundingClientRect читает уже отрисованный DOM (anchorEl смонтирован
  // родителем раньше) — не побочный эффект рендера, а чтение геометрии
  // существующего узла, поэтому вычисляем прямо в теле рендера (useMemo).
  const style = useMemo(() => (anchorEl ? computeStyle(anchorEl) : null), [anchorEl])

  if (!conferenceId || !anchorEl || !style || isError) return null

  return createPortal(
    <div className="conf-hover-card" style={style} role="tooltip" aria-live="polite">
      {isLoading || !data ? (
        <p className="conf-hover-card-hint">Загрузка…</p>
      ) : (
        <>
          <p className="conf-hover-card-title">{data.title ?? 'Конференция без названия'}</p>
          <p className="conf-hover-card-row">
            <span className="conf-hover-card-label">Организатор</span>
            {data.organizer_name ?? '—'}
          </p>
          <p className="conf-hover-card-row">
            {data.is_pinned ? (
              <>
                <Repeat style={{ width: 13, height: 13 }} aria-hidden="true" />
                Закреплённая (постоянная)
              </>
            ) : (
              'Разовая'
            )}
          </p>
          {data.participants && data.participants.length > 0 && (
            <div className="conf-hover-card-participants">
              <span className="conf-hover-card-label">
                <UsersIcon style={{ width: 13, height: 13 }} aria-hidden="true" />
                Участники ({data.participants.length})
              </span>
              <ul>
                {data.participants.map((p) => (
                  <li key={p.user_id ?? p.email}>
                    <Avatar name={p.name ?? p.email} avatarUrl={p.avatar_url} size={18} />
                    {p.name ?? p.email}
                    {p.is_organizer && <span className="conf-hover-card-tag">организатор</span>}
                  </li>
                ))}
              </ul>
            </div>
          )}
        </>
      )}
    </div>,
    document.body,
  )
}
