import { useMemo } from 'react';

import Stack from '@material-hu/mui/Stack';
import { type SxProps, type Theme } from '@material-hu/mui/styles';
import Typography, { type TypographyProps } from '@material-hu/mui/Typography';

import {
  createCurrencyFormatter,
  resolveCurrencyAmount,
} from './resolveCurrencyAmount';

const fractionSupSx: SxProps<Theme> = theme => ({
  fontSize: '0.5em',
  fontWeight: 'inherit',
  verticalAlign: 'super',
  display: 'inline',
  marginLeft: theme.spacing(0.1),
});

export type CurrencyAmountProps = {
  value: number | string | null | undefined;
  currency?: string;
  variant?: TypographyProps['variant'];
  sx?: SxProps<Theme>;
};

type EmptySlotProps = Pick<CurrencyAmountProps, 'variant' | 'sx'>;

function CurrencyAmountEmpty({ variant = 'globalM', sx }: EmptySlotProps) {
  return (
    <Typography
      variant={variant}
      sx={{ fontVariantNumeric: 'tabular-nums', ...sx }}
    >
      —
    </Typography>
  );
}

// TODO: move to HuGo Components after Design analysis
export const CurrencyAmount = ({
  value,
  currency = 'MXN',
  variant = 'globalM',
  sx,
}: CurrencyAmountProps) => {
  const formatter = useMemo(
    () => createCurrencyFormatter(currency),
    [currency],
  );

  const resolved = resolveCurrencyAmount(value, formatter);
  if (resolved === null) {
    return (
      <CurrencyAmountEmpty
        variant={variant}
        sx={sx}
      />
    );
  }

  const { accessibleLabel, parts } = resolved;

  return (
    <Typography
      variant={variant}
      aria-label={accessibleLabel}
      sx={{
        fontVariantNumeric: 'tabular-nums',
        whiteSpace: 'nowrap',
        ...sx,
      }}
    >
      {parts.map((part, index) => {
        if (part.type === 'fraction') {
          return (
            <Stack
              key={index}
              component="span"
              sx={fractionSupSx}
            >
              {part.value}
            </Stack>
          );
        }
        return <span key={index}>{part.value}</span>;
      })}
    </Typography>
  );
};
