import React, { forwardRef, ReactElement } from "react";
import styled from "styled-components";
import { theme } from "../../../css/globalStyle";

const BoxComponent = styled.div<Props>`
  width: ${({ w }) => (typeof w === "number" ? `${w}px` : w)};
  height: ${({ h }) => (typeof h === "number" ? `${h}px` : h)};
  position: ${({ position }) => position};
  top: ${({ top }) => top};
  right: ${({ right }) => right};
  bottom: ${({ bottom }) => bottom};
  left: ${({ left }) => left};
  display: ${({ display }) => display};
  justify-content: ${({ justify }) => justify};
  align-items: ${({ align }) => align};
  flex-direction: ${({ direction }) => direction};
  padding: ${({ p, px, py }) =>
    px && py
      ? `${theme.spacing[py]} ${theme.spacing[px]}`
      : px
      ? `0 ${theme.spacing[px]}`
      : py
      ? `${theme.spacing[py]} 0`
      : typeof p === "number"
      ? theme.spacing[p]
      : p};
  padding-top: ${({ pt }) => theme.spacing[pt]};
  padding-left: ${({ pl }) => theme.spacing[pl]};
  padding-right: ${({ pr }) => theme.spacing[pr]};
  padding-bottom: ${({ pb }) => theme.spacing[pb]};
  margin: ${({ m, mx, my }) =>
    mx && my
      ? `${theme.spacing[my]} ${theme.spacing[mx]}`
      : mx
      ? `0 ${theme.spacing[mx]}`
      : my
      ? `${theme.spacing[my]} 0`
      : typeof m === "number"
      ? theme.spacing[m]
      : m};
  margin-top: ${({ mt }) => theme.spacing[mt]};
  margin-left: ${({ ml }) => theme.spacing[ml]};
  margin-right: ${({ mr }) => theme.spacing[mr]};
  margin-bottom: ${({ mb }) => theme.spacing[mb]};
  color: ${({ color }) => color};
  overflow: ${({ overflow }) => overflow};
  box-shadow: ${({ boxShadow }) => theme.shadow[boxShadow]};
  border: ${({ border }) => border};
  border-radius: ${({ rounded }) => theme.radius[rounded]};
  background: ${({ bg }) => bg};
  z-index: ${({ z }) => z};
  box-sizing: border-box;
  white-space: ${({ noWrap }) => (noWrap ? "nowrap" : "normal")};
`;

interface Props extends React.HTMLAttributes<HTMLDivElement> {
  // Padding
  p?: number | string;
  pt?: number;
  pr?: number;
  pb?: number;
  pl?: number;
  px?: number;
  py?: number;
  // Margin
  m?: number | string;
  mt?: number;
  mr?: number;
  mb?: number;
  ml?: number;
  mx?: number;
  my?: number;
  // Background
  bg?: string;
  // Width
  w?: number | string;
  // Height
  h?: number | string;
  // Z-index
  z?: number;
  color?: string;
  // Border-Radius
  rounded?: "sm" | "md" | "lg" | "full";
  overflow?: "hidden" | "visible" | "scroll" | "auto";
  display?:
    | "flex"
    | "inline-flex"
    | "inline"
    | "block"
    | "none"
    | "grid"
    | "inline-grid"
    | "table"
    | "table-row-group"
    | "table-header-group"
    | "table-footer-group"
    | "table-row"
    | "table-column-group"
    | "table-column"
    | "table-cell"
    | "table-caption"
    | "initial"
    | "inherit";
  direction?: "row" | "row-reverse" | "column" | "column-reverse";
  align?: "flex-start" | "flex-end" | "center" | "baseline" | "stretch";
  justify?:
    | "flex-start"
    | "flex-end"
    | "center"
    | "space-between"
    | "space-around";
  boxShadow?: "sm" | "md" | "lg";
  border?: string;
  position?: "relative" | "absolute" | "fixed" | "sticky";
  top?: number | string;
  right?: number | string;
  bottom?: number | string;
  left?: number | string;
  as?: any;
  noWrap?: boolean;
  children?: ReactElement | ReactElement[] | string | number;
}

export const Box = forwardRef<HTMLDivElement, Props>(
  ({ children, boxShadow, rounded, ...rest }, ref): ReactElement => {
    return (
      <BoxComponent ref={ref} shadow={boxShadow} rounded={rounded} {...rest}>
        {children}
      </BoxComponent>
    );
  }
);
