import * as React from 'react';
import { useCallback } from 'react';
import PropTypes from 'prop-types';
import DownloadIcon from '@mui/icons-material/GetApp';
import {
  Exporter,
  FilterPayload,
  fetchRelatedRecords,
  useDataProvider,
  useListContext,
  useNotify,
  useResourceContext
} from 'ra-core';
import { Button, ButtonProps } from './Button';

/**
 * Custom ExportButton that exports data.
 *
 *
 * @example
 * import { ExportButton } from '@applica-software-guru/react-admin';
 * import { TopToolbar } from 'react-admin';
 *
 * const ListActions = () => (
 *   <TopToolbar>
 *     <ExportButton />
 *   </TopToolbar>
 * );
 */
function _ExportButton(props: ExportButtonProps) {
  const {
    maxResults = 1000,
    onClick,
    label = 'ra.action.export',
    icon = defaultIcon,
    exporter: customExporter,
    meta,
    sort,
    ...rest
  } = props;
  const { filter, filterValues, exporter: exportContext, total } = useListContext(props);
  const resource = useResourceContext(props);
  const exporter = customExporter || exportContext;
  const dataProvider = useDataProvider();
  const notify = useNotify();

  const handleClick = useCallback(
    (event: React.MouseEvent) => {
      dataProvider
        .getList(resource, {
          sort: { field: '_id', order: 'ASC' },
          filter: filter ? { ...filterValues, ...filter } : filterValues,
          pagination: { page: 1, perPage: maxResults },
          meta
        })
        .then(({ data }) => exporter && exporter(data, fetchRelatedRecords(dataProvider), dataProvider, resource))
        .catch((error) => {
          console.error(error);
          notify('ra.notification.http_error', { type: 'error' });
        });
      if (typeof onClick === 'function') {
        onClick(event as any);
      }
    },
    [dataProvider, exporter, filter, filterValues, maxResults, notify, onClick, resource, meta]
  );

  return (
    <Button onClick={handleClick} label={label} disabled={total === 0} {...rest}>
      {icon}
    </Button>
  );
}

interface Props {
  exporter?: Exporter;
  filterValues?: FilterPayload;
  icon?: JSX.Element;
  label?: string;
  maxResults?: number;
  onClick?: (e: Event) => void;
  resource?: string;
  meta?: any;
  sort?: any;
}

type ExportButtonProps = Props & ButtonProps;

_ExportButton.propTypes = {
  exporter: PropTypes.func,
  filterValues: PropTypes.object,
  label: PropTypes.string,
  maxResults: PropTypes.number,
  resource: PropTypes.string,
  icon: PropTypes.element,
  meta: PropTypes.any
};

const defaultIcon = <DownloadIcon />;

const ExportButton = React.memo(_ExportButton);

export { ExportButton };
export type { ExportButtonProps };
