import { ComponentPropsWithRef, forwardRef, ForwardedRef } from 'react';
import {
    Root,
    Viewport,
    Scrollbar,
    Thumb,
    Corner,
} from '@radix-ui/react-scroll-area';
import { styled, theme } from '../../stitches.config';

const SCROLLBAR_SIZE = theme.space['3'];

const StyledRoot = styled(Root, {
    width: '100%',
    height: '100%',
    overflow: 'hidden',
});

const StyledViewport = styled(Viewport, {
    width: '100%',
    height: '100%',
    borderRadius: 'inherit',
    '> div[style]': {
        display: 'block !important',
    },
});

const StyledScrollbar = styled(Scrollbar, {
    display: 'flex',
    userSelect: 'none',
    touchAction: 'none',
    padding: `calc( ${theme.space['1']} / 2 )`,
    // backgroundColor: theme.colors['grey-5'],
    '&:hover': {
        backgroundColor: theme.colors['grey-5'],
    },
    '&[data-orientation="vertical"]': {
        width: SCROLLBAR_SIZE,
    },
    '&[data-orientation="horizontal"]': {
        flexDirection: 'column',
        height: SCROLLBAR_SIZE,
    },
});

const StyledThumb = styled(Thumb, {
    flex: 1,
    backgroundColor: theme.colors['grey-3'],
    borderRadius: SCROLLBAR_SIZE,
    '&:hover': {
        backgroundColor: theme.colors['grey-2'],
    },
    // increase target size for touch devices https://www.w3.org/WAI/WCAG21/Understanding/target-size.html
    position: 'relative',
    '&::before': {
        content: '""',
        position: 'absolute',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: '100%',
        height: '100%',
        minWidth: 44,
        minHeight: 44,
    },
});

export interface ScrollProps
    extends Omit<ComponentPropsWithRef<'div'>, 'dir' | 'onScroll'> {
    /** Type of the scroll */
    type?: 'hover' | 'auto' | 'always' | 'scroll';

    /** Allow horizontal scrolling */
    horizontal?: boolean;

    /** Allow vertical scrolling */
    vertical?: boolean;

    /** Callback that is triggered when the area is scrolle */
    onScroll?: (event: React.UIEvent<HTMLDivElement>) => void;
}

/**
 * Scroll component
 */
const _Scroll = (
    props: ScrollProps,
    ref: ForwardedRef<HTMLDivElement>,
): JSX.Element => {
    const {
        children,
        type = 'hover',
        horizontal = true,
        vertical = true,
        onScroll = () => null,
        ...otherProps
    } = props;

    return (
        <StyledRoot ref={ref} type={type} {...otherProps}>
            <StyledViewport onScroll={(event) => onScroll(event)}>
                {children}
            </StyledViewport>
            {horizontal && (
                <StyledScrollbar orientation="horizontal">
                    <StyledThumb />
                </StyledScrollbar>
            )}
            {vertical && (
                <StyledScrollbar orientation="vertical">
                    <StyledThumb />
                </StyledScrollbar>
            )}
            <Corner />
        </StyledRoot>
    );
};

export const Scroll = forwardRef(_Scroll) as (
    props: ScrollProps & {
        ref?: ForwardedRef<HTMLDivElement>;
    },
) => ReturnType<typeof _Scroll>;
