import { ComponentPropsWithRef, forwardRef, ForwardedRef } from 'react';

import { styled } from '../../stitches.config';

import { BaseFormInputProps } from '../internal';

const StyledIconButton = styled('button', {
    alignItems: 'center',
    backgroundColor: `transparent`,
    borderRadius: '$default',
    cursor: 'pointer',
    display: 'inline-flex',
    justifyContent: 'center',
    lineHeight: '$none',
    margin: '0',
    outline: 'none',
    textAlign: 'center',
    userSelect: 'none',
    whiteSpace: 'nowrap',
    '&:disabled': {
        color: `$grey-2`,
        cursor: 'default',
        pointerEvents: 'none',
    },
    '&:focus': {
        outline: '2px solid $primary-1',
        outlineOffset: '2px',
    },
    variants: {
        color: {
            primary: {
                color: `$primary-1`,
                '&:hover': {
                    color: `$primary-2`,
                },
            },
            success: {
                color: `$success-1`,
                '&:hover': {
                    color: `$success-2`,
                },
            },
            error: {
                color: `$error-1`,
                '&:hover': {
                    color: `$error-2`,
                },
            },
            warning: {
                color: `$warning-1`,
                '&:hover': {
                    color: `$warning-2`,
                },
            },
            grey: {
                color: `$grey-1`,
                '&:hover': {
                    color: `$grey-2`,
                },
            },
        },
        size: {
            sm: {
                fontSize: '$space$4',
                height: '$space$4',
                width: '$space$4',
            },
            md: {
                fontSize: '$space$6',
                height: '$space$6',
                width: '$space$6',
            },
            lg: {
                fontSize: '$space$8',
                height: '$space$8',
                width: '$space$8',
            },
        },
    },
    defaultVariants: {
        color: 'grey',
        size: 'md',
    },
});

export interface IconButtonProps extends ComponentPropsWithRef<'button'> {
    /** Rendered color of the IconButton */
    color?: 'primary' | 'success' | 'error' | 'warning' | 'grey';

    /** Rendered size of the IconButton */
    size?: BaseFormInputProps<never>['size'];

    /** Type of the button. Defaults to 'button' */
    type?: 'reset' | 'submit' | 'button';
}

/**
 * IconButton component
 */
const _IconButton = (
    props: IconButtonProps,
    ref: ForwardedRef<HTMLButtonElement>,
): JSX.Element => {
    const {
        children,
        tabIndex = 0,
        disabled = false,
        type = 'button',
        ...otherProps
    } = props;

    return (
        <StyledIconButton
            ref={ref}
            tabIndex={tabIndex}
            disabled={disabled}
            type={type}
            {...otherProps}
        >
            {children}
        </StyledIconButton>
    );
};

export const IconButton = forwardRef(_IconButton) as (
    props: IconButtonProps & {
        ref?: ForwardedRef<HTMLButtonElement>;
    },
) => ReturnType<typeof _IconButton>;
