import { useAppConfig } from '@/components/AppStateProvider';
import { Button, ButtonProps, Stack, Typography } from '@mui/material';
import { get } from 'lodash';
import { FieldTitle, useRecordContext, useResourceContext } from 'ra-core';
import React, { ElementType } from 'react';

/**
 * Implements the ListItem component designed and drawn by Applica.
 * This component can be used in different combinations of properties and allows you to view and/or modify data
 * by adding decorative elements of details and customizations in data formatting.
 */
function ListItem({
  source,
  label,
  variant = 'body1',
  record: providedRecord,
  spaceBottom,
  spaceTop,
  component,
  leftIcon,
  rightIcon,
  button,
  buttonProps,
  ...props
}: ListItemProps): JSX.Element {
  const { getCurrentDialog } = useAppConfig();
  const resource = useResourceContext(props as any);
  const dialogResource = getCurrentDialog();
  const _record = useRecordContext();
  const record = providedRecord || _record;
  const value = get(record, (source as string) || '');
  return (
    <Stack
      direction="row"
      alignItems="center"
      justifyContent="space-between"
      sx={(theme) => ({
        pt: 1,
        pb: 1,
        borderBottom: `1px solid ${theme.palette.divider}`,
        ...(spaceBottom && { mb: 2 }),
        ...(spaceTop && { mt: 2 })
      })}
    >
      <Stack direction="row" alignItems="start">
        {leftIcon
          ? React.isValidElement(leftIcon)
            ? React.cloneElement(leftIcon, { style: defaultIconStyle } as any)
            : React.createElement(leftIcon as ElementType<any>, { style: defaultIconStyle })
          : null}
        <FieldTitle label={label} source={source} resource={dialogResource || resource} />
      </Stack>
      <Stack direction="row" alignItems="center">
        {component ? (
          React.isValidElement(component) ? (
            React.cloneElement(component, { record, resource, value } as any)
          ) : (
            React.createElement(component as ElementType<any>, { source, record, resource, value })
          )
        ) : (
          <Typography variant={variant}>{value}</Typography>
        )}
        {rightIcon
          ? React.isValidElement(rightIcon)
            ? React.cloneElement(rightIcon, { style: defaultIconStyle } as any)
            : React.createElement(rightIcon as ElementType<any>, { style: defaultIconStyle })
          : null}
        {button ? (
          <Button size="small" variant="outlined" sx={{ ml: 1, p: 0 }} {...buttonProps}>
            {button}
          </Button>
        ) : null}
      </Stack>
    </Stack>
  );
}

const defaultIconStyle = {
  width: '1.5rem',
  alignSelf: 'center'
};

type ListItemProps = {
  source?: string;
  label?: string;
  record?: any;
  variant?:
    | 'body1'
    | 'body2'
    | 'caption'
    | 'button'
    | 'h1'
    | 'h2'
    | 'h3'
    | 'h4'
    | 'h5'
    | 'h6'
    | 'inherit'
    | 'overline'
    | 'subtitle1'
    | 'subtitle2';
  spaceTop?: boolean;
  spaceBottom?: boolean;
  leftIcon?: ElementType<any>;
  rightIcon?: ElementType<any>;
  component?: ElementType<any>;
  button?: string;
  buttonProps?: ButtonProps;
};

export { ListItem };
export type { ListItemProps };
