/* eslint-disable jsx-a11y/no-static-element-interactions */
import type { RefObject } from 'react'
import React, { useEffect } from 'react'
import { useRovingTabIndex } from '../react-roving-tabindex'
import { useMergeRefs } from '../utils/refs'

const SELECTOR = 'button[aria-controls="app-switcher-list"]'

function findButton(container: HTMLDivElement | null) {
    if (!container) {
        return null
    }

    const button = container.querySelector(SELECTOR)
    return button == null ? null : (button as HTMLElement)
}

function isCustomEvent(e: Event): e is CustomEvent {
    return 'detail' in e
}

/**
 * This component is meant to be used with the Dovetail Product Switcher.
 * It provides a bridge between the product switcher and the single tab
 * stop navigation provided in the NavigationBar.
 *
 * When using this component, be sure to pass `singleTabStop: true` to the
 * render method of the Dovetail Product Switcher.
 *
 * Here is an example of how you could connect the Dovetail component to
 * the ref used by ProductSwitcherBridge:
 *
 * ```tsx
 *     React.useEffect(() => {
 *      const switcher = lib.components.ProductSwitcher({
 *          element: ref.current,
 *      })
 *      switcher.render({
 *          platformaAuthTokenClosure,
 *          singleTabStop: true,
 *      })
 *      return () => {
 *          switcher.unmount()
 *      }
 *  }, [])
 * ```
 */
export const ProductSwitcherBridge = React.forwardRef<HTMLDivElement>(
    function ProductSwitcherBridgeImpl(props, forwardedRef) {
        const ref = React.useRef<HTMLDivElement>(null)
        const [isTriggerVisible, setIsTriggerVisible] = React.useState(false)

        const mergedRef = useMergeRefs([ref, forwardedRef])

        const [tabIndex, focused, handleKeyDown, handleClick] =
            useRovingTabIndex(
                ref as RefObject<HTMLDivElement>,
                !isTriggerVisible
            )

        const handleFocus = React.useCallback(() => {
            const button = findButton(ref.current)
            button?.focus()
        }, [])

        useEffect(() => {
            if (focused) {
                handleFocus()
            }
        }, [focused, handleFocus])

        useEffect(() => {
            const callback = (e: Event) => {
                if (isCustomEvent(e)) {
                    setIsTriggerVisible(e.detail.visible)
                }
            }

            document.addEventListener('productswitcher', callback, false)

            return () => {
                document.removeEventListener('productswitcher', callback, false)
            }
        }, [])

        return (
            <div
                ref={mergedRef}
                tabIndex={tabIndex}
                onKeyDown={handleKeyDown}
                onClick={handleClick}
                onFocus={handleFocus}
            />
        )
    }
)
