import { fetchCsv } from '#amidala/wcs/shared/filtered-data/fetch-data.js'
import FilteredData from '#amidala/wcs/shared/filtered-data/filtered-data.js'
import ICON_BACK from './icon-back.svg'
import ICON_CART from './icon-cart.svg'
import ICON_CLOSE from './icon-close.svg'

const { h, matter, preactHooks, register } = globalThis.ami
const { Box, Button, Card, Heading, Popup, RichText, Scroller } = matter
const { useEffect, useRef, useState } = preactHooks

const LABELS = {
  CATEGORY: 'Nach Kategorie filtern',
  ORDER_BY: 'Sortieren nach',
  LOAD_MORE: 'Mehr laden',
  RESET_FILTERS: 'Filter zurücksetzen',
  ASCENDING: 'aufsteigend',
  DESCENDING: 'absteigend',
  ALL_CATEGORIES: 'Alle Prämienkategorien',
  POINTS: 'Punkte',
  BACK_TO_OVERVIEW: 'Zurück zur übersicht',
  LEARN_MORE: 'Mehr erfahren'
}
const IMG_SIZE = { width: 320, height: 320 }
const FORWARD_URL = 'https://www.acinguiuxsmart.com/smart/reward?site=de-de&code='

// -----------------------------------------------------------------------------
// Data fetch utilities
// -----------------------------------------------------------------------------

async function getData ({ src, imageRoot }) {
  const products = await fetchCsv(src)
  const sanitizedImageRoot = (imageRoot ?? '').replace(/\/$/, '')
  parseProducts(products, sanitizedImageRoot)

  return products
}

function parseProducts (products, imageRoot) {
  for (const product of products) {
    product.IMAGE = `${imageRoot}/${product.GIFT_CODE}.jpg`
    product[LABELS.POINTS] = Number.parseInt(product.POINTS, 10) || ''
  }
}

// -----------------------------------------------------------------------------
// Common presentation components (item)
// -----------------------------------------------------------------------------

function Item ({ product, role }) {
  const [isOpen, setIsOpen] = useState(false)
  const cardRef = useRef(null)

  const closePopup = () => {
    setIsOpen(false)
    cardRef.current?.focus()
  }

  return h('div', { className: 'animate-fade h-full', role },
    h(Card, {
      key: product.GIFT_CODE,
      tabindex: 0,
      ref: cardRef,
      onClick: event => {
        cardRef.current = event.currentTarget
        setIsOpen(true)
      },
      onKeyDown: event => event.key === 'Enter' && event.currentTarget.click(),
      children: h('div',
        h(ProductAsset, { product }),
        h('div', { className: 'sm:col-span-1' },
          h(Box,
            h('span', product.BRAND),
            h(Heading, { _level: '3' }, product.GIFT_NAME),
            h('p', product.CATEGORY_NAME)
          )
        )
      )
    }),
    h(Popup, {
      onKeyDown: event => event.key === 'Escape' && closePopup(),
      _show: isOpen,
      _layout: 'center',
      children: isOpen && [
        h('div', { className: 'flex gap-2' },
          h('div', { className: 'grow' },
            h(Heading, { _level: '3', className: 'pr-10' }, product.GIFT_NAME)
          ),
          h('div', { className: 'shrink-0' },
            h(Button, {
              _variant: 'plain',
              _textless: true,
              _size: 'xs',
              _model: {
                name: LABELS.BACK_TO_OVERVIEW,
                value: '#',
                icon: ICON_CLOSE
              },
              onClick: event => {
                event.preventDefault()
                closePopup()
              }
            })
          )
        ),
        h(ProductAsset, { product, className: 'rounded-lg overflow-hidden' }),
        h(Heading, { _level: '5' }, product.BRAND),
        h(RichText, product.DESCRIPTION),
        h('div', { className: 'flex gap-5 sm:flex-wrap' },
          h(Button, {
            _size: 'sm',
            _model: {
              name: LABELS.BACK_TO_OVERVIEW,
              value: '#',
              icon: ICON_BACK
            },
            onClick: event => {
              event.preventDefault()
              closePopup()
            }
          }),
          h(Button, {
            target: '_blank',
            rel: 'noopener',
            _size: 'sm',
            _model: {
              name: LABELS.LEARN_MORE,
              value: `${FORWARD_URL}${product.GIFT_CODE}`,
              icon: ICON_CART
            }
          })
        )
      ]
    })
  )
}

function ProductAsset ({ product, className = '' }) {
  return h('div', { className },
    h('img', { src: product.IMAGE, alt: product.GIFT_NAME, className: 'block object-cover w-full h-auto', loading: 'lazy', ...IMG_SIZE }),
    h('div', { className: 'relative' },
      h('div', { className: 'bg-bgb text-txb absolute bottom-3 left-3 pt-2 pb-2 pl-3 pr-3 rounded-lg font-bold' },
        `${product.POINTS} ${LABELS.POINTS}`
      )
    )
  )
}

// -----------------------------------------------------------------------------
// Default variant (via Filtered data): items
// -----------------------------------------------------------------------------

function Items ({ items }) {
  return h('div', { className: 'grid gap-5 grid-cols-4 md:grid-cols-2 sm:grid-cols-1', role: 'list' }, items.map(product =>
    h(Item, { product, role: 'listitem' })
  ))
}

// -----------------------------------------------------------------------------
// Slider variant: items
// -----------------------------------------------------------------------------

function Slider ({ src, imageRoot }) {
  const [items, setItems] = useState([])

  useEffect(() => {
    getData({ src, imageRoot }).then(setItems)
  }, [])

  return h(Scroller, {
    // Remove gap; shadow compensation is enough.
    _style: id => `${id} [role="list"] { gap: 0 }`,
    // Compensate for shadow.
    children: items.map(product => h('div', { style: 'padding: 10px' },
      h(Item, { product })
    ))
  })
}

// -----------------------------------------------------------------------------
// Main component, custom element definition
// -----------------------------------------------------------------------------

function ProductCatalogue ({ src, 'image-root': imageRoot, variant }) {
  if (!src) {
    return null
  }

  if (variant === 'slider') {
    return h(Slider, { src, imageRoot })
  }

  return h(FilteredData, {
    getData,
    filters: [{
      type: 'select',
      label: LABELS.CATEGORY,
      keys: [LABELS.ALL_CATEGORIES, 'CATEGORY_NAME']
    }, {
      type: 'order',
      label: LABELS.ORDER_BY,
      keys: [LABELS.POINTS, `-${LABELS.POINTS}`]
    }],
    Items,
    i18n: {
      loadMore: LABELS.LOAD_MORE,
      resetFilters: LABELS.RESET_FILTERS,
      ascending: LABELS.ASCENDING,
      descending: LABELS.DESCENDING
    },
    src,
    imageRoot
  })
}

register(ProductCatalogue, 'product-catalogue')
