import { type ReactNode, useState } from 'react';

import { ExpandLess, ExpandMore } from '@mui/icons-material';
import {
  ListItem,
  ListItemButton,
  ListItemText,
  Skeleton,
  Stack,
  type StackProps,
  Typography,
} from '@mui/material';

import LinearProgressWithLabel from './LinearProgressWithLabel';

export const ParticipationItemSkeleton = () => (
  <Stack
    sx={{
      flexDirection: 'row',
      justifyContent: 'space-between',
      alignItems: 'center',
      px: 2,
      py: 1,
    }}
  >
    <Skeleton
      variant="text"
      width={200}
      height={16}
    />
    <Stack sx={{ alignItems: 'flex-end' }}>
      <Skeleton
        variant="text"
        width={130}
        height={14}
      />
      <Skeleton
        variant="text"
        width={100}
        height={12}
      />
    </Stack>
  </Stack>
);

type MiscProps = StackProps & {
  noDataMessage?: ReactNode;
  label: string;
  isEmpty?: boolean;
  value: number;
};

const Misc = ({
  isEmpty,
  value,
  noDataMessage,
  label,
  ...props
}: MiscProps) => {
  if (isEmpty) {
    return (
      <Typography
        variant="body1"
        color="secondary"
      >
        {noDataMessage}
      </Typography>
    );
  }

  return (
    <Stack
      {...props}
      sx={{ alignItems: 'flex-end', ...props.sx }}
    >
      <LinearProgressWithLabel
        value={value}
        sx={{ flexDirection: 'row' }}
      />
      <Typography
        variant="body2"
        color="secondary"
      >
        {label}
      </Typography>
    </Stack>
  );
};

export type ParticipationItemProps = {
  primary: string;
  secondary?: string | null;
  value: MiscProps['value'];
  slotProps: {
    misc: Omit<MiscProps, 'value'>;
  };
};

export const ParticipationItem = ({
  primary,
  secondary,
  slotProps,
  value,
}: ParticipationItemProps) => (
  <ListItem>
    <ListItemText
      primary={primary}
      secondary={secondary}
    />
    <Misc
      value={value}
      {...slotProps.misc}
    />
  </ListItem>
);

export type ParticipationExpandableItemProps = ParticipationItemProps & {
  children: (expandable: boolean) => ReactNode;
};

export const ParticipationExpandableItem = ({
  children,
  primary,
  secondary,
  slotProps,
  value,
}: ParticipationExpandableItemProps) => {
  const [expanded, setExpanded] = useState(false);

  const handleToggle = () => setExpanded(prev => !prev);

  return (
    <>
      <ListItemButton
        sx={{ gap: 2 }}
        onClick={handleToggle}
      >
        <Stack
          sx={{
            flexDirection: 'row',
            justifyContent: 'flex-start',
            alignItems: 'center',
            gap: 2,
            flex: 1,
          }}
        >
          <ListItemText
            primary={primary}
            secondary={secondary}
            sx={{ flexGrow: 0 }}
          />
          {expanded ? (
            <ExpandLess color="secondary" />
          ) : (
            <ExpandMore color="secondary" />
          )}
        </Stack>
        <Misc
          value={value}
          {...slotProps.misc}
        />
      </ListItemButton>
      {children(expanded)}
    </>
  );
};
