<!-- Главный контейнер фильтра видео: синхронизация с query и применение фильтров -->
<template>
  <div class="filter-main">
    <FilterBtn
      v-model="filterOpen"
      :count="filterCount"
      :theme="buttonTheme"
      :size="buttonSize"
    />

    <transition>
      <LazyFilterPopup
        v-if="filterOpen"
        v-model="filterOpen"
        :title="$t('filter')"
        :active-count="activeCount"
        :active-chips="activeChips"
        :quick="quickFields"
        :groups="groupItems"
        :loading="!scheme.length"
        @chip-click="onChipClick"
        @field-update="onFieldUpdate"
      >
        <template #footer>
          <div class="filter-main__footer-buttons">
            <UiBtn
              :disabled="!isFiltered"
              theme="secondary"
              class="filter-main__reset"
              @click="reset"
            >{{ $t('reset_all') }}
            </UiBtn>
            <UiBtn
              theme="primary"
              @click="saveResult"
            >{{ $t('apply') }}{{ activeCount ? ` (${activeCount})` : '' }}
            </UiBtn>
          </div>
        </template>
      </LazyFilterPopup>
    </transition>
  </div>
</template>

<script setup lang="ts">
import type { ButtonSizes, ButtonThemes, IChipsItem, IFilterScheme, ISelectItem } from '../../types';
import type { LocationQuery } from '#vue-router';
import { parseFilterCategories } from '../../utils/parse-filter-categories';
import { parseCategoryFilterValues } from '../../utils/filter-main/parse-category-filter-values';
import { getActiveFilterValues } from '../../utils/filter-main/get-active-filter-values';
import { buildFilterQuery } from '../../utils/filter-main/build-filter-query';

const props = defineProps<{
  scheme: IFilterScheme[]
  addedItems: ISelectItem[]
  durationItems: ISelectItem[]
  buttonSize?: ButtonSizes
  buttonTheme?: ButtonThemes
}>();

const emit = defineEmits<{
  (e: 'open'): void
}>();

const { t } = useI18n();
const route = useRoute();
const router = useRouter();

const filterOpen = ref(false);

const durationValue = ref('');
const addedValue = ref('');
const filterValue = ref({} as Record<string, string>);

function syncFromQuery(query: LocationQuery) {
  filterValue.value = parseCategoryFilterValues(parseFilterCategories(query));
  durationValue.value = (query.duration as string) || '';
  addedValue.value = (query.added as string) || '';
}

syncFromQuery(route.query);

watch(() => route.query, (q) => syncFromQuery(q));

watch(filterOpen, (value) => {
  if (value) emit('open');
});

const filterCount = ref(0);
filterCount.value = getActiveFilterValues(route.query).length;
watch(() => route.query, (value) => {
  filterCount.value = getActiveFilterValues(value).length;
});

const activeCount = computed(() => {
  const hasDuration = durationValue.value ? 1 : 0;
  const hasAdded = addedValue.value ? 1 : 0;
  return Object.keys(filterValue.value).length + hasAdded + hasDuration;
});

const isFiltered = computed(() => !!route.query['categories'] || Object.keys(filterValue.value).length > 0 || !!durationValue.value || !!addedValue.value);

const QUICK_NAMES = ['action', 'guy type', 'ppl involved', 'ethnicity & nationality'];
const PERFORMER_NAMES = [
  'age',
  'cock size & type',
  'body shape',
  'hair',
  'body part',
  'skin & body decoration',
  'sexual orientation',
  'family affiliation',
  'attitude',
  'cultural affiliation',
  'professional affiliation',
  'interracial',
];
const SCENE_NAMES = [
  'sex position',
  'location inside',
  'location outside',
  'bdsm',
  'fetish',
  'sex toys',
  'object insertion',
  'clothing',
  'roleplay',
  'sport',
  'anime',
  'holiday',
  'transport',
];

function pickByNames(names: string[]): IFilterScheme[] {
  return names
      .map(n => props.scheme.find(s => s.name.toLowerCase() === n))
      .filter((item): item is IFilterScheme => Boolean(item));
}

const quickScheme = computed(() => pickByNames(QUICK_NAMES));

function schemeToField(item: IFilterScheme) {
  const key = item.name.toLowerCase();
  return {
    name: key,
    title: item.title || item.name,
    label: (item as any).label,
    value: filterValue.value[key] ?? '',
    items: item.items,
    active: !!filterValue.value[key],
    icon: (item as any).icon,
    placeholder: (item as any).placeholder ?? t('select'),
  };
}

const quickFields = computed(() => quickScheme.value.map(schemeToField));

type VideoField =
    | ReturnType<typeof schemeToField>
    | { kind: 'duration', name: string, title: string, value: string, items: ISelectItem[], active: boolean }
    | { kind: 'added', name: string, title: string, value: string, items: ISelectItem[], active: boolean };

function translateTitle(array: ISelectItem[]) {
  return array.map((item: ISelectItem) => ({
    title: t(item.title),
    key: item.key,
    value: item.value,
  }));
}

const groupItems = computed(() => {
  const performer = pickByNames(PERFORMER_NAMES).map(schemeToField);
  const scene = pickByNames(SCENE_NAMES).map(schemeToField);
  const used = new Set([...QUICK_NAMES, ...PERFORMER_NAMES, ...SCENE_NAMES]);
  const other = props.scheme.filter(s => !used.has(s.name.toLowerCase())).map(schemeToField);

  const videoFields: VideoField[] = [
    {
      kind: 'duration',
      name: 'duration',
      title: t('duration'),
      label: t('duration'),
      value: durationValue.value,
      items: translateTitle(props.durationItems),
      active: !!durationValue.value,
      icon: 'time',
      placeholder: t('select'),
    } as any,
    {
      kind: 'added',
      name: 'added',
      title: t('added'),
      label: t('added'),
      value: addedValue.value,
      items: translateTitle(props.addedItems),
      active: !!addedValue.value,
      icon: 'date',
      placeholder: t('select'),
    } as any,
    ...other,
  ];

  return [
    { key: 'performer', title: t('filter_popup.performer.title'), description: t('filter_popup.performer.description'), count: performer.length, fields: performer },
    { key: 'scene', title: t('filter_popup.scene.title'), description: t('filter_popup.scene.description'), count: scene.length, fields: scene },
    { key: 'video', title: t('filter_popup.video_info.title'), description: t('filter_popup.video_info.description'), count: videoFields.length, fields: videoFields },
  ];
});

const DURATION_CHIP_KEY = '__duration';
const ADDED_CHIP_KEY = '__added';

const activeChips = computed<IChipsItem[]>(() => {
  const chips: IChipsItem[] = [];

  for (const str of parseFilterCategories(route.query)) {
    const [key, ...rest] = str.split('_');
    const value = rest.join('_');
    if (!key || !value) continue;
    const schemeItem = props.scheme.find(s => s.name.toLowerCase() === key);
    const matched = schemeItem?.items.find(i => i.value === value);
    chips.push({ title: matched?.title || value, key });
  }

  const duration = route.query.duration as string;
  if (duration) {
    const item = props.durationItems.find(i => i.value === duration);
    chips.push({ title: item?.title ? t(item.title) : duration, key: DURATION_CHIP_KEY });
  }

  const added = route.query.added as string;
  if (added) {
    const item = props.addedItems.find(i => i.value === added);
    chips.push({ title: item?.title ? t(item.title) : added, key: ADDED_CHIP_KEY });
  }

  return chips;
});

function onChipClick(item: IChipsItem) {
  const nextQuery = { ...route.query };
  delete nextQuery.page;

  if (item.key === DURATION_CHIP_KEY) {
    delete nextQuery.duration;
  } else if (item.key === ADDED_CHIP_KEY) {
    delete nextQuery.added;
  } else if (item.key) {
    const remaining = parseFilterCategories(route.query).filter(str => {
      const [k] = str.split('_');
      return k !== item.key;
    });
    if (remaining.length) {
      nextQuery.categories = remaining.join(',');
    } else {
      delete nextQuery.categories;
    }
  }

  router.push({ query: nextQuery });
}

function onFieldUpdate({ name, value }: { name: string, value: any }) {
  if (name === 'duration') {
    durationValue.value = value;
  } else if (name === 'added') {
    addedValue.value = value;
  } else {
    if (!value) {
      const next = { ...filterValue.value };
      delete next[name];
      filterValue.value = next;
    } else {
      filterValue.value = { ...filterValue.value, [name]: value };
    }
  }
}

function saveResult() {
  router.push({
    query: buildFilterQuery({
      currentQuery: route.query,
      filterValue: filterValue.value,
      durationValue: durationValue.value,
      addedValue: addedValue.value,
    }),
  });

  filterOpen.value = false;
}

function reset() {
  durationValue.value = '';
  addedValue.value = '';
  filterValue.value = {};
  router.push({ query: { categories: null } });
}
</script>

<style lang="scss">
.filter-main__footer-buttons {
  display: flex;
  justify-content: space-between;
  column-gap: 8px;
}

.filter-main__reset {
  @include button-variant(filter-reset)
}
</style>
