import { ComponentPropsWithRef, forwardRef, ForwardedRef } from 'react';
import { styled, StitchesCSS } from '../../stitches.config';

import { useGrid } from './GridContext';

const StyledGridItem = styled('div', {
    display: 'block',
    flexGrow: 0,
    flexShrink: 0,
});

/**
 * Calculate the size of the grid
 */
const calculateSize = (span: number | undefined, columns: number) => {
    if (span === undefined) {
        return undefined;
    }

    return `${(span / columns) * 100}%`;
};

export interface GridItemProps extends ComponentPropsWithRef<'div'> {
    /** Number of columns to span the grid */
    span?: number;

    /** Responsive of columns to span the grid */
    responsive?: {
        sm?: number;
        md?: number;
        lg?: number;
        xl?: number;
        xxl?: number;
    };
}

export const _GridItem = (
    props: GridItemProps,
    ref: ForwardedRef<HTMLDivElement>,
): JSX.Element => {
    const { children, span, responsive, ...otherProps } = props;

    // get the grid
    const grid = useGrid();

    // calculate the flexBasis
    let basis: StitchesCSS = {};
    if (typeof span === 'undefined') {
        basis = {
            flexBasis: '100%',
            maxWidth: '100%',
        };
    } else if (typeof span === 'number') {
        basis = {
            flexBasis: calculateSize(span, grid.columns),
            maxWidth: calculateSize(span, grid.columns),
        };
    }

    if (responsive) {
        basis = {
            ...basis,
            '@sm': {
                flexBasis: calculateSize(responsive.sm, grid.columns),
                maxWidth: calculateSize(responsive.sm, grid.columns),
            },
            '@md': {
                flexBasis: calculateSize(responsive.md, grid.columns),
                maxWidth: calculateSize(responsive.md, grid.columns),
            },
            '@lg': {
                flexBasis: calculateSize(responsive.lg, grid.columns),
                maxWidth: calculateSize(responsive.lg, grid.columns),
            },
            '@xl': {
                flexBasis: calculateSize(responsive.xl, grid.columns),
                maxWidth: calculateSize(responsive.xl, grid.columns),
            },
            '@xxl': {
                flexBasis: calculateSize(responsive.xxl, grid.columns),
                maxWidth: calculateSize(responsive.xxl, grid.columns),
            },
        };
    }

    return (
        <StyledGridItem
            ref={ref}
            css={{
                paddingLeft: `calc(${grid.gutterX}/2)`,
                paddingRight: `calc(${grid.gutterX}/2)`,
                ...basis,
            }}
            {...otherProps}
        >
            {children}
        </StyledGridItem>
    );
};

export const GridItem = forwardRef(_GridItem) as (
    props: GridItemProps & {
        ref?: ForwardedRef<HTMLLabelElement>;
    },
) => ReturnType<typeof _GridItem>;
