import React, {useRef, useState, useContext, useEffect, useCallback} from 'react'
import { LinkAria } from '$core-components'
import { Popover, PopoverBody } from 'reactstrap-wc'
import NavigationMenu from './NavigationMenu'
import urlGenerator from '$ustoreinternal/services/urlGenerator'
import { decodeStringForURL } from '$ustoreinternal/services/utils'
import { getVariableValue } from '$ustoreinternal/services/cssVariables'
import { t } from '$themelocalization'
import { RootDocumentContext } from '$themeservices'
import './CategoriesNavbar.scss'

const CategoriesNavbar = ({ categoriesTree }) => {
  const {documentRoot, rootElement} = useContext(RootDocumentContext)()
  const [hoveredItem, setHoveredItem] = useState(null)
  const [selectedCategory, setSelectedCategory] = useState(null)
  const openedByKeyboard = useRef(false)
  const containerRef = useRef(null)

  if (!(categoriesTree && categoriesTree.length > 0)) {
    return null
  }

  // Build custom menu items array
  const addMenuPosition = getVariableValue('--cust-menu-position', 'End')
  const customMenus = [
    { text: getVariableValue('--cust-menu1-text', ''), url: getVariableValue('--cust-menu1-url', ''), id: 'custom-1' },
    { text: getVariableValue('--cust-menu2-text', ''), url: getVariableValue('--cust-menu2-url', ''), id: 'custom-2' },
    { text: getVariableValue('--cust-menu3-text', ''), url: getVariableValue('--cust-menu3-url', ''), id: 'custom-3' }
  ].filter(menu => menu.text.length > 0 && menu.url.substring(0, 4).toLowerCase() === 'http')
    .map(menu => ({
      Category: {
        FriendlyID: menu.id,
        Name: menu.text,
        isCustom: true,
        customUrl: menu.url
      },
      SubCategories: []
    }))

  // Combine custom menus with categories based on position
  const allMenuItems = addMenuPosition.toLowerCase() === 'start'
    ? [...customMenus, ...categoriesTree]
    : [...categoriesTree, ...customMenus]

  const onMouseEnter = (category) => {
    queueMicrotask(() => {
      setSelectedCategory(category)
      setHoveredItem(documentRoot.getElementById(`id-${category}`))
    })
  }

  const onMouseLeave = () => {
    if (openedByKeyboard.current) return
    setSelectedCategory(null)
    setHoveredItem(null)
  }

  const onFocus = (category) => {
    queueMicrotask(() => {
      setSelectedCategory(category)
      setHoveredItem(documentRoot.getElementById(`id-${category}`))
    })
  }

  const onBlur = () => {
    setTimeout(() => {
      const active = document.activeElement
      if (openedByKeyboard.current && active?.closest('.categories-navbar-popper')) return
      if (!containerRef.current?.contains(active) &&
          !active?.closest('.categories-navbar-popper')) {
        openedByKeyboard.current = false
        setSelectedCategory(null)
        setHoveredItem(null)
      }
    }, 0)
  }

  const onEscapeKey = useCallback((e) => {
    if (e.key === 'Escape' && selectedCategory !== null) {
      openedByKeyboard.current = false
      const triggerId = selectedCategory === 0 ? 'id-0' : `id-${selectedCategory}`
      setSelectedCategory(null)
      setHoveredItem(null)
      const trigger = documentRoot.getElementById(triggerId)?.closest('[tabindex], a')
      trigger?.focus()
    }
  }, [selectedCategory, documentRoot])

  useEffect(() => {
    document.addEventListener('keydown', onEscapeKey)
    return () => document.removeEventListener('keydown', onEscapeKey)
  }, [onEscapeKey])

  useEffect(() => {
    if (openedByKeyboard.current && selectedCategory !== null && selectedCategory !== 0) {
      rootElement?.querySelector('.categories-navbar-popper a')?.focus()
    }
  }, [selectedCategory, rootElement])

  return (
    <div className="categories-navbar" role="navigation" ref={containerRef}>
      <div
        className="categories-navbar-item"
        onMouseEnter={( e ) => onMouseEnter( 0 )}
        onMouseLeave={onMouseLeave}
      >
        <div className="category-title-wrapper view-show-all"
             role="button" tabIndex={0}
             aria-haspopup="true" aria-expanded={selectedCategory === 0}
             onBlur={onBlur}
             onKeyDown={(e) => { if ((e.key === 'Enter' || e.key === ' ') && e.target === e.currentTarget) { e.preventDefault(); if (selectedCategory === 0) { openedByKeyboard.current = false; setSelectedCategory(null); setHoveredItem(null) } else { openedByKeyboard.current = true; onFocus(0) } } }}>
          <span className={`category-title ${selectedCategory === 0 ? 'highlight' : ''}`} id="id-0">
            {t( 'Header.All_Categories' )}
          </span>
          <span className="category-spacer"></span>
          {
            hoveredItem && selectedCategory === 0 &&
            <Popover className="" fade={false} isOpen={true} placement="bottom-start"
                     target={hoveredItem} container={hoveredItem} popperClassName="categories-navbar-popper">
              <PopoverBody onClick={() => { openedByKeyboard.current = false; setSelectedCategory(null); setHoveredItem(null) }}>
                <NavigationMenu categoriesTree={categoriesTree} viewShowAll={true} selectedCategory={null} />
              </PopoverBody>
            </Popover>
          }
        </div>
      </div>
      {
        allMenuItems.map( ( { Category, SubCategories }, i ) => {
          const { FriendlyID, Name, isCustom, customUrl } = Category
          return (
            <div
              className="categories-navbar-item"
              key={i}
              onMouseEnter={( e ) => onMouseEnter( FriendlyID, e.target )}
              onMouseLeave={onMouseLeave}
            >
              <LinkAria className="category-title-wrapper"
                        to={isCustom ? customUrl : urlGenerator.get( {
                          page: 'category',
                          id: FriendlyID,
                          name: decodeStringForURL( Name ),
                        } )}
                        target={isCustom ? '_blank' : undefined}
                        rel={isCustom ? 'noopener noreferrer' : undefined}
                        onBlur={onBlur}
                        aria-haspopup={SubCategories?.length > 0 ? "true" : undefined}
                        aria-expanded={SubCategories?.length > 0 ? selectedCategory === FriendlyID : undefined}
                        onKeyDown={SubCategories?.length > 0 ? (e) => { if (e.key === ' ') { e.preventDefault(); if (selectedCategory === FriendlyID) { onMouseLeave() } else { openedByKeyboard.current = true; onFocus(FriendlyID) } } } : undefined}>
                <span className={`category-title ${selectedCategory === FriendlyID ? 'highlight' : ''}`}
                      key={i} id={`id-${FriendlyID}`}>
                  <span className="link" key={i} dangerouslySetInnerHTML={{ __html: Name }} />
                </span>
                {
                  hoveredItem && selectedCategory === FriendlyID && SubCategories?.length > 0 &&
                  <Popover fade={false} isOpen={true} placement="bottom-start"
                           target={hoveredItem} container={rootElement}
                           popperClassName="categories-navbar-popper">
                    <PopoverBody onClick={() => { openedByKeyboard.current = false; setSelectedCategory(null); setHoveredItem(null) }}
                                 onKeyDown={(e) => { if (e.key === 'Escape') { e.preventDefault(); openedByKeyboard.current = false; setSelectedCategory(null); setHoveredItem(null); documentRoot.getElementById(`id-${FriendlyID}`)?.closest('a')?.focus() } }}>
                      <NavigationMenu categoriesTree={categoriesTree} viewShowAll={false} selectedCategory={Category} />
                    </PopoverBody>
                  </Popover>
                }
              </LinkAria>
            </div>
          )
        } )
      }
    </div>
  )
}

export default CategoriesNavbar
