import type { DropdownTriggerProps } from '@planview/pv-uikit'
import { Tooltip } from '@planview/pv-uikit'
import * as React from 'react'
import { ToolbarDropdownMenu } from '../dropdown'
import { useUserMenu } from '../utils/context'
import { ToolbarItem, ToolbarItemView } from '../wrapper'
import { StrippedButton } from './styles'
import { useIsFocusVisible } from '@planview/pv-utilities'
import { useMergeRefs } from '../utils/refs'

type Props = {
    trigger: React.ReactNode
    children: React.ReactNode
    label: string
}

const UserMenuImpl = ({ children, trigger, label }: Props) => {
    const {
        innerRef: _innerRef,
        focusVisible,
        ...focusProps
    } = useIsFocusVisible()
    const buttonRef = React.useRef<HTMLButtonElement>(null)
    const mergedRef = useMergeRefs([buttonRef, focusProps.ref])
    return (
        <ToolbarDropdownMenu
            label={label}
            trigger={(props: DropdownTriggerProps) => (
                <ToolbarItem>
                    <ToolbarItemView<HTMLButtonElement> refOverride={buttonRef}>
                        {(
                            _ref,
                            {
                                toolbarItemProps: {
                                    focused: _focused,
                                    ...toolbarItemProps
                                },
                            }
                        ) => (
                            <Tooltip text={label}>
                                <StrippedButton
                                    type="button"
                                    {...props}
                                    {...toolbarItemProps}
                                    {...focusProps}
                                    $focusVisible={focusVisible}
                                    aria-label={label}
                                    ref={(el: HTMLButtonElement) => {
                                        mergedRef?.(el)
                                        if (props.ref) {
                                            ;(
                                                props.ref as React.MutableRefObject<HTMLButtonElement>
                                            ).current = el
                                        }
                                    }}
                                    onKeyDown={(ev) => {
                                        toolbarItemProps.onKeyDown(ev)
                                        props.onKeyDown(ev)
                                    }}
                                >
                                    {trigger}
                                </StrippedButton>
                            </Tooltip>
                        )}
                    </ToolbarItemView>
                </ToolbarItem>
            )}
        >
            {children}
        </ToolbarDropdownMenu>
    )
}

export const UserMenuInternal = React.memo(UserMenuImpl)

export type UserMenuProps = {
    /** element to be wrapped inside a `DropdownMenu` trigger  **/
    triggerElement: React.JSX.Element
    /**
     * any `DropdownMenu`-compatible content
     */
    children: React.ReactNode
}

export const UserMenuConfig = ({ triggerElement, children }: UserMenuProps) => {
    const { add, remove } = useUserMenu()
    React.useEffect(() => {
        add({ trigger: triggerElement, children })
        return () => {
            remove()
        }
    }, [triggerElement, children, add, remove])

    return null
}

/**
 *
 * `import { UserMenu } from '@planview/pv-toolbar'`
 *
 * The `UserMenu` uses a _component-as-configuration_ strategy. This means the content of the component will not be rendered where it is placed inside the `NavigationBar`.
 * Rendering of the content, and it's placement is handled internally inside the `NavigationBar`.
 *
 * ### Accessibility
 *
 * `aria-label` is automatically added with localized label for the drop-down which internally uses the `DropdownMenu` implementing the [Menu WAI aria pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menu/)
 *
 */
export const UserMenu = React.memo(UserMenuConfig)
