<!-- Фильтр моделей, развёрнутый на отдельной странице (без модалки, в отличие от popup) -->
<template>
  <div class="filter-page">
    <div class="filter-page__items-wrapper">
      <h2
        v-if="title"
        class="filter-page__title"
      >{{ title }}
      </h2>
      <div
        v-for="(group, index) in groups"
        :key="`filter-group-${index}`"
        :class="{'--short': group.name === 'tags'}"
        class="filter-page__group"
      >
        <div
          v-if="filters.length > 0"
          class="filter-page__group-header"
        >
          <span class="filter-page__group-title">
            {{ group?.title }}
          </span>
          <UiSegmented
            v-if="group?.name === 'physical'"
            :items="unitItems"
            :model-value="units"
            small
            @update:model-value="units = $event"
          />
        </div>
        <div
          v-if="getGroupSliders(group?.name).length > 1"
          :style="{ '--slider-count': getGroupSliders(group?.name).length }"
          class="filter-page__sliders"
        >
          <FilterSlider
            v-for="(item, subIndex) in getGroupSliders(group?.name)"
            :key="`slider-${subIndex}`"
            :item="item"
            :group-name="item.group.name"
            :index="subIndex"
          />
        </div>
        <div class="filter-page__items">
          <template
            v-for="(item, subIndex) in filters"
            :key="`model-filter-${subIndex}`"
          >
            <FilterSlider
              v-if="(item.kind === 'range') && (item.group.name === group?.name) && !hiddenByUnits.has(item.name) && getGroupSliders(group?.name).length === 1"
              :item="item"
              :group-name="item.group.name"
              :index="subIndex"
              class="filter-page__slider"
            />
            <UiSelect
              v-if="(item.kind === 'select') && (item.group.name === group?.name) && !hiddenByUnits.has(item.name)"
              :name="item.name"
              :model-value="getValue(item.name)"
              :items="selectItems(item)"
              :active="isActiveSelect(item.name)"
              :label="item.title"
              class="filter-page__select"
              size="s"
              @update:model-value="val => updateFilter(item.name, val)"
            />
            <UiSegmented
              v-if="(item.kind === 'radio') && (item.group.name === group?.name)"
              :items="getRadioItems(item.options)"
              :title="item.title"
              :model-value="getValue(item.name)"
              class="filter-page__radio"
              @update:model-value="val => updateFilter(item.name, val)"
            />
          </template>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { IModelFilter } from '../../types';

import { useRoute, useRouter } from 'vue-router';
import { sortFilterRadioOptions } from '../../utils/sort-filter-radio-options';
import { getSortedFilterGroups } from '../../utils/get-sorted-filter-groups';

const props = defineProps<{
  filters: IModelFilter[]
  count: number
  title?: string
}>();

const route = useRoute();
const router = useRouter();

const { t } = useI18n();

const { units, hiddenByUnits } = useUnits();

watch(units, () => {
  const query = { ...route.query };
  const unitFields = ['height_cm', 'height_in', 'weight_kg', 'weight_lb'];
  for (const field of unitFields) {
    delete query[`filter_${field}_from`];
    delete query[`filter_${field}_to`];
  }
  router.replace({ query });
});

const unitItems = computed(() => [
  { name: 'imperial', title: t('units_imperial'), quantity: 0 },
  { name: 'metric', title: t('units_metric'), quantity: 0 },
]);

const groups = computed(() => getSortedFilterGroups(props.filters));

function getGroupSliders(groupName: string) {
  return props.filters.filter(
    (item) => item.kind === 'range' && item.group.name === groupName && !hiddenByUnits.value.has(item.name)
  );
}

function selectItems(item: IModelFilter) {
  return [
    ...item.options.map(item => ({
      value: item.name,
      title: `${item.title} (${item.quantity})`,
    }))
  ];
}

function updateFilter(name: string, val: any) {
  const query = { ...route.query };

  if (!val || val === 'all') {
    delete query[ `filter_${name}` ];
  } else {
    query[ `filter_${name}` ] = val;
  }

  router.replace({ query });
}

function isActiveSelect(name: string) {
  const baseName = name.replace(/_(from|to)$/, '');
  return Object.keys(route.query).some(key => key.startsWith(`filter_${baseName}`));
}

function getValue(name: string) {
  const value = route.query[ `filter_${name}` ];
  if (value) {
    return value;
  }
  const filter = props.filters.find(f => f.name === name);
  if (filter && filter.options.length > 0) {
    return filter.options[ 0 ].name;
  }
  return null;
}

function getRadioItems(items: IModelFilter['options']) {
  return sortFilterRadioOptions(items);
}
</script>
