import React, { forwardRef } from 'react';

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

const CIRCLE_SIZE = theme.space['6'];

const StyledStep = styled('li', {
    display: 'flex',
    position: 'relative',
    variants: {
        layout: {
            vertical: {
                flexGrow: '0',
                paddingBottom: CIRCLE_SIZE,
            },
            horizontal: {
                flex: '1',
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
            },
        },
        last: {
            true: {
                paddingBottom: 0,
            },
        },
    },
});

const StyledButton = styled('button', {
    display: 'inline-flex',
    borderRadius: theme.radii.default,
    textAlign: 'left',
    '&[data-disabled]': {
        cursor: 'default',
        pointerEvents: 'none',
    },
    variants: {
        interactive: {
            true: {
                cursor: 'pointer',
            },
        },
        layout: {
            vertical: {
                flexGrow: '0',
                gap: theme.space['2'],
            },
            horizontal: {
                flex: '1',
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                gap: theme.space['1'],
            },
        },
    },
});

const StyledIcon = styled('div', {
    display: 'flex',
    flexShrink: '0',
    alignItems: 'center',
    justifyContent: 'center',
    width: CIRCLE_SIZE,
    height: CIRCLE_SIZE,
    borderWidth: theme.borderWidths.default,
    borderRadius: theme.space.full,
    backgroundColor: theme.colors['base'],
    borderColor: theme.colors['grey-3'],
    color: theme.colors['grey-3'],
    fontSize: theme.fontSizes.xs,
    overflow: 'hidden',
    whiteSpace: 'nowrap',
    textOverflow: 'ellipsis',
    '&[data-disabled]': {
        backgroundColor: theme.colors['grey-5'],
        borderColor: theme.colors['grey-4'],
        color: theme.colors['grey-3'],
    },
    variants: {
        highlighted: {
            true: {
                borderColor: theme.colors['primary-1'],
                color: theme.colors['primary-1'],
            },
            false: {},
        },
        valid: {
            true: {},
            false: {},
        },
        selected: {
            true: {
                borderColor: theme.colors['primary-1'],
                backgroundColor: theme.colors['primary-1'],
                color: 'white',
            },
            false: {},
        },
    },
    compoundVariants: [
        {
            valid: false,
            selected: false,
            css: {
                borderColor: theme.colors['error-1'],
                color: theme.colors['error-1'],
            },
        },
        {
            valid: false,
            selected: true,
            css: {
                borderColor: theme.colors['error-1'],
                backgroundColor: theme.colors['error-1'],
                color: 'white',
            },
        },
    ],
});

const StyledLabel = styled('div', {
    fontSize: theme.fontSizes.sm,
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    padding: `${theme.space['0']} ${theme.space['1']}`,
    variants: {
        layout: {
            vertical: {
                lineHeight: CIRCLE_SIZE,
            },
            horizontal: {},
        },
    },
});

const StyledLine = styled('div', {
    backgroundColor: theme.colors['grey-3'],
    variants: {
        highlighted: {
            true: {
                backgroundColor: theme.colors['primary-1'],
            },
            false: {},
        },
        layout: {
            vertical: {
                position: 'absolute',
                top: `calc(${CIRCLE_SIZE} + ${theme.space['1']})`,
                left: `calc(${CIRCLE_SIZE}/2)`,
                bottom: theme.space['1'],
                width: theme.borderWidths.default,
                zIndex: '-1',
            },
            horizontal: {
                position: 'absolute',
                top: `calc((${CIRCLE_SIZE}d)/2)`,
                left: '50%',
                width: '100%',
                height: theme.borderWidths.default,
                zIndex: '-1',
            },
        },
        last: {
            true: {
                display: 'none',
            },
            false: {},
        },
    },
});

export interface StepperStepProps
    extends Omit<
        React.ComponentPropsWithRef<'li'>,
        'value' | 'defaultValue' | 'onChange'
    > {
    /** value of the step */
    value: string;

    /** Mark the step in a disabled/enabled state */
    disabled?: boolean;

    /** Mark the step in a valid/invalid state */
    valid?: boolean;
}

/**
 * StepperStep component
 */
export const StepperStep = forwardRef<HTMLLIElement, StepperStepProps>(
    (props, ref): JSX.Element => {
        const {
            children,
            value,
            disabled = false,
            valid = true,
            // @ts-expect-error: Passed in from Parent Stepper
            number,
            // @ts-expect-error: Passed in from Parent Stepper
            highlighted,
            // @ts-expect-error: Passed in from Parent Stepper
            selected,
            // @ts-expect-error: Passed in from Parent Stepper
            last,
            // @ts-expect-error: Passed in from Parent Stepper
            interactive,
            // @ts-expect-error: Passed in from Parent Stepper
            layout,
            // @ts-expect-error: Passed in from Parent Stepper
            onChange,
            ...otherProps
        } = props;

        return (
            <StyledStep ref={ref} layout={layout} last={last} {...otherProps}>
                <StyledButton
                    tabIndex={interactive ? 0 : -1}
                    layout={layout}
                    interactive={interactive}
                    data-disabled={disabled || undefined}
                    onClick={() => {
                        if (interactive) {
                            onChange(value);
                        }
                    }}
                    type={'button'}
                >
                    <StyledIcon
                        highlighted={highlighted}
                        valid={valid}
                        selected={selected}
                        data-disabled={disabled || undefined}
                    >
                        {number}
                    </StyledIcon>
                    <StyledLabel layout={layout}>{children}</StyledLabel>
                    <StyledLine
                        highlighted={highlighted}
                        layout={layout}
                        last={last}
                    />
                </StyledButton>
            </StyledStep>
        );
    },
);

StepperStep.displayName = 'StepperStep';
