<!-- Страница одного видео: плеер, заголовок с моделями/тегами, похожие -->
<template>
  <div class="view-video _page _container">
    <header class="view-video__header">
      <h1 class="view-video__title">
        <span class="_truncate">{{ data.title }}</span>
      </h1>
      <div class="view-video__header-wrapper">
        <UiExpandRow
          v-if="topChips && topChips.length > 0"
          :items="topChips"
          class="view-video__header-categories"
        >
          <template #prepend>
            <PlayerChannel
              v-if="data.channelName"
              :name="data.channelName"
              :avatar="data.channelAvatar"
              :subscribers-count="12500"
            />
            <template v-if="data.models">
              <UiChips
                v-for="(model, index) in data.models"
                :key="index"
                :item="getModelChips(model, index)"
                is-link
              />
            </template>
          </template>
        </UiExpandRow>
      </div>
    </header>

    <PlayerMain
      :data="data"
      :loading="statusVideo === 'pending'"
      :status-aside="statusAside"
      :suggested-videos="suggestedVideos"
      :base-path="basePath"
      class="view-video__video"
      @end="emit('end')"
    >
      <slot/>
    </PlayerMain>

    <section
      v-if="related"
      :class="{'_loading': status === 'pending'}"
      class="view-video__related"
    >
      <h2 class="view-video__subtitle">{{ t('related_videos') }}</h2>

      <LazyGridVideos
        related
        :hide-first-row="page !== 'playlist'"
        :items="related"
        :top-chips="topChipsStrings"
        :hydrate-on-visible="HYDRATE_MARGIN"
      >
        <template #grid-start>
          <LazyAdvNativePlayer
            v-if="featureFlags.AdsNativeEnabled"
            hydrate-on-visible
          />
        </template>

        <template #grid-end>
          <LazyAdvNativeBottom
            v-if="featureFlags.AdsNativeEnabled"
            hydrate-on-visible
          />
        </template>
      </LazyGridVideos>
    </section>

    <LazyUiPagination
      v-if="total"
      arrow-icon
      :key="`pagination-${total}`"
      :total="total"
      :limit="10"
      class="view-video__pagination _pagination"
      hydrate-on-visible
    />

    <LazySectionSwiperCards
      v-if="models"
      :items="modelsRoundCards"
      class="view-video__popular-models"
      placeholder-avatar="/img/model-placeholder.webp"
      hydrate-on-visible
    >
      {{ $t('related_models')}}
    </LazySectionSwiperCards>

    <section
      v-if="recentSearches && recentSearches.length > 0"
      class="view-video__referer"
    >
      <h2 class="view-video__subtitle">{{ t('recent_searches') }}</h2>
      <LazyUiExpandRow
        :items="recentSearches"
        mobile-expand
        hydrate-on-visible
      />
    </section>
  </div>
</template>

<script setup lang="ts">
import type { IChipsItem, IModelCard, IVideoCard, IVideoData, PaginatedResponse } from '../../types';
import { convertModelToRoundCard } from '../../runtime';
import type { AsyncDataRequestStatus } from '#app';

const featureFlags = useRuntimeConfig().public.featureFlags;

/** Запас гидрации релейтед-грида: без него тап по карточке у нижнего края экрана уходит по негидрированной разметке. */
const HYDRATE_MARGIN = { rootMargin: '300px' };

const props = defineProps<{
  related?: Array<IVideoCard> | undefined,
  status: AsyncDataRequestStatus
  data: IVideoData
  total?: number
  title?: string
  models?: IModelCard[]
  page?: string
  chips?: string[]
  recent?: string[] | null
  statusVideo: AsyncDataRequestStatus
  suggestedVideos?: PaginatedResponse<IVideoCard> | null
  statusAside?: AsyncDataRequestStatus
  basePath?: string
}>();

const { t } = useI18n();

const modelsRoundCards = computed(() =>
    props.models?.map(convertModelToRoundCard) || []
);

const emit = defineEmits<{
  (eventName: 'end'): void
}>();

const tagChips = computed((): IChipsItem[] => props.data.tags?.map((item) => ({
  title: item,
  value: item,
  prefix: 'tag',
})) ?? []);

const categoriesChips = computed((): IChipsItem[] => props.data.categories && props.data.categories?.map((item) => ({
  title: item.title,
  value: item.name,
  image: item.icon ? `/icons/flags/${item.icon}.svg` : undefined,
  imageFit: 'contain',
  prefix: 'categories',
})));

const categoriesTitles = computed<string[]>(() => props.data.categories && props.data.categories?.map(item => item.title?.replace(/\s+/g, '').toLowerCase() ?? ''));

const filterTagChips = computed(() => {
  if (categoriesTitles.value && categoriesTitles.value.length > 0) {
    return tagChips.value.filter(tagItem => !categoriesTitles.value.includes(tagItem.title.replace(/\s+/g, '').toLowerCase()));
  } else {
    return tagChips.value;
  }
});

const recentSearches = computed(() => {
  if (props.recent && typeof props.recent === 'object' && Object.keys(props.recent).length === 0) {
    return [];
  }
  return props.recent?.map((item: string) => ({
    value: item,
    title: item,
    prefix: 'search',
  } as IChipsItem));
});

const topChips = computed(() => {
  if (props.chips && props.chips.length > 0) {
    return props.chips?.map((item: string) => ({
      value: item,
      title: item,
      prefix: 'search',
    } as IChipsItem));
  } else if (categoriesChips.value || filterTagChips.value) {
    return [...categoriesChips.value || [], ...filterTagChips.value || []];
  }
  return null;
});

const topChipsStrings = computed(() => topChips.value?.map(item => item.value));

const testModelImages = [
  '/img/models/Austin_Young.png',
  '/img/models/Dakota_Lovell.png',
  '/img/models/Devin_Franco.png',
  '/img/models/Falcon_Al.png',
  '/img/models/Jax_Thirio.png',
  '/img/models/LeGrand_Wolf.png',
  '/img/models/Oliver_Strelly.png',
  '/img/models/Roman_Todd.png',
  '/img/models/Sebastian _Kane.png',
];

function getModelChips(model: IVideoData['models'][number], index: number): IChipsItem {
  return {
    prefix: '/models',
    value: model.title,
    title: model.title,
    image: testModelImages[index % testModelImages.length],
  };
}
</script>

<style lang="scss">
.view-video__related {
  display: grid;
}

.view-video__subtitle,
.view-video__title {
  @include font-lg;

  font-weight: 700;
}

.view-video__title {
  --line-clamp: 2;

  display: flex;
  align-items: center;
  column-gap: 8px;
  margin-bottom: 12px;
}

.view-video__subtitle {
  text-transform: uppercase;
  margin-bottom: 24px;
  letter-spacing: var(--tracking-wide);
}

.view-video__header-wrapper {
  margin-bottom: 16px;
}

.ui-pagination.view-video__pagination {
  padding-bottom: 12px;
  margin-top: 32px;
}

.view-video__popular-models {
  margin-top: 32px;
}

.view-video__video-aside {
  @include from-br(md) {
    display: flex;
    flex-direction: column;
    height: 100%;
  }
}

.view-videos__top-categories {
  margin-top: auto;
  padding-top: 32px;
}
</style>
