<template>
  <!-- <SectionShopPageCurrencyRatesBar
    class="mb-[25px] sm:mb-[55px] xl:mb-[75px]"
  /> -->
  <UiContainer>
    <div class="flex flex-col gap-[25px] sm:gap-10 xl:flex-row">
      <!-- button to open categories -->
      <div class="xl:hidden flex items-center w-full">
        <button
          class="h-[40px] w-full cursor-pointer rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px] bg-button text-text-dark group-hover:bg-button-hover"
          @click="openCategories = !openCategories">
          Otevřené kategorie a filtry
        </button>
      </div>

      <Transition>
        <div v-if="openCategories" class="min-w-[250px] px-5 sm:p-0 xl:hidden">
          <h1 class="font-bounded leading-[140%] font-bold text-[24px] mb-[25px]">
            {{ $t("category") }}
          </h1>
          <div class="flex flex-col gap-[25px]">
            <div>
              <div v-if="categoriesList && categoriesList.length < 1" class="animate-pulse">
                <div class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24">
                  <div class="w-32 h-4 bg-gray-200 rounded" />
                  <div class="w-4 h-4 bg-gray-200 rounded-full" />
                </div>
              </div>
              <CategoryTree :data="categoriesList" :active="categoryId" @change-category="changeCategory($event)" />
            </div>
            <div>
              <p class="mb-[25px] text-lg font-extrabold text-black dark:text-white">
                {{ $t("filtered_by") }}
              </p>

              <div v-for="(item, itemIndex) in filters" :key="itemIndex" :class="[
                'mb-[30px]',
                visibleFeatures[item.feature] && 'border-b border-block pb-2',
              ]">
                <span class="flex justify-between items-center font-bold cursor-pointer mb-[25px] text-base"
                      @click="toggleFeature(item.feature)">
                  {{ item.feature }}
                  <span :class="[
                    visibleFeatures[item.feature] && 'rotate-180',
                    'transition-all',
                  ]"><i class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto" /></span>
                </span>
                <ul v-show="visibleFeatures[item.feature]" class="flex flex-col gap-5">
                  <li v-for="filter in item.feature_values" :key="filter.value_id"
                      class="flex items-center gap-[10px] cursor-pointer">
                    <input :id="`${filter.value_id}`" v-model="selectedFilters"
                           :value="`${filter.parent}.${filter.value_id}`" type="checkbox" class="border-button !bg-inherit">
                    <label :for="`${filter.value_id}`"
                           class="cursor-pointer flex items-center justify-between w-full text-base">
                      <span>{{ filter.value }}</span>
                      <span>12</span>
                    </label>
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </Transition>

      <!-- categories -->
      <div class="min-w-[250px] hidden xl:block">
        <h1 class="font-bounded leading-[140%] font-bold text-[40px] mb-[55px]">
          {{ $t("category") }}
        </h1>
        <div class="flex flex-col gap-12">
          <div>
            <div v-if="categoriesList && categoriesList.length < 1" class="animate-pulse">
              <div class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24">
                <div class="w-32 h-4 bg-gray-200 rounded" />
                <div class="w-4 h-4 bg-gray-200 rounded-full" />
              </div>
            </div>
            <CategoryTree :data="categoriesList" :active="categoryId" @change-category="changeCategory($event)" />
          </div>
          <div>
            <p class="mb-10 text-2xl font-extrabold text-black dark:text-white">
              {{ $t("filtered_by") }}
            </p>

            <!-- <div v-if="filters.length < 1" class="mb-8 text-white animate-pulse">
                            <div v-for="i in 5"
                                class="mt-10 flex justify-between font-bold text-black cursor-pointer 2xl:pr-24 dark:text-gray">
                                <div class="w-32 h-4 bg-gray-200 rounded"></div>
                                <div class="w-4 h-4 bg-gray-200 rounded"></div>
                            </div>
                        </div> -->

            <div v-for="(item, itemIndex) in filters" :key="itemIndex" :class="[
              'mb-[30px]',
              visibleFeatures[item.feature] && 'border-b border-block pb-2',
            ]">
              <span class="flex justify-between items-center font-bold cursor-pointer mb-[25px]"
                    @click="toggleFeature(item.feature)">
                {{ item.feature }}
                <span :class="[
                  visibleFeatures[item.feature] && 'rotate-180',
                  'transition-all',
                ]"><i class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto" /></span>
              </span>
              <ul v-show="visibleFeatures[item.feature]" class="flex flex-col gap-5">
                <li v-for="filter in item.feature_values" :key="filter.value_id"
                    class="flex items-center gap-[10px] cursor-pointer">
                  <!-- <input :id="`${filter.value_id}`" :value="`${filter.parent}.${filter.value_id}`"
                                        v-model="selectedFilters" type="checkbox" class="border-button !bg-inherit" />
                                    <label :for="`${filter.value_id}`" class="cursor-pointer">{{ filter.value }}</label> -->

                  <input :id="`${filter.value_id}`" v-model="selectedFilters"
                         :value="`${filter.parent}.${filter.value_id}`" type="checkbox" class="border-button !bg-inherit">
                  <label :for="`${filter.value_id}`" class="cursor-pointer flex items-center justify-between w-full">
                    <span>{{ filter.value }}</span>
                    <span>12</span>
                  </label>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>

      <div class="w-full space-y-10">
        <!-- pop-up -->
        <div v-if="isInfo"
             class="w-full xl:w-[70%] mx-auto border-y border-block py-[15px] sm:p-[30px] flex gap-[55px] relative">
          <UButton variant="ghost"
                   class="p-0 absolute right-0 top-2 sm:right-2 sm:top-2 cursor-pointer text-button font-light hover:bg-inherit hover:text-button-hover"
                   size="xl" icon="i-lucide-x" @click="closeElement()" />

          <div class="flex flex-col sm:flex-row gap-[25px]">
            <div class="flex flex-col justify-between gap-[25px]">
              <h4 class="font-inter text-lg sm:text-[24px] leading-[150%] md:leading-[120%] font-bold">
                {{ component.front_section_lang[0].data.title }}
              </h4>
              <p>{{ component.front_section_lang[0].data.description }}</p>
            </div>
            <img class="max-w-[150px] mx-auto" :src="`/api/public/file/${component.img[0]}_m.webp')`">
          </div>
        </div>

        <div v-if="products.length < 1" class="grid gap-12 pt-32 pb-16 md:grid-cols-2 2xl:grid-cols-3">
          <!-- <TheProductSkeleton v-for="index in 6" :key="index" /> -->
        </div>

        <!-- products -->
        <div v-else ref="loadingElement" class="flex flex-wrap justify-center gap-5 sm:gap-10">
          <Product v-for="product in products" :key="product.id" :product="product" />
        </div>

        <div v-if="reachedEnd" class="w-full flex justify-center">
          <p>
            {{ $t("FrontTranslations", "You reached end of the list.") }}
          </p>
        </div>
      </div>
    </div>
  </UiContainer>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import Product from './Product.vue'
import CategoryTree from './CategoryTree.vue'
import type {
  Feature,
  GenericResponse,
  GenericResponseChildren,
  GenericResponseItems,
  ProductType,
} from '~/types'

const { $session } = useNuxtApp()

watch(
  () => $session.cookieData,
  async () => await getProducts(),
  { deep: true },
)
defineProps<{
  component: {
    id: number
    name: string
    img: string[]
    component_name: string
    is_no_lang: boolean
    page_name: string
    front_section_lang: {
      data: {
        title: string
        description: string
      }
      id_front_section: number
      id_lang: number
    }[]
  }
}>()

const openCategories = ref(false)
const isInfo = ref<boolean>(true)
const selectedFilters = ref<string[]>([])
const categoryId = ref<number>(1)

const loading = ref(false)
const reachedEnd = ref(false)

const loadingElement = ref<HTMLElement | null>(null)

const page = ref(1)
const elems = ref(12)
const maxElements = ref(0)

const products = ref([] as ProductType[])
async function getProducts() {
  try {
    const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
      `/api/public/products/category/${categoryId.value}?p=${page.value}&elems=${elems.value}`,
      {
        headers: {
          'Content-Type': 'application/json',
        },
        onErrorOccured: (_, status) => {
          throw new Error(`HTTP error: ${status}`)
        },
      },
    )

    products.value = data.items
    maxElements.value = data.items_count + 1
  }
  catch (error) {
    console.error('getProducts error:', error)
  }
}

const filters = ref([] as Feature[])
async function getCategory() {
  try {
    const { data } = await useMyFetch<GenericResponse<object>>(
      `/api/public/products/category/1/classification`,
      {
        headers: {
          'Content-Type': 'application/json',
        },
        onErrorOccured: (_, status) => {
          throw new Error(`HTTP error: ${status}`)
        },
      },
    )

    filters.value = data as Feature[]
    filters.value.forEach((el: Feature) => {
      const parentId = el.feature_id
      el.feature_values.forEach((el) => {
        el.parent = parentId
      })
    })
  }
  catch (error) {
    console.error('getCategory error:', error)
  }
}

const categoriesList = ref()
async function getCategoryTree() {
  try {
    const { data } = await useMyFetch<GenericResponseChildren<ProductType[]>>(
      `/api/public/categories/tree`,
      {
        headers: {
          'Content-Type': 'application/json',
        },
        onErrorOccured: (_, status) => {
          throw new Error(`HTTP error: ${status}`)
        },
      },
    )

    categoriesList.value = data.children
  }
  catch (error) {
    console.error('getCategory error:', error)
  }
}

getProducts()
getCategory()
getCategoryTree()

const closeElement = () => {
  isInfo.value = false
}

onMounted(() => {
  window.addEventListener('scroll', scrollEvent)
})

onUnmounted(() => {
  window.removeEventListener('scroll', scrollEvent)
})

async function scrollEvent() {
  const maxScrollY
    = window.scrollY
      || document.documentElement.scrollHeight
      - document.documentElement.clientHeight

  if (
    window.scrollY >= maxScrollY - 500
    && !reachedEnd.value
    && !loading.value
  ) {
    loading.value = true
    await loadMoreProducts()
    loading.value = false
  }
}

filters.value.forEach((item) => {
  visibleFeatures[item.feature] = false
})

const visibleFeatures = reactive<Record<string, boolean>>({})
function toggleFeature(feature: string) {
  if (feature in visibleFeatures) {
    visibleFeatures[feature] = !visibleFeatures[feature]
  }
  else {
    visibleFeatures[feature] = true
  }
}

class FilteredQueryString extends URLSearchParams {
  override append(name: string, value: string): void {
    if (value == null) {
      return
    }

    super.append(name, value)
  }
}

async function loadMoreProducts() {
  const qParams = new FilteredQueryString()

  page.value = page.value + 1

  qParams.append('p', `${page.value}`)
  qParams.append('elems', `${elems.value}`)
  qParams.append('features', selectedFilters.value.length > 0 ? `${selectedFilters.value}` : '')

  try {
    const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
      `/api/public/products/category/${categoryId.value}?${qParams.toString()}`,
      {
        headers: {
          'Content-Type': 'application/json',
        },
        onErrorOccured: (_, status) => {
          throw new Error(`HTTP error: ${status}`)
        },
      },
    )

    maxElements.value = data.items_count

    if (data.items) {
      products.value.push(...(data.items as ProductType[]))
    }
    else {
      reachedEnd.value = true
    }

    if (products.value.length >= maxElements.value) {
      reachedEnd.value = true
    }
  }
  catch (error) {
    console.error('getCategory error:', error)
  }
}

interface CategoryItem {
  id: number
  name: string
}

const changeCategory = (item: CategoryItem) => {
  categoryId.value = item.id
}

watch(selectedFilters, async (newQuestion) => {
  if (newQuestion) {
    page.value = 1
    reachedEnd.value = false
    loadingElement.value?.scrollIntoView()

    const qParams = new FilteredQueryString()

    qParams.append('p', `${page.value}`)
    qParams.append('elems', `${elems.value}`)
    qParams.append(
      'features',
      selectedFilters.value.length > 0 ? `${selectedFilters.value}` : '',
    )

    try {
      const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
        `/api/public/products/category/1?${qParams.toString()}`,
        {
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: (_, status) => {
            throw new Error(`HTTP error: ${status}`)
          },
        },
      )

      products.value = data.items
      maxElements.value = data.items_count
    }
    catch (error) {
      console.error('selectedFilters error:', error)
    }
  }
})

watch(categoryId, async (newCategoryId) => {
  if (newCategoryId) {
    page.value = 1
    reachedEnd.value = false
    loadingElement.value?.scrollIntoView()

    const qParams = new FilteredQueryString()
    qParams.append('p', `${page.value}`)
    qParams.append('elems', `${elems.value}`)
    qParams.append(
      'features',
      selectedFilters.value.length > 0 ? `${selectedFilters.value}` : '',
    )

    try {
      const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
        `api/public/products/category/${newCategoryId}?${qParams.toString()}`,
        {
          headers: { 'Content-Type': 'application/json' },
          onErrorOccured: (_, status) => {
            throw new Error(`HTTP error: ${status}`)
          },
        },
      )

      products.value = data.items
      maxElements.value = data.items_count
    }
    catch (error) {
      console.error('getCategory error:', error)
    }
  }
})
</script>

<style scoped>
.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}
</style>
