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

import { GridContext, GridValue } from './GridContext';

const StyledGrid = styled('div', {
    display: 'flex',
});

export interface GridProps extends ComponentPropsWithRef<'div'> {
    /** Number of columns in the grid */
    columns?: GridValue['columns'];

    /** Size of the gutter */
    gutterX?: GridValue['gutterX'];

    /** Size of the gutter */
    gutterY?: GridValue['gutterY'];

    /** Justify the content */
    justify?: StitchesCSS['justifyContent'];

    /** Align the content */
    align?: StitchesCSS['alignItems'];

    /** Align the content */
    wrap?: StitchesCSS['flexWrap'];
}

export const _Grid = (
    props: GridProps,
    ref: ForwardedRef<HTMLDivElement>,
): JSX.Element => {
    const {
        children,
        columns = 12,
        gutterX = '$4',
        gutterY = '$4',
        justify = 'flex-start',
        align = 'stretch',
        wrap = 'wrap',
        ...otherProps
    } = props;

    // construct the value to pass to the grid
    const value = {
        columns: columns,
        gutterX: gutterX,
        gutterY: gutterY,
    };

    // TODO: wrap with a form library?
    return (
        <GridContext.Provider value={value}>
            <StyledGrid
                ref={ref}
                css={{
                    marginLeft: `calc(-1 * ${gutterX}/2)`,
                    marginRight: `calc(-1 * ${gutterX}/2)`,
                    rowGap: gutterY,
                    justifyContent: justify,
                    alignItems: align,
                    flexWrap: wrap,
                }}
                {...otherProps}
            >
                {children}
            </StyledGrid>
        </GridContext.Provider>
    );
};

export const Grid = forwardRef(_Grid) as (
    props: GridProps & {
        ref?: ForwardedRef<HTMLLabelElement>;
    },
) => ReturnType<typeof _Grid>;
