/* eslint-disable filenames/match-regex */
import { Box, SxProps, Typography, styled } from '@mui/material';
import { useGetResourceLabel, useResourceContext, useResourceDefinition, useTranslate } from 'ra-core';
import * as React from 'react';
import { CreateButton } from '@/components/ra-buttons';
import clsx from 'clsx';
import { EmptyIcon, NotFoundIcon } from './icons';
import { useThemeConfig } from '@/components/Layout/ThemeProvider';

type EmptyProps = {
  /**
   * The actions of the empty page.
   *
   * @example <Button label="Refresh" onClick={refresh} />
   * @example <Button label="Add" onClick={add} />
   * @example <Button label="Export" onClick={export} />
   * @example <Button label="Import" onClick={import} />
   **/
  actions?: React.ReactNode;
  /**
   * The class name of the empty page.
   *
   * @example 'my-custom-empty'
   * @example 'my-custom-empty my-custom-empty--full-width'
   **/
  className?: string;
  hasCreate?: boolean;
  /**
   * The icon of the empty page.
   *
   * @example <DropboxOutlined />
   * @example <DropboxOutlined style={{ fontSize: '9em' }} />
   **/
  icon?: React.ReactNode;
  /**
   * The title of the empty page.
   *
   * @example 'No data available'
   * @example translate('ra_text')
   **/
  title?: string | React.ReactNode;
  /**
   * The subtitle of the empty page.
   *
   * @example 'Please add some data'
   * @example translate('ra_text')
   **/
  subtitle?: string | React.ReactNode;
  sx?: SxProps;
  /**
   * If true the component height fits its content (auto),
   * otherwise it takes the full available height.
   */
  fitContent?: boolean;
};

const StyledToolbar = styled('div')(({ theme }) => ({
  padding: theme.spacing(2),
  display: 'flex',
  justifyContent: 'center',
  gap: theme.spacing(2)
}));

const PREFIX = 'ApplicaEmpty';

const EmptyClasses = {
  message: `${PREFIX}-message`,
  icon: `${PREFIX}-icon`,
  toolbar: `${PREFIX}-toolbar`
};

interface RootProps {
  horizontal?: boolean;
  sx?: SxProps;
  className?: string;
  children?: React.ReactNode;
  fitContent?: boolean;
}

const Root = styled('div', {
  name: PREFIX,
  slot: 'Root',
  overridesResolver: (_, styles) => styles.root,
  shouldForwardProp: (prop) => prop !== 'horizontal' && prop !== 'fitContent'
})<RootProps>(({ theme, horizontal, fitContent }) => ({
  flex: 1,
  height: fitContent ? 'auto' : horizontal ? 'calc(100vh - 240px)' : 'calc(100vh - 200px)',
  [`& .${EmptyClasses.message}`]: {
    textAlign: 'center',
    opacity: theme.palette.mode === 'light' ? 1 : 0.8,
    margin: '0 1em',
    color: theme.palette.mode === 'light' ? 'inherit' : theme.palette.text.primary
  },
  [`& .${EmptyClasses.icon}`]: {
    fontSize: '9em',
    marginTop: '16px',
    marginBottom: '16px'
  },
  [`& .${EmptyClasses.toolbar}`]: {
    textAlign: 'center'
  }
}));

function getEmptyIcon({ icon, className }: { icon?: React.ReactNode; className?: string }) {
  if (icon !== undefined) return icon;
  if (className?.includes('RaList-noResults')) {
    return <NotFoundIcon className={EmptyClasses.icon} />;
  }
  return <EmptyIcon className={EmptyClasses.icon} />;
}

/**
 * Mostra una pagina vuota per le liste senza risultati o senza dati.
 * Da usare solo all'interno di un componente List.
 *
 * @example
 * <List empty={<Empty actions={<Button label="Add" onClick={add} />} />} />
 */
function Empty({
  actions,
  className,
  hasCreate: hasCreateProp,
  icon,
  title,
  subtitle,
  sx,
  fitContent = false,
  ...props
}: EmptyProps): JSX.Element {
  const { hasCreate } = useResourceDefinition(props);
  const canCreate = hasCreateProp !== undefined ? hasCreateProp : hasCreate;
  const resource = useResourceContext();
  const translate = useTranslate();
  const getResourceLabel = useGetResourceLabel();
  const resourceName = resource
    ? translate(`resources.${resource}.name`, {
        smart_count: 0,
        _: getResourceLabel(resource, 0)
      })
    : translate('ra.empty.no_resource');
  const emptyMessage = translate('ra.page.empty', { name: resourceName });
  const inviteMessage = translate('ra.page.invite');

  const { themeOrientation } = useThemeConfig();
  const isHorizontal = themeOrientation === 'horizontal';

  return (
    <Root className={clsx(`${PREFIX}-root`, className)} sx={sx} horizontal={isHorizontal} fitContent={fitContent}>
      <Box className={EmptyClasses.message}>
        {getEmptyIcon({ icon, className })}
        <Typography variant="h4" paragraph>
          {title ||
            translate(`resources.${resource}.empty`, {
              _: emptyMessage
            })}
        </Typography>
        {subtitle ||
          (canCreate ? (
            <Typography variant="body1">
              {translate(`resources.${resource}.invite`, {
                _: inviteMessage
              })}
            </Typography>
          ) : null)}
      </Box>
      <StyledToolbar className={EmptyClasses.toolbar}>
        {actions || (canCreate ? <CreateButton variant="contained" size="medium" disableFloatingButton /> : null)}
      </StyledToolbar>
    </Root>
  );
}

export { Empty, EmptyClasses };
export type { EmptyProps };
