import { ListView } from '@/components/ra-lists/ListView';
import { styled } from '@mui/system';
import { ListBase, RaRecord } from 'ra-core';
import { ReactElement } from 'react';
import { ListProps } from 'react-admin';
import { Pagination } from '@/components/Pagination/Pagination';
import { ListViewProvider } from './ListViewProvider';

/**
 * List page component
 *
 * The <List> component renders the list layout (title, buttons, filters, pagination),
 * and fetches the list of records from the REST API.
 *
 * It then delegates the rendering of the list of records to its child component.
 * Usually, it's a <Datagrid>, responsible for displaying a table with one row for each post.
 *
 * The <List> component accepts the following props:
 *
 * - actions
 * - aside: Side Component
 * - children: List Layout
 * - component
 * - disableAuthentication
 * - disableSyncWithLocation
 * - empty: Empty Page Component
 * - emptyWhileLoading
 * - exporter
 * - filters: Filter Inputs
 * - filter: Permanent Filter
 * - filterDefaultValues
 * - pagination: Pagination Component
 * - perPage: Pagination Size
 * - queryOptions
 * - sort: Default Sort Field & Order
 * - title
 * - sx: CSS API
 *
 * @example
 * const postFilters = [
 *     <TextInput label="Search" source="q" alwaysOn />,
 *     <TextInput label="Title" source="title" />
 * ];
 * export const PostList = () => (
 *     <List
 *         title="List of posts"
 *         sort={{ field: 'published_at' }}
 *         filter={{ is_published: true }}
 *         filters={postFilters}
 *     >
 *         <Datagrid>
 *             <TextField source="id" />
 *             <TextField source="title" />
 *             <EditButton />
 *         </Datagrid>
 *     </List>
 * );
 */

function RaList<RecordType extends RaRecord = any>({
  debounce,
  disableAuthentication,
  disableSyncWithLocation,
  exporter,
  filter = defaultFilter,
  filterDefaultValues,
  perPage = 10,
  queryOptions,
  resource,
  sort,
  storeKey,
  ...rest
}: ListProps): ReactElement {
  return (
    <ListBase<RecordType>
      debounce={debounce}
      disableAuthentication={disableAuthentication}
      disableSyncWithLocation={disableSyncWithLocation}
      exporter={exporter}
      filter={filter}
      filterDefaultValues={filterDefaultValues}
      perPage={perPage}
      queryOptions={queryOptions}
      resource={resource}
      sort={sort}
      storeKey={storeKey}
    >
      <ListViewProvider>
        <ListView<RecordType> {...rest} />
      </ListViewProvider>
    </ListBase>
  );
}

const defaultFilter = {};

const StyledList = styled(RaList, { slot: 'root' })(({ theme }) => ({
  '& .RaList-main': {
    overflowX: 'auto',
    '& .RaBulkActionsToolbar-toolbar': {
      // The react-admin bulk actions toolbar is not perfectly compatible with the
      // mantis theme, so I had to make a series of corrections to align it correctly
      // and allow its use even on tables with horizontal scrolling (especially on mobile).
      height: 36,
      top: 42,
      paddingTop: 16,
      '& .RaBulkActionsToolbar-title': {
        alignItems: 'end',
        '& .MuiTypography-root': {
          alignSelf: 'center'
        }
      }
    },
    '& .MuiToolbar-root': {
      '& form': {
        padding: theme.spacing(2),
        paddingBottom: theme.spacing(2),
        alignItems: 'flex-start'
      }
    },
    '& .MuiButton-root': {
      margin: 0
    },

    '& .RaList-actions': {
      minHeight: 80,
      alignItems: 'center',
      borderTopLeftRadius: `${theme.shape.borderRadius}px`,
      borderTopRightRadius: `${theme.shape.borderRadius}px`,
      borderBottomLeftRadius: 0,
      borderBottomRightRadius: 0,
      [theme.breakpoints.down('sm')]: {
        flexDirection: 'row'
      },
      '& form': {
        alignItems: 'center',
        minHeight: 'auto',
        paddingBottom: 0,
        rowGap: theme.spacing(2.5)
      },
      '& .RaFilterForm-filterFormInput': {
        margin: 0,
        '& .MuiInputLabel-root': {
          paddingTop: 0
        },
        '& .MuiFormControl-root': {
          marginTop: 0
        },
        '& .ra-input': {
          alignSelf: 'center',
          marginTop: 0
        },
        // This rule allows each filter input to be 100% width when the screen is small.
        [theme.breakpoints.down('sm')]: {
          '&>.MuiStack-root': {
            width: '100%',
            '&>div:not(.MuiStack-root)': {
              width: '100%'
            }
          }
        }
      },
      '& .RaFilterFormInput-hideButton': {
        margin: '0 !important',
        alignSelf: 'center'
      },
      '& .MuiToolbar-root': {
        flex: 'unset',
        padding: 0,
        alignSelf: 'center',
        minHeight: 'fit-content',
        [theme.breakpoints.down('sm')]: {
          paddingBottom: theme.spacing(2)
        }
      }
    },

    '& .RaList-content': {
      borderRadius: 0,
      // Resolve an issue related to the visualization of the bulk actions toolbar.
      // Padding and margin create a non empty space that allows the toolbar to be displayed when
      // the selection is empty.
      '& .RaBulkActionsToolbar-collapsed': {
        height: 0,
        paddingTop: 0,
        paddingBottom: 0
      },
      // Resolve a defect related to the usage of AntDesign icons with Mantis and React-Admin.
      // These two lines are not needed if you are not using AntDesign icons.
      '& .icon span': {
        top: -1,
        left: -1
      }
    },
    '& .ApplicaEmpty-root': {
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center',
      alignItems: 'center',
      height: 'calc(100vh - 260px)',
      backgroundColor: theme.palette.background.paper,
      border: '1px solid',
      borderTop: 'none',
      borderColor: theme.palette.mode === 'dark' ? theme.palette.divider : theme.palette.grey.A800,
      borderBottomLeftRadius: `${theme.shape.borderRadius}px`,
      borderBottomRightRadius: `${theme.shape.borderRadius}px`
    }
  },

  '& .RaList-noResults': {
    backgroundColor: theme.palette.background.paper,
    border: '1px solid',
    borderColor: theme.palette.mode === 'dark' ? theme.palette.divider : theme.palette.grey.A800,
    borderRadius: `${theme.shape.borderRadius}px`
  },

  '& .RaEmpty-toolbar': {
    margin: theme.spacing(2)
  }
}));

function List(props: ListProps): ReactElement {
  const passProps = { ...props, pagination: props.pagination ?? <Pagination /> };

  return <StyledList {...passProps} />;
}

export { List };
export type { ListProps };
