import buttonSizeVariants from "@insite/mobius/Button/buttonSizeVariants";
import Icon, { IconPresentationProps } from "@insite/mobius/Icon";
import { TypographyPresentationProps } from "@insite/mobius/Typography";
import { StyledProp } from "@insite/mobius/utilities/InjectableCss";
import * as React from "react";
import styled from "styled-components";

export type ButtonSizeVariants = keyof typeof buttonSizeVariants;
export type ButtonVariants = "primary" | "secondary" | "tertiary";

export interface ButtonIconPresentationProps extends IconPresentationProps {}

export interface ButtonPresentationProps {
    /** How the color changes when the button is clicked.
     * @themable */
    activeMode?: "darken" | "lighten" | "none";
    /** Allows for fine-tuning of the active (clicked) state of the button.
     * @themable */
    activeStyle?: React.CSSProperties;
    /** The color of the button.
     * @themable */
    color?: string;
    /** CSS string or styled-components function to be injected into this component.
     * @themable */
    css?: StyledProp<ButtonProps>;
    /**
     * Indicates how the `css` property is combined with the variant `css` property from the theme.
     * If true, the variant css is applied first and then the component css is applied after causing
     * a merge, much like normal CSS. If false, only the component css is applied, overriding the variant css in the theme.
     */
    mergeCss?: boolean;
    /** Default presets for hover animation. This setting overrides hoverStyle if present.
     * @themable */
    hoverAnimation?: "grow" | "shrink" | "float";
    /** How the color changes when the button is hovered over.
     * @themable */
    hoverMode?: "darken" | "lighten" | "none";
    /** Allows for fine-tuning of the hovered state of the button.
     * @themable */
    hoverStyle?: React.CSSProperties;
    /** The source for icon displaying on the button. */
    icon?: {
        src: React.ComponentType | string;
        position: "right" | "left";
    };
    /** Toggles a shadow behind/below the button.
     * @themable */
    shadow?: boolean;
    /** Default presets for the button's shape.
     * @themable */
    shape?: "rectangle" | "pill" | "rounded";
    /** Defines the height of the button, as one of the preset values.
     * @themable */
    sizeVariant?: ButtonSizeVariants;
    /** Defines the height of the button, as the number of pixels.
     * @themable */
    size?: number;
    /** An object containing props to be passed down to the Typography component inside the button.
     * @themable */
    typographyProps?: TypographyPresentationProps;
    /** Applies one of the predefined button types defined in `buttonTypes.js`.
     * @themable */
    buttonType?: "outline" | "solid";
    /** Applies one of the predefined button variants defined in the theme. */
    variant?: ButtonVariants;
}

interface ButtonComponentProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
    activeStyle?: React.CSSProperties;
    /** Children of the Button component */
    children?: React.ReactNode;
    /** @ignore */
    forwardAs?: keyof JSX.IntrinsicElements;
    /** Focus the button on render */
    isFocusAfterMount?: boolean;
}

export type ButtonProps = ButtonComponentProps & ButtonPresentationProps;

export const ButtonIcon = styled(Icon)``;
