<!-- Блок «Live Cams»: заголовок со счётчиками онлайна и сетка тумб текущего
провайдера. Стоит после основного листинга — как на боевом purple-haze.

Слои ответственности (чтобы дизайн и провайдер менялись независимо):
  main (этот файл)    — где блок стоит, сколько тумб, заголовок и счётчики;
  grid                — раскладка и выбор обёртки провайдера;
  card                — дизайн и поведение тумбы.

Сетка (общая с разделом вебкамов) повторяет основной грид сайта, а неполная последняя
строка не рисуется вовсе: дырок в ней быть не должно, поэтому число тумб
округляется вниз до кратного числу колонок, а на десктопе ограничено тремя
линиями. Всё под флагом `FeatureWebcamsEnabled`. -->
<template>
  <section
    v-if="isEnabled && visibleItems.length"
    class="webcam-main"
  >
    <WebcamHeader :counts="counts"/>

    <GridWebcams
      :items="visibleItems"
      @model-click="payload => emit('model-click', payload)"
      @model-view="payload => emit('model-view', payload)"
    />
  </section>
</template>

<script setup lang="ts">
import type { IStripcashModel, IWebcamsConfig } from '../../types';
import { WEBCAMS_DEFAULTS } from '../../runtime';

const props = defineProps<{
  /** Сколько моделей просить у провайдера; по умолчанию — из конфига сайта. */
  limit?: number
  /** Категория/тег провайдера — для тематических блоков. */
  category?: string
}>();

/**
 * Клики и показы тумб блок отдаёт наружу: индексы он знает, а вот куда их
 * отправлять — дело сайта (у статистики свой контекст страницы и устройства).
 */
const emit = defineEmits<{
  'model-click': [payload: { model: IStripcashModel, index: number }]
  'model-view': [payload: { model: IStripcashModel, index: number, element: HTMLElement }]
}>();

const webcamsConfig = computed(() => (useRuntimeConfig().public.webcamsConfig || {}) as IWebcamsConfig);

const { items, counts, isEnabled } = await useFetchWebcams({
  limit: props.limit || webcamsConfig.value.limit || WEBCAMS_DEFAULTS.limit,
  category: props.category,
});

/**
 * Колонок в сетке столько же, сколько в основном гриде сайта на этом
 * брейкпоинте. На сервере ширины нет, поэтому там 0 — «пока не знаем».
 */
const columns = ref(0);

/**
 * Неполную последнюю строку не рисуем: дырок в сетке быть не должно. Пока число
 * колонок неизвестно (сервер), отдаём выдачу целиком — просить у провайдера мы
 * просим 12 моделей, а 12 делится и на 2, и на 3, и на 4, так что в норме резать
 * нечего и контент после гидрации не прыгает. На десктопе эти 12 и дают ровно
 * три линии тумб.
 */
const visibleItems = computed<IStripcashModel[]>(() => {
  const cols = columns.value;
  if (!cols) return items.value;

  return items.value.slice(0, Math.floor(items.value.length / cols) * cols);
});

// те же пороги, что у основного грида (`grid-videos`): xs → 3 колонки, md → 4
const MEDIA_COLUMNS: Array<{ query: string, columns: number }> = [
  { query: '(min-width: 1350px)', columns: 4 },
  { query: '(min-width: 475px)', columns: 3 },
];

function syncColumns() {
  columns.value = MEDIA_COLUMNS.find(item => window.matchMedia(item.query).matches)?.columns || 2;
}

onMounted(() => {
  syncColumns();
  window.addEventListener('resize', syncColumns, { passive: true });
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', syncColumns);
});
</script>

<style lang="scss">
.webcam-main {
  display: grid;
  row-gap: 20px;
  margin-bottom: 40px;
}
</style>
