import React from 'react'
import styled, { keyframes } from 'styled-components'
import { breakpoints, isTestEnvironment, theme } from '@planview/pv-utilities'
import { useFloating } from '@floating-ui/react-dom'
import { Portal } from '@planview/pv-uikit'

const animFrames = keyframes`
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
`

const Wrap = styled.div<{
    theme: { zindex: number }
}>`
    z-index: ${({ theme }) => theme.zindex};
    background-color: transparent;
    ${breakpoints.phone`
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        overflow: hidden;
        outline: 0;
        background-color: ${theme.backgroundNeutral0};
    `}
`

const InnerWrap = styled.div`
    height: 100%;
    display: flex;
    opacity: 0;
    animation: ${animFrames} 0.1s linear forwards;
`

export type PortalProps = {
    type?: string
    children: React.JSX.Element
}

type FloatingWrapDetailsProps = {
    style: React.CSSProperties
    children: React.ReactNode
}

const FloatingWrapDetails = React.forwardRef<
    HTMLDivElement,
    FloatingWrapDetailsProps
>(({ style, children, ...rest }, ref) => (
    <Wrap {...rest} style={style} ref={ref}>
        <InnerWrap>{children}</InnerWrap>
    </Wrap>
))

FloatingWrapDetails.displayName = 'FloatingWrapDetails'

type FloaterProps = {
    /**
     * Element/coordinates to anchor to
     */
    anchor?: React.RefObject<HTMLButtonElement | null>
    children: React.ReactNode
}

export const Floater = ({ anchor, children }: FloaterProps) => {
    const {
        refs: { setFloating },
        x,
        y,
        strategy,
    } = useFloating({
        placement: 'bottom-start',
        elements: {
            reference: anchor!.current,
        },
    })
    const isMobile = window.innerWidth <= breakpoints.PHONE

    return (
        <Portal>
            {isMobile ? (
                <Wrap>
                    <InnerWrap>{children}</InnerWrap>
                </Wrap>
            ) : (
                <FloatingWrapDetails
                    style={{
                        position: strategy,
                        top: y ?? 0,
                        left: x ?? 0,
                    }}
                    ref={setFloating}
                >
                    {((x !== 0 && y !== 0) || isTestEnvironment) && (
                        <div>{children}</div>
                    )}
                </FloatingWrapDetails>
            )}
        </Portal>
    )
}
