import { useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useQuery } from '@tanstack/react-query'
import { AlertTriangle, CheckCircle2, Clock, Lock, Pencil, Play, Repeat } from 'lucide-react'
import { ShellTopbar } from '@/components/layout/ShellTopbar'
import { AppFooter } from '@/components/layout/AppFooter'
import { ConferenceFormCard } from '@/components/calendar/ConferenceFormCard'
import { ConferenceHoverCard } from '@/components/ui/ConferenceHoverCard'
import { CopyPill } from '@/components/ui/CopyPill'
import { getMyConferences, type ConferenceOut } from '@/api/conferences'
import { formatNextOccurrence } from '@/lib/localTime'
import { addMinutesToTime, formatRecurrenceSummary } from '@/lib/recurrenceFormat'
import '@/styles/lobby.css'
import '@/styles/my-conferences.css'

type Filter = 'all' | 'pinned' | 'upcoming'

/** До начала разовой конференции можно войти заранее — порог «скоро начнётся» (UX-эвристика, не ограничение backend). */
const EARLY_JOIN_WINDOW_MS = 10 * 60 * 1000

function formatRelativeStart(iso: string): string {
  const diffMs = new Date(iso).getTime() - Date.now()
  const diffMin = Math.round(diffMs / 60_000)
  if (diffMin <= 0) return 'вот-вот'
  if (diffMin < 60) return `через ${diffMin} мин`
  const diffHours = Math.round(diffMin / 60)
  if (diffHours < 24) return `через ${diffHours} ч`
  return `через ${Math.round(diffHours / 24)} дн.`
}

function formatSubtitle(conf: ConferenceOut): string {
  if (conf.is_pinned && conf.recurrence) return formatRecurrenceSummary(conf.recurrence)
  if (!conf.scheduled_at) return 'Разовая конференция'
  const start = new Date(conf.scheduled_at)
  const dateLabel = start.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long' })
  const timeLabel = start.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })
  const endLabel = conf.duration_minutes ? addMinutesToTime(timeLabel, conf.duration_minutes) : null
  return `Разовая · ${dateLabel}, ${timeLabel}${endLabel ? `–${endLabel}` : ''}`
}

/**
 * «Мои конференции» (design/mockups/my-conferences.html):
 * закреплённые (повторяющиеся) и предстоящие разовые конференции, где текущий
 * пользователь — организатор или приглашённый участник (решение от 2026-07-20,
 * см. ADR-003); кнопки владельца скрываются по `is_owner`.
 * Кнопка редактирования показывается только организатору (`is_owner`);
 * состав участников — в ховер-карточке (ленивый запрос по наведению/фокусу).
 *
 * Контракт `/conferences/my` не возвращает завершённые конференции — фильтр
 * «Завершённые» и карточка «Открыть саммари» из макета опущены.
 */
export function MyConferencesPage() {
  const navigate = useNavigate()
  const [filter, setFilter] = useState<Filter>('all')
  const [editingConference, setEditingConference] = useState<ConferenceOut | null>(null)
  const [hoverTarget, setHoverTarget] = useState<{ conferenceId: string; anchorEl: HTMLElement } | null>(null)

  const {
    data: conferences,
    isPending,
    isError,
    refetch,
  } = useQuery({ queryKey: ['conferences', 'my'], queryFn: getMyConferences })
  const list = useMemo(() => conferences ?? [], [conferences])

  const pinnedCount = list.filter((c) => c.is_pinned).length

  const filtered = useMemo(() => {
    if (filter === 'pinned') return list.filter((c) => c.is_pinned)
    if (filter === 'upcoming') return list.filter((c) => !c.is_pinned)
    return list
  }, [list, filter])

  function handleJoin(conf: ConferenceOut) {
    navigate(`/j/${conf.slug}`)
  }

  return (
    <div className="page-shell">
      <ShellTopbar />
      <main className="page-main">
        <div className="page-head">
          <div>
            <h1>Мои конференции</h1>
            <p>
              {list.length} {list.length === 1 ? 'конференция' : 'конференций'} · {pinnedCount} закреплённых с повторением
            </p>
          </div>
          <button type="button" className="btn btn-primary" onClick={() => navigate('/calendar')}>
            Запланировать новую
          </button>
        </div>

        <div className="filters">
          <button type="button" className={`chip${filter === 'all' ? ' is-active' : ''}`} onClick={() => setFilter('all')}>
            Все
          </button>
          <button type="button" className={`chip${filter === 'pinned' ? ' is-active' : ''}`} onClick={() => setFilter('pinned')}>
            <Repeat style={{ width: 14, height: 14 }} aria-hidden="true" />
            Закреплённые
          </button>
          <button type="button" className={`chip${filter === 'upcoming' ? ' is-active' : ''}`} onClick={() => setFilter('upcoming')}>
            <Clock style={{ width: 14, height: 14 }} aria-hidden="true" />
            Предстоящие
          </button>
        </div>

        {isPending ? (
          <p className="field-hint">Загрузка конференций…</p>
        ) : isError ? (
          <div className="error-banner">
            <AlertTriangle style={{ width: 18, height: 18 }} aria-hidden="true" />
            <div style={{ flex: 1 }}>Не удалось загрузить конференции. Проверьте соединение и попробуйте ещё раз.</div>
            <button type="button" className="btn btn-secondary" style={{ width: 'auto' }} onClick={() => refetch()}>
              Повторить
            </button>
          </div>
        ) : filtered.length === 0 ? (
          <p className="field-hint">Здесь пока пусто — запланируйте конференцию в календаре.</p>
        ) : (
          <section className="conf-grid">
            {filtered.map((conf) => {
              const joinable =
                conf.is_pinned || conf.status === 'active' || (conf.scheduled_at
                  ? new Date(conf.scheduled_at).getTime() - new Date().getTime() <= EARLY_JOIN_WINDOW_MS
                  : false)
              const link = `${window.location.origin}/j/${conf.slug}`
              return (
                <article
                  className={`conf-card${conf.status === 'ended' ? ' is-ended' : ''}`}
                  key={conf.id}
                  onMouseEnter={(e) => setHoverTarget({ conferenceId: conf.id, anchorEl: e.currentTarget })}
                  onMouseLeave={() => setHoverTarget((prev) => (prev?.conferenceId === conf.id ? null : prev))}
                  onFocus={(e) => setHoverTarget({ conferenceId: conf.id, anchorEl: e.currentTarget })}
                  onBlur={() => setHoverTarget((prev) => (prev?.conferenceId === conf.id ? null : prev))}
                >
                  <div className="conf-card-head">
                    <div className="conf-title-wrap">
                      <h3>
                        {conf.is_closed && <Lock style={{ width: 15, height: 15, flexShrink: 0 }} aria-hidden="true" />}
                        {conf.title ?? 'Конференция без названия'}
                      </h3>
                      <p>{formatSubtitle(conf)}</p>
                    </div>
                    {conf.is_pinned ? (
                      <span className="conf-badge pinned">
                        <Repeat style={{ width: 12, height: 12 }} aria-hidden="true" />
                        Закреплена
                      </span>
                    ) : conf.status === 'active' ? (
                      <span className="conf-badge live">
                        <Play style={{ width: 12, height: 12 }} aria-hidden="true" />
                        Идёт сейчас
                      </span>
                    ) : conf.status === 'ended' ? (
                      <span className="conf-badge ended">
                        <CheckCircle2 style={{ width: 12, height: 12 }} aria-hidden="true" />
                        Завершена
                      </span>
                    ) : (
                      <span className="conf-badge scheduled">
                        <Clock style={{ width: 12, height: 12 }} aria-hidden="true" />
                        Предстоящая
                      </span>
                    )}
                  </div>

                  {conf.is_pinned && conf.next_occurrence && (
                    <div className="conf-meta-row">
                      <span className="meta-item">
                        <Clock style={{ width: 15, height: 15 }} aria-hidden="true" />
                        Ближайшее: {formatNextOccurrence(conf.next_occurrence)}
                      </span>
                    </div>
                  )}

                  {conf.status !== 'ended' && (
                    <div className="pills-row">
                      <CopyPill label="Ссылка" value={link.replace(/^https?:\/\//, '')} copyText={link} />
                      <CopyPill label="Номер" value={conf.number} copyText={conf.number} />
                    </div>
                  )}

                  <div className="conf-card-footer">
                    {conf.status === 'ended' ? (
                      <button type="button" className="btn btn-secondary" style={{ flex: 1 }} disabled>
                        Конференция завершена
                      </button>
                    ) : joinable ? (
                      <button type="button" className="btn btn-primary" onClick={() => handleJoin(conf)}>
                        {conf.is_closed ? (
                          <Lock style={{ width: 16, height: 16 }} aria-hidden="true" />
                        ) : (
                          <Play style={{ width: 16, height: 16 }} aria-hidden="true" />
                        )}
                        {conf.is_closed ? 'Войти по паролю' : 'Войти'}
                      </button>
                    ) : (
                      <button type="button" className="btn btn-secondary" style={{ flex: 1 }} disabled>
                        <Clock style={{ width: 16, height: 16 }} aria-hidden="true" />
                        Начнётся {formatRelativeStart(conf.scheduled_at!)}
                      </button>
                    )}
                    {conf.status !== 'ended' && conf.is_owner && (
                      <button type="button" className="icon-btn" aria-label="Редактировать" onClick={() => setEditingConference(conf)}>
                        <Pencil style={{ width: 17, height: 17 }} aria-hidden="true" />
                      </button>
                    )}
                  </div>
                </article>
              )
            })}
          </section>
        )}
      </main>
      <AppFooter />

      {editingConference && (
        <div className="modal-overlay" role="dialog" aria-modal="true" onClick={() => setEditingConference(null)}>
          <div className="modal-form-wrap" onClick={(e) => e.stopPropagation()}>
            <ConferenceFormCard
              conference={editingConference}
              onSaved={() => setEditingConference(null)}
              onDeleted={() => setEditingConference(null)}
              onCancelEdit={() => setEditingConference(null)}
            />
          </div>
        </div>
      )}

      <ConferenceHoverCard conferenceId={hoverTarget?.conferenceId ?? null} anchorEl={hoverTarget?.anchorEl ?? null} />
    </div>
  )
}
