<script setup lang="ts">
import { computed, inject, onMounted, ref } from 'vue'
import { useLecturesStore } from '@/stores/lectures'
import SearchInput from '@/components/ui/SearchInput.vue'
import LectureCard from '@/components/ui/LectureCard.vue'
import GlassCard from '@/components/ui/GlassCard.vue'
import FilterChips from '@/components/ui/FilterChips.vue'
import EmptyState from '@/components/ui/EmptyState.vue'
import DataTable from '@/components/ui/DataTable.vue'
import ModalDialog from '@/components/ui/ModalDialog.vue'
import EnrollmentLimitModal from '@/components/ui/EnrollmentLimitModal.vue'

const lecturesStore = useLecturesStore()
type DataTableColumn = { key: string; label: string; align?: 'left' | 'center' | 'right' }

const search = ref('')
const viewMode = ref<'cards' | 'list' | 'calendar'>('cards')
const dateFilter = ref('Любая дата')
const direction = ref('Все направления')
const teacher = ref('Все преподаватели')
const building = ref('Все корпуса')
const format = ref<'all' | 'online' | 'offline'>('all')
const onlyFree = ref(false)
const filtersOpen = ref(false)
const enrollmentLimitModalOpen = ref(false)
const addToast = inject('addToast') as
  | ((message: string, type?: 'success' | 'error' | 'info') => void)
  | undefined

onMounted(() => {
  if (!lecturesStore.all.length) void lecturesStore.fetchLectures()
})

const tagFilters = ref([
  { label: '#ML', value: '#ML', active: false },
  { label: '#ИИ', value: '#ИИ', active: false },
  { label: '#Python', value: '#Python', active: false },
  { label: '#квантовые-вычисления', value: '#квантовые-вычисления', active: false },
  { label: '#биоинформатика', value: '#биоинформатика', active: false },
  { label: '#философия', value: '#философия', active: false },
  { label: '#право', value: '#право', active: false },
  { label: '#маркетинг', value: '#маркетинг', active: false },
])

const directions = [
  'Все направления',
  'Информатика и вычислительная техника',
  'Физика',
  'Биология',
  'Философия',
  'Право',
  'Экономика и маркетинг',
]

const teachers = computed(() => [
  'Все преподаватели',
  ...new Set(lecturesStore.all.map((l) => l.teacher)),
])
const buildings = computed(() => [
  'Все корпуса',
  ...new Set(lecturesStore.all.map((l) => l.building)),
])

function toggleTag(value: string) {
  const target = tagFilters.value.find((t) => t.value === value)
  if (target) target.active = !target.active
}

const activeTags = computed(() => tagFilters.value.filter((t) => t.active).map((t) => t.value))

const filtered = computed(() =>
  lecturesStore.all.filter((l) => {
    const matchesSearch = l.title.toLowerCase().includes(search.value.toLowerCase())
    const directionKey = direction.value.split(' ')[0] || ''
    const matchesDirection =
      direction.value === 'Все направления' || l.institute.includes(directionKey)
    const matchesTeacher = teacher.value === 'Все преподаватели' || l.teacher === teacher.value
    const matchesBuilding = building.value === 'Все корпуса' || l.building === building.value
    const matchesFormat = format.value === 'all' || l.format === format.value
    const matchesTags =
      activeTags.value.length === 0 || activeTags.value.some((tag) => l.tags.includes(tag))
    const matchesFree = !onlyFree.value || l.freeSeats > 0
    return (
      matchesSearch &&
      matchesDirection &&
      matchesTeacher &&
      matchesBuilding &&
      matchesFormat &&
      matchesTags &&
      matchesFree
    )
  }),
)

const appliedFilters = computed(() => {
  const filters: string[] = []
  if (dateFilter.value !== 'Любая дата') filters.push(dateFilter.value)
  if (direction.value !== 'Все направления') filters.push(direction.value)
  if (teacher.value !== 'Все преподаватели') filters.push(teacher.value)
  if (building.value !== 'Все корпуса') filters.push(building.value)
  if (format.value !== 'all') filters.push(format.value === 'online' ? 'Онлайн' : 'Офлайн')
  if (onlyFree.value) filters.push('Есть места')
  filters.push(...activeTags.value)
  return filters
})

const tableColumns: DataTableColumn[] = [
  { key: 'title', label: 'Лекция' },
  { key: 'teacher', label: 'Преподаватель' },
  { key: 'date', label: 'Дата' },
  { key: 'place', label: 'Локация' },
  { key: 'seats', label: 'Места', align: 'center' },
  { key: 'action', label: 'Действия', align: 'right' },
]

const calendarGroups = computed(() => {
  const groups: Record<string, typeof filtered.value> = {}
  filtered.value.forEach((l) => {
    const date = new Date(l.date).toLocaleDateString('ru-RU', { day: 'numeric', month: 'long' })
    groups[date] = groups[date] || []
    groups[date].push(l)
  })
  return Object.entries(groups)
})

function isEnrollmentLimitError(err: unknown) {
  return err instanceof Error && err.message.includes('Лимит записей достигнут')
}

async function registerLecture(id: string) {
  try {
    await lecturesStore.register(id)
    addToast?.('Вы записаны на лекцию.', 'success')
  } catch (err) {
    if (isEnrollmentLimitError(err)) {
      enrollmentLimitModalOpen.value = true
      return
    }
    addToast?.(err instanceof Error ? err.message : 'Не удалось записаться на лекцию.', 'error')
  }
}

function isRegistered(id: string) {
  return lecturesStore.isRegistered(id)
}
</script>

<template>
  <div class="catalog page-content">
    <div class="catalog-header">
      <div>
        <h1 class="page-title">Каталог открытых лекций</h1>
        <p class="text-secondary">
          Выберите лекцию, фильтруйте по направлениям и регистрируйтесь в один клик.
        </p>
      </div>
      <div class="header-actions">
        <SearchInput v-model="search" placeholder="Поиск по теме лекции" />
        <button class="btn-secondary filters-btn" @click="filtersOpen = true">Фильтры</button>
      </div>
    </div>

    <GlassCard>
      <div class="filters-grid">
        <div>
          <label class="filter-label">Дата</label>
          <select v-model="dateFilter" class="glass-input">
            <option>Любая дата</option>
            <option>Сегодня</option>
            <option>Завтра</option>
            <option>На этой неделе</option>
          </select>
        </div>
        <div>
          <label class="filter-label">Направление</label>
          <select v-model="direction" class="glass-input">
            <option v-for="d in directions" :key="d">{{ d }}</option>
          </select>
        </div>
        <div>
          <label class="filter-label">Преподаватель</label>
          <select v-model="teacher" class="glass-input">
            <option v-for="t in teachers" :key="t">{{ t }}</option>
          </select>
        </div>
        <div>
          <label class="filter-label">Корпус</label>
          <select v-model="building" class="glass-input">
            <option v-for="b in buildings" :key="b">{{ b }}</option>
          </select>
        </div>
        <div>
          <label class="filter-label">Формат</label>
          <div class="segmented">
            <button :class="{ active: format === 'all' }" @click="format = 'all'">Все</button>
            <button :class="{ active: format === 'offline' }" @click="format = 'offline'">
              Офлайн
            </button>
            <button :class="{ active: format === 'online' }" @click="format = 'online'">
              Онлайн
            </button>
          </div>
        </div>
        <div>
          <label class="filter-label">Теги</label>
          <FilterChips :filters="tagFilters" @toggle="toggleTag" />
        </div>
        <div class="free-toggle">
          <label class="filter-label">Наличие мест</label>
          <label class="switch">
            <input type="checkbox" v-model="onlyFree" />
            <span>Только свободные</span>
          </label>
        </div>
      </div>
    </GlassCard>

    <div class="view-row">
      <div class="segmented">
        <button :class="{ active: viewMode === 'cards' }" @click="viewMode = 'cards'">
          Карточки
        </button>
        <button :class="{ active: viewMode === 'list' }" @click="viewMode = 'list'">Список</button>
        <button :class="{ active: viewMode === 'calendar' }" @click="viewMode = 'calendar'">
          Календарь
        </button>
      </div>
      <div class="applied" v-if="appliedFilters.length">
        <span class="text-secondary">Фильтры:</span>
        <span v-for="f in appliedFilters" :key="f" class="tag-chip active">{{ f }}</span>
      </div>
    </div>

    <GlassCard v-if="lecturesStore.loading">
      <div class="text-secondary">Загружаем лекции...</div>
    </GlassCard>

    <div v-else-if="lecturesStore.error">
      <EmptyState title="Не удалось загрузить каталог" :subtitle="lecturesStore.error" />
    </div>

    <div v-else-if="filtered.length === 0">
      <EmptyState
        title="Нет результатов"
        subtitle="Попробуйте изменить фильтры или сбросить поиск."
      />
    </div>

    <div v-else-if="viewMode === 'cards'" class="cards-grid">
      <LectureCard
        v-for="l in filtered"
        :key="l.id"
        :lecture="l"
        :registered="isRegistered(l.id)"
        :show-rating="false"
        @register="registerLecture"
      />
    </div>

    <div v-else-if="viewMode === 'list'" class="list-view">
      <GlassCard>
        <DataTable :columns="tableColumns" :rows="filtered">
          <template #title="{ row }">
            <div class="list-title">{{ row.title }}</div>
            <div class="text-secondary text-sm">{{ row.tags.join(' ') }}</div>
          </template>
          <template #date="{ row }">
            {{ new Date(row.date).toLocaleDateString('ru-RU') }} {{ row.time }}
          </template>
          <template #place="{ row }">
            {{ row.building }} {{ row.room ? `ауд. ${row.room}` : '' }}
          </template>
          <template #seats="{ row }">
            <span :class="row.freeSeats === 0 ? 'badge badge-gray' : 'badge badge-green'">
              {{
                row.registrationClosed ? 'Запись закрыта' : `${row.enrolledSeats}/${row.totalSeats}`
              }}
            </span>
          </template>
          <template #action="{ row }">
            <button
              class="btn-primary btn-sm"
              :disabled="row.freeSeats === 0 || row.registrationClosed || isRegistered(row.id)"
              @click="registerLecture(row.id)"
            >
              {{ isRegistered(row.id) ? 'Записан' : 'Записаться' }}
            </button>
          </template>
        </DataTable>
      </GlassCard>
    </div>

    <div v-else class="calendar-view">
      <GlassCard v-for="[date, items] in calendarGroups" :key="date" class="calendar-day">
        <div class="calendar-date">{{ date }}</div>
        <div class="calendar-items">
          <div v-for="l in items" :key="l.id" class="calendar-item">
            <div class="calendar-title">{{ l.title }}</div>
            <div class="calendar-meta">
              {{ l.time }} {{ l.building }} {{ l.room ? `ауд. ${l.room}` : '' }}
            </div>
            <button class="btn-secondary btn-sm">Подробнее</button>
          </div>
        </div>
      </GlassCard>
    </div>

    <ModalDialog v-model="filtersOpen" title="Фильтры" icon="search" size="lg">
      <div class="modal-filters">
        <label>Дата</label>
        <select v-model="dateFilter" class="glass-input">
          <option>Любая дата</option>
          <option>Сегодня</option>
          <option>Завтра</option>
          <option>На этой неделе</option>
        </select>
        <label>Направление</label>
        <select v-model="direction" class="glass-input">
          <option v-for="d in directions" :key="d">{{ d }}</option>
        </select>
        <label>Преподаватель</label>
        <select v-model="teacher" class="glass-input">
          <option v-for="t in teachers" :key="t">{{ t }}</option>
        </select>
        <label>Корпус</label>
        <select v-model="building" class="glass-input">
          <option v-for="b in buildings" :key="b">{{ b }}</option>
        </select>
        <label>Формат</label>
        <div class="segmented">
          <button :class="{ active: format === 'all' }" @click="format = 'all'">Все</button>
          <button :class="{ active: format === 'offline' }" @click="format = 'offline'">
            Офлайн
          </button>
          <button :class="{ active: format === 'online' }" @click="format = 'online'">
            Онлайн
          </button>
        </div>
        <label>Теги</label>
        <FilterChips :filters="tagFilters" @toggle="toggleTag" />
        <label class="switch">
          <input type="checkbox" v-model="onlyFree" />
          <span>Только свободные места</span>
        </label>
      </div>
      <template #footer>
        <button class="btn-secondary" type="button" @click="filtersOpen = false">Закрыть</button>
        <button class="btn-primary" type="button" @click="filtersOpen = false">Применить</button>
      </template>
    </ModalDialog>

    <EnrollmentLimitModal v-model="enrollmentLimitModalOpen" />
  </div>
</template>

<style scoped>
.catalog {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.catalog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.header-actions {
  display: flex;
  gap: 12px;
  align-items: center;
  flex: 1;
  justify-content: flex-end;
}
.filters-btn {
  display: none;
}
.filters-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
}
.filters-grid > * {
  min-width: 0;
}
.filter-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text-secondary);
  margin-bottom: 6px;
  display: block;
}
.segmented {
  display: inline-flex;
  border: 1px solid var(--color-border-glass);
  border-radius: 10px;
  overflow: hidden;
}
.segmented button {
  background: rgba(255, 255, 255, 0.7);
  border: none;
  padding: 8px 14px;
  font-size: 13px;
  cursor: pointer;
  color: var(--color-text-secondary);
}
.segmented button.active {
  background: rgba(34, 197, 94, 0.15);
  color: var(--color-primary-dark);
  font-weight: 600;
}
.free-toggle {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.switch {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--color-text-secondary);
}
.view-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.applied {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  min-width: 0;
}
.applied .tag-chip {
  max-width: 100%;
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  line-height: 1.25;
}
.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}
.list-title {
  font-weight: 600;
}
.list-view {
  margin-top: 6px;
}
.calendar-view {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.calendar-day {
  padding: 16px;
}
.calendar-date {
  font-weight: 700;
  margin-bottom: 8px;
}
.calendar-items {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.calendar-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border-bottom: 1px solid var(--color-border-glass);
  padding-bottom: 8px;
}
.calendar-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.calendar-title {
  font-weight: 600;
}
.calendar-meta {
  font-size: 12px;
  color: var(--color-text-secondary);
}
.modal-filters {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

@media (max-width: 768px) {
  .filters-grid {
    display: none;
  }
  .filters-btn {
    display: inline-flex;
  }
  .header-actions {
    width: 100%;
    justify-content: space-between;
  }
}
</style>
