import 'iconify-icon';
import { useState } from 'react';
import { useAsyncEffect } from 'ahooks';
import { Avatar } from '@mui/material';
import type { AvatarProps, BoxProps } from '@mui/material';
import { Icon as IconifyIcon, loadIcon } from '@iconify/react';
import { isUrl } from '../utils';

/**
 * Icon 组件, 基于 mui Avatar 组件扩展对 iconify 的支持
 */
export default function Icon({
  icon,
  size = undefined,
  sx = {},
  ...rest
}: {
  icon: string;
  size?: number;
  sx?: BoxProps['sx'];
} & AvatarProps) {
  // eslint-disable-next-line @typescript-eslint/naming-convention
  const _sx = [...(Array.isArray(sx) ? sx : [sx])];
  if (size) {
    _sx.push({ width: size, height: size });
  }
  const [isIconify, setIsIconify] = useState(false);
  // NOTICE: 需要设置默认为 true，代表在判断 icon 是否为 iconify 时，需要等待 icon 加载完成
  const [loading, setLoading] = useState(true);
  useAsyncEffect(async () => {
    setLoading(true);
    try {
      await loadIcon(icon);
      setIsIconify(true);
    } catch {
      setIsIconify(false);
    }
    setLoading(false);
  }, [icon]);
  // 禁用默认的 circular variant 样式
  if (!rest.variant) {
    _sx.push({
      '&.MuiAvatar-root': {
        color: 'inherit',
        fontWeight: 'bold',
        backgroundColor: 'transparent',
        borderRadius: 0,
      },
      // 无 icon 背景时, svg icon 尺寸与窗口尺寸一致
      '&.MuiAvatar-root svg': {
        width: '100%',
        height: '100%',
      },
    });
  }
  if (isUrl(icon)) {
    return <Avatar component="span" {...rest} src={icon} sx={_sx} />;
  }
  // y = 0.6 * x + 4
  const height = size ? 0.6 * size + 4 : 0;

  if (loading) {
    return <IconifyIcon icon="codicon:blank" height={height || undefined} />;
  }
  if (isIconify) {
    return (
      <Avatar component="span" {...rest} sx={_sx}>
        <IconifyIcon icon={icon} height={height || undefined} />
      </Avatar>
    );
  }
  // letter avatar
  if (icon && typeof icon === 'string') {
    _sx.push({
      '&.MuiAvatar-root': {
        display: 'inline-flex',
        ...(size && { fontSize: size - 2 }),
      },
    });
    return (
      <Avatar component="span" {...rest} sx={_sx}>
        {Array.from(icon)[0]}
      </Avatar>
    );
  }
  return null;
}
