import { type FC, memo } from 'react';
import { Link as RouterLink } from 'react-router-dom';

import Avatar, { type AvatarProps } from '@material-hu/mui/Avatar';
import Badge from '@material-hu/mui/Badge';
import { type SxProps, useTheme } from '@material-hu/mui/styles';

import { useAuth } from 'src/contexts/JWTContext';
import { profileRoutes } from 'src/pages/dashboard/profile/routes';
import { type User } from 'src/types/user';
import { getFullName, getInitials } from 'src/utils/userUtils';

const getSizeInPixels = (
  size: 'small' | 'medium' | 'large' | number,
): string => {
  switch (size) {
    case 'small':
      return '32px';
    case 'medium':
      return '40px';
    case 'large':
      return '50px';
    default:
      return `${size}px`;
  }
};

export type ProfilePictureProps = Omit<AvatarProps, 'id'> & {
  user: Partial<User> & Pick<User, 'id' | 'profilePicture'>;
  withInitials?: boolean;
  size?: 'small' | 'medium' | 'large' | number;
  withBadge?: boolean;
  badgeSize?: string;
  badgeImage?: string;
  badgeSx?: SxProps;
  onLoad?: any;
  withUserDeleted?: boolean;
} & (
    | {
        withLink: true;
        openInNewTab?: boolean;
        id: number;
      }
    | {
        withLink?: false;
        openInNewTab?: never;
        id?: number;
      }
  );

export const ProfilePicture: FC<ProfilePictureProps> = memo(
  function ProfilePictureComponent(props) {
    const {
      id,
      user,
      withLink = false,
      withInitials = false,
      size = 'medium',
      withBadge,
      badgeImage,
      badgeSize,
      badgeSx,
      sx = {},
      onLoad,
      withUserDeleted = false,
      openInNewTab = false,
      ...avatarProps
    } = props;

    const { instance } = useAuth();
    const theme = useTheme();

    const sizeInPixels = getSizeInPixels(size);
    const styles = {
      width: sizeInPixels,
      height: sizeInPixels,
      textDecoration: 'none',
      lineHeight: `calc(${sizeInPixels} / 2)`,
      fontSize: `calc(${sizeInPixels} / 2)`,
      backgroundColor: instance?.color,
      color: theme.palette.newBase?.grey[50],
      ...sx,
    };

    const badgeProps = {
      withBadge,
      badgeImage,
      badgeSize,
      badgeSx,
    };

    const openInNewTabProps = openInNewTab
      ? {
          target: '_blank' as const,
          rel: 'noopener noreferrer' as const,
        }
      : ({} as const);

    if (!user) {
      return (
        <BadgeWrapper {...badgeProps}>
          <Avatar
            {...avatarProps}
            sx={styles}
            src={undefined}
          />
        </BadgeWrapper>
      );
    }

    const showInitials = withInitials || !user.profilePicture;
    const showLink = withLink && !!id;

    const fullName = user.fullName || getFullName(user);

    if (showInitials) {
      if (showLink) {
        return (
          <BadgeWrapper {...badgeProps}>
            <Avatar
              sx={styles}
              alt={fullName}
              component={RouterLink}
              to={profileRoutes.profile(id)}
              {...openInNewTabProps}
            >
              {getInitials(fullName)}
            </Avatar>
          </BadgeWrapper>
        );
      }

      return (
        <BadgeWrapper {...badgeProps}>
          <Avatar
            sx={{
              ...styles,
              filter: withUserDeleted ? 'grayscale(100%) opacity(0.8)' : '',
            }}
            alt={fullName}
          >
            {getInitials(fullName)}
          </Avatar>
        </BadgeWrapper>
      );
    }

    if (showLink) {
      return (
        <BadgeWrapper {...badgeProps}>
          <Avatar
            sx={styles}
            src={user.profilePicture || undefined}
            alt={fullName}
            component={RouterLink}
            to={profileRoutes.profile(id)}
            onLoad={onLoad}
            {...openInNewTabProps}
          />
        </BadgeWrapper>
      );
    }

    return (
      <BadgeWrapper {...badgeProps}>
        <Avatar
          {...avatarProps}
          sx={{
            ...styles,
            filter: withUserDeleted ? 'grayscale(100%) opacity(0.8)' : '',
          }}
          src={user.profilePicture || undefined}
          alt={fullName}
          onLoad={onLoad}
        />
      </BadgeWrapper>
    );
  },
);

type BadgeWrapperProps = {
  children: React.ReactNode;
} & Pick<
  ProfilePictureProps,
  'withBadge' | 'badgeImage' | 'badgeSize' | 'badgeSx'
>;

const BadgeWrapper = ({
  children,
  withBadge,
  badgeImage,
  badgeSize = '24px',
  badgeSx = null,
}: BadgeWrapperProps) => {
  if (!withBadge || !badgeImage) return children;

  return (
    <Badge
      overlap="circular"
      anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
      sx={badgeSx}
      badgeContent={
        <img
          alt=""
          height={badgeSize}
          width={badgeSize}
          src={badgeImage}
        />
      }
    >
      {children}
    </Badge>
  );
};

export default ProfilePicture;
