import React, { useState } from 'react'
import { Flex, Box, Text, BoxProps } from 'theme-ui'
import { MenuTrigger } from './MenuTrigger'
import { NAV_HEIGHT } from './Navbar'
import { Transition } from 'react-transition-group'
import { useScrollSwipe } from '../hooks/use-scroll-swipe'
import { RenderInBody } from './RenderInBody'
import classnames from 'classnames'
import BackgroundImage from 'gatsby-background-image'

export const Menu: React.FunctionComponent = (props) => {
    const [menuVisible, setMenuVisible] = useState(false)
    useScrollSwipe(() => {
        setMenuVisible(false)
    })

    return (
        <>
            <MenuTrigger active={menuVisible} onChange={(val) => setMenuVisible(val)} />
            <Transition in={menuVisible} timeout={330}>
                {(state) => {
                    const onEnter = state === 'entering' || state === 'entered'
                    return (
                        <RenderInBody
                            sx={{
                                display: 'flex',
                                position: 'fixed',
                                top: NAV_HEIGHT,
                                left: 0,
                                right: 0,
                                bottom: 0,
                                transition: 'default',
                                // 仅当动画完全停止后可以点击
                                pointerEvents: state === 'entered' ? 'auto' : 'none',
                                // 隐藏后清除合成层，使用 `display:none` 会造成伪元素动画失效
                                visibility: state === 'exited' ? 'hidden' : 'visible',
                                zIndex: 3,
                                // 添加一个伪元素作为背景色，单独过渡
                                '::after': {
                                    position: 'absolute',
                                    content: '""',
                                    transition: 'inherit',
                                    transitionDelay: onEnter ? '0' : '100ms',
                                    left: 0,
                                    right: 0,
                                    bottom: 0,
                                    top: 0,
                                    bg: 'background',
                                    backdropFilter: 'blur(3px)',
                                    zIndex: -1,
                                    opacity: onEnter ? 0.9 : 0,
                                    willChange: 'opacity'
                                }
                            }}
                        >
                            <Flex
                                sx={{
                                    transition: 'inherit',
                                    transitionDelay: onEnter ? '100ms' : '0',
                                    opacity: onEnter ? 1 : 0,
                                    willChange: 'opacity',
                                    flex: 1,
                                    flexDirection: ['column', 'column', 'row']
                                }}
                            >
                                {props.children}
                            </Flex>
                        </RenderInBody>
                    )
                }}
            </Transition>
        </>
    )
}

export interface MenuItemProps {
    backgroundImage: any
    text: string
    /** 类型，垂直仅在 PC 端显示，水平仅在移动端显示 */
    type?: 'horizontal' | 'vertical' | 'all'
    /** 是否处于激活状态 */
    active?: boolean
    /** 激活状态文字颜色 */
    activeColor?: any
}

export const MenuItem: React.FunctionComponent<MenuItemProps & BoxProps> = (props) => {
    const { active, backgroundImage, activeColor, text, type } = props

    let itemDisplay = ['flex']

    if (type === 'vertical') {
        itemDisplay = ['none', 'none', 'flex']
    } else if (type === 'horizontal') {
        itemDisplay = ['flex', 'flex', 'none']
    }

    return (
        <Box
            {...props}
            className={classnames({ active })}
            sx={{
                display: itemDisplay,
                boxShadow: '-1px -1px 0 rgba(0,0,0,0.08)',
                flexGrow: 1,
                position: 'relative',
                cursor: 'pointer',
                ':hover,&.active': {
                    color: activeColor,
                    '.bg': {
                        opacity: 1
                    }
                }
            }}
        >
            <Box
                className="bg"
                sx={{
                    position: 'absolute',
                    top: 0,
                    left: 0,
                    right: 0,
                    bottom: 0,
                    zIndex: -1,
                    // transition: 'default',
                    opacity: active ? 1 : 0
                }}
            >
                <BackgroundImage
                    {...backgroundImage}
                    style={{
                        height: '100%'
                    }}
                />
            </Box>
            {(type === 'vertical' || type === 'all') && (
                <Text
                    sx={{
                        display: ['none', 'none', 'flex'],
                        fontWeight: 100,
                        fontSize: 8,
                        flex: 1,
                        whiteSpace: 'break-spaces',
                        maxWidth: '1em',
                        lineHeight: 1.1,
                        ml: '.5em',
                        mt: '.5em'
                    }}
                >
                    {text}
                </Text>
            )}

            {(type === 'horizontal' || type === 'all') && (
                <Text
                    sx={{
                        display: ['flex', 'flex', 'none'],
                        alignItems: 'center',
                        justifyContent: 'center',
                        fontWeight: 300,
                        fontSize: 4,
                        flex: 1
                    }}
                >
                    {text}
                </Text>
            )}
        </Box>
    )
}

MenuItem.defaultProps = {
    active: false,
    type: 'all'
}
