import LayoutGroupContext from "@insite/mobius/LayoutGroup/LayoutGroupContext";
import LayoutTableContext, { LayoutTableContextData } from "@insite/mobius/LayoutTable/LayoutTableContext";
import { TypographyPresentationProps } from "@insite/mobius/Typography";
import applyPropBuilder from "@insite/mobius/utilities/applyPropBuilder";
import { StyledProp } from "@insite/mobius/utilities/InjectableCss";
import injectCss from "@insite/mobius/utilities/injectCss";
import MobiusStyledComponentProps from "@insite/mobius/utilities/MobiusStyledComponentProps";
import * as React from "react";
import styled, { withTheme } from "styled-components";

export interface LayoutTableCellProps {
    /** Props to be passed to the cell's typography child. */
    typographyProps?: TypographyPresentationProps;
    /**
     * Indicates how the `css` property is combined with the default `css` property from the theme.
     * If true, the default 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 default css in the theme.
     */
    mergeCss?: boolean;
    /** CSS string or styled-components function to be injected into this component. */
    css?: StyledProp<LayoutCellProps>;
}

export type LayoutCellProps = MobiusStyledComponentProps<
    "div",
    LayoutTableContextData &
        LayoutTableCellProps & {
            /** Order of appearance of this LayoutCell within its parent LayoutGroup. */
            index: number;
        }
>;

const LayoutCellStyle = styled.div<{
    cellFlow: LayoutTableContextData["cellFlow"];
    cellIndex: number;
    groupIndex: number;
}>`
    ${({ cellFlow, cellIndex, groupIndex }) => {
        const row = (cellFlow === "row" ? groupIndex : cellIndex) + 1;
        const column = (cellFlow === "row" ? cellIndex : groupIndex) + 1;
        return `
            -ms-grid-row: ${row};
            -ms-grid-column: ${column};
        `;
    }}
    ${injectCss}
`;

/**
 * LayoutTable equivalent to a `<td>` in an HTML table.
 */
const LayoutCell: React.FC<LayoutCellProps> = ({ index, children, css, mergeCss, ...otherProps }) => {
    const { applyStyledProp } = applyPropBuilder({ css, ...otherProps }, { component: "layoutCell" });
    const { theme } = otherProps;
    const resolvedMergeCss = mergeCss ?? theme?.layoutCell.defaultProps?.mergeCss;
    return (
        <LayoutTableContext.Consumer>
            {({ cellFlow, gap }) => (
                <LayoutGroupContext.Consumer>
                    {({ groupIndex }) => (
                        <LayoutCellStyle
                            cellIndex={index}
                            css={applyStyledProp("css", resolvedMergeCss)}
                            {...{ cellFlow, gap, groupIndex }}
                            {...otherProps}
                        >
                            {children}
                        </LayoutCellStyle>
                    )}
                </LayoutGroupContext.Consumer>
            )}
        </LayoutTableContext.Consumer>
    );
};

/** @component */
export default withTheme(LayoutCell);

export { LayoutCellStyle };
