import React, { useEffect, useState } from 'react'
import {useParams} from 'react-router-dom'
import { UStoreProvider } from '@ustore/core'
import { throttle } from 'throttle-debounce'
import Layout from '../components/layout'
import { Slider, ScrollableGallery } from '$core-components'
import CategoryItem from '../components/category/CategoryItem'
import ProductItem from '../components/products/ProductItem'
import urlGenerator from '$ustoreinternal/services/urlGenerator'
import { t } from '$themelocalization'
import { getIsNGProduct } from '$themeservices'
import { decodeStringForURL } from '$ustoreinternal/services/utils'

import theme from '$styles/_theme.scss'
import './Category.scss'
import Slot from '../components/widgets/Slot';

const PRODUCTS_PAGE_SIZE = 8
const SUB_CATEGORIES_PAGE_SIZE = 200

const clearCustomState = () => {
  UStoreProvider.state.customState.delete('categoryFeaturedProducts')
  UStoreProvider.state.customState.delete('categoryProductsCount')
  UStoreProvider.state.customState.delete('currentCategory')
  UStoreProvider.state.customState.delete('subCategories')
  UStoreProvider.state.customState.delete('currentProduct')
  UStoreProvider.state.customState.delete('currentOrderItem')
  UStoreProvider.state.customState.delete('currentOrderItemId')
  UStoreProvider.state.customState.delete('currentOrderItemPriceModel')
  UStoreProvider.state.customState.delete('lastOrder')
  UStoreProvider.state.customState.delete('currentProductThumbnails')
}


const Category = (props) => {
  const { id: categoryFriendlyID } = useParams()
  const [isMobile, setIsMobile] = useState(false)
  const [categoryID, setCategoryID] = useState(null)
  const [currentCategory, setCurrentCategory] = useState(null)
  const [subCategories, setSubCategories] = useState(null)
  const [categoryFeaturedProducts, setCategoryFeaturedProducts] = useState(null)
  const [categoryProductsCount, setCategoryProductsCount] = useState(null)

  const onResize = throttle(250, () => setIsMobile(document.body.clientWidth < parseInt(theme.md.replace('px', ''))))
  const initialLoad = async () => {
    if (categoryFriendlyID !== currentCategory?.FriendlyID) {
      clearCustomState()
      const newCategoryID = await UStoreProvider.api.categories.getCategoryIDByFriendlyID(categoryFriendlyID)
      setCategoryID(newCategoryID)
      setCurrentCategory(await UStoreProvider.api.categories.getCategory(newCategoryID))
      setSubCategories((await UStoreProvider.api.categories.getSubCategories(newCategoryID, 1, SUB_CATEGORIES_PAGE_SIZE))?.Categories)
      const { Products, Count } = await UStoreProvider.api.products.getProducts(newCategoryID, 1, PRODUCTS_PAGE_SIZE)
      setCategoryFeaturedProducts(Products)
      setCategoryProductsCount(Count)
    }
  }

  const loadProducts = async () => {
    if (!props.customState) {
      return null
    }
    const nextPage = categoryFeaturedProducts ? Math.ceil(categoryFeaturedProducts.length / PRODUCTS_PAGE_SIZE) + 1 : 1
    const { Products: products } = await UStoreProvider.api.products.getProducts(currentCategory?.ID || categoryID, nextPage, PRODUCTS_PAGE_SIZE)
    const joinedProducts = categoryFeaturedProducts ? [...categoryFeaturedProducts, ...products] : products
    setCategoryFeaturedProducts(joinedProducts)
    UStoreProvider.state.customState.set('categoryFeaturedProducts', joinedProducts)
  }

  useEffect(() => {
    (async () => {
      window.addEventListener('resize', onResize)
      await initialLoad()
    })()
    return () => {
      window.removeEventListener('resize', onResize)
      clearCustomState()
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  useEffect(() => {
    (async () => await initialLoad())()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [categoryFriendlyID])

  if (!props.customState) {
    return null
  }
  const galleryTitle =
    categoryProductsCount
      ? subCategories && subCategories.length > 0
        ? t('Category.Count_featured_products', { count: categoryProductsCount })
        : t('Category.Count_products', { count: categoryProductsCount })
      : ''

  const hasMoreItems = categoryFeaturedProducts && categoryFeaturedProducts.length < categoryProductsCount

  return (

    <Layout {...props} className="category">
      <Slot name="category_top" />
      <div className="title" dangerouslySetInnerHTML={{ __html: currentCategory && currentCategory.Name }} />

      {subCategories && subCategories.length > 0 &&
        <div>
          <div className="categories-wrapper">
            <Slider key={currentCategory.ID} multi>
              {
                subCategories.map((model) => {
                    return <CategoryItem key={model.ID} model={model}
                                         url={urlGenerator.get({ page: 'category', id: model.FriendlyID, name: decodeStringForURL(model.Name) })} />
                  }
                )
              }
            </Slider>
          </div>
          <div className="divider" />
        </div>
      }
      {currentCategory && categoryFeaturedProducts && categoryFeaturedProducts.length > 0 &&
        <div>
          <div className="featured-products-wrapper">
            <ScrollableGallery title={galleryTitle} hasMoreItems={hasMoreItems} onScroll={loadProducts}>
              {
                categoryFeaturedProducts.map((model) => {
                  const hideProduct =
                    isMobile &&
                    model.Attributes &&
                    model.Attributes.find(attr => attr.Name === 'UEditEnabled' && attr.Value === 'true') !== undefined

                  return !hideProduct &&
                    <ProductItem
                      key={model.ID}
                      model={model} detailed
                      productNameLines="2"
                      descriptionLines="4"
                      url={getIsNGProduct(model)
                        ? urlGenerator.get({ page: 'products', id: model.FriendlyID, name: decodeStringForURL(model.Name) })
                        : urlGenerator.get({ page: 'product', id: model.FriendlyID, name: decodeStringForURL(model.Name) })
                      }
                    />
                })
              }
            </ScrollableGallery>
          </div>
        </div>
      }
      <Slot name="category_bottom" />
    </Layout>
  )
}

export default Category
