import { Card, CardContent, CardHeader, Divider, Typography } from '@mui/material';
import { SxProps, lighten, useTheme } from '@mui/material/styles';
import { forwardRef } from 'react';

const headerSX = {
  p: 2.5,
  '& .MuiCardHeader-action': { m: '0px auto', alignSelf: 'center' }
};

type MainCardProps = {
  /**
   * Indicates if the card must be rendered with a border.
   */
  border?: boolean;
  /**
   * Indicates if the card must be rendered with a box shadow.
   */
  boxShadow?: boolean;
  /**
   * The content of the card.
   */
  children?: React.ReactNode | React.ReactNode[];
  /**
   * The subheader of the card.
   */
  subheader?: React.ReactNode | string;
  /**
   * Indicates if the card must be rendered with a content.
   */
  content?: boolean;
  /**
   * The class name of the content.
   */
  contentClass?: string;
  /**
   * The style of the content.
   */
  contentSX?: SxProps | any;
  /**
   * Indicates if the title of the card must be rendered with a dark color.
   */
  darkTitle?: boolean;
  /**
   * Indicates if the card must be rendered with a divider.
   */
  divider?: boolean;
  /**
   * The elevation of the card.
   */
  elevation?: number;
  /**
   * The secondary content of the card.
   */
  secondary?: React.ReactNode | string | object;
  /**
   * The shadow of the card.
   * @example '0px 0px 0px 0px rgba(0,0,0,0.2)'
   */
  shadow?: string;
  /**
   * The style of the card.
   */
  sx?: SxProps | any;
  /**
   * The title of the card.
   */
  title?: React.ReactNode | string | object;
  /**
   * Indicates if the card must be rendered as a modal.
   */
  modal?: boolean;
  /**
   * The color of the card.
   */
  color?: 'default' | 'primary' | 'secondary';
};

const MainCard = forwardRef(
  (
    {
      border = true,
      boxShadow,
      children,
      subheader,
      content = true,
      contentSX = {},
      darkTitle,
      divider = true,
      elevation,
      secondary,
      shadow,
      sx = {},
      title,
      modal = false,
      color = 'default',
      ...others
    }: MainCardProps,
    ref
  ) => {
    const theme = useTheme() as any;
    boxShadow = theme.palette.mode === 'dark' ? boxShadow || true : boxShadow;

    return (
      /** @ts-ignore */
      <Card
        elevation={elevation || 0}
        ref={ref}
        {...others}
        sx={{
          position: 'relative',
          border: border ? '1px solid' : 'none',
          borderRadius: 1,
          borderColor: theme.palette.mode === 'dark' ? theme.palette.divider : theme.palette.grey.A800,
          boxShadow:
            boxShadow && (!border || theme.palette.mode === 'dark') ? shadow || theme.customShadows.z0 : 'inherit',
          ':hover': {
            boxShadow: boxShadow ? shadow || theme.customShadows.z0 : 'inherit'
          },
          backgroundColor:
            color === 'default'
              ? theme.palette.background.paper
              : color === 'primary'
              ? lighten(theme.palette.primary[100], 0.5)
              : lighten(theme.palette.secondary[100], 0.5),
          ...(modal && {
            position: 'absolute',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            width: { xs: `calc( 100% - 50px)`, sm: 'auto' },
            '& .MuiCardContent-root': {
              overflowY: 'auto',
              minHeight: 'auto',
              maxHeight: `calc(100vh - 200px)`
            }
          }),
          ...sx
        }}
      >
        {!darkTitle && title ? (
          // @ts-ignore
          <CardHeader sx={headerSX} title={title} action={secondary} subheader={subheader} />
        ) : null}
        {darkTitle && title ? (
          <CardHeader
            sx={headerSX}
            title={<Typography variant="h4">{title as any}</Typography>}
            action={secondary as any}
          />
        ) : null}
        {title && divider ? <Divider /> : null}
        {content ? <CardContent sx={contentSX}>{children}</CardContent> : null}
        {!content && children}
      </Card>
    );
  }
);

export { MainCard };
export type { MainCardProps };
