import React from 'react';
import classNames from 'classnames';

import { getInitials } from '../util/getInitials';
import { LocalizerType } from '../types/Util';

interface Props {
  avatarPath?: string;
  color?: string;
  conversationType: 'group' | 'direct';
  i18n: LocalizerType;
  noteToSelf?: boolean;
  name?: string;
  phoneNumber?: string;
  profileName?: string;
  size: number;
  borderColor?: string;
  borderWidth?: number;
}

interface State {
  imageBroken: boolean;
}

export class Avatar extends React.Component<Props, State> {
  public handleImageErrorBound: () => void;

  public constructor(props: Props) {
    super(props);

    this.handleImageErrorBound = this.handleImageError.bind(this);

    this.state = {
      imageBroken: false,
    };
  }

  public handleImageError() {
    // tslint:disable-next-line no-console
    console.log('Avatar: Image failed to load; failing over to placeholder');
    this.setState({
      imageBroken: true,
    });
  }

  public renderImage() {
    const {
      avatarPath,
      i18n,
      name,
      phoneNumber,
      profileName,
      borderColor,
      borderWidth,
    } = this.props;
    const { imageBroken } = this.state;

    if (!avatarPath || imageBroken) {
      return null;
    }

    const title = `${name || phoneNumber}${
      !name && profileName ? ` ~${profileName}` : ''
    }`;

    const borderStyle = this.getBorderStyle(borderColor, borderWidth);

    return (
      <img
        style={borderStyle}
        onError={this.handleImageErrorBound}
        alt={i18n('contactAvatarAlt', [title])}
        src={avatarPath}
      />
    );
  }

  public renderNoImage() {
    const {
      conversationType,
      name,
      noteToSelf,
      size,
      borderColor,
      borderWidth,
    } = this.props;

    const initials = getInitials(name);
    const isGroup = conversationType === 'group';

    if (noteToSelf) {
      return (
        <div
          className={classNames(
            'module-avatar__icon',
            'module-avatar__icon--note-to-self',
            `module-avatar__icon--${size}`
          )}
        />
      );
    }

    const borderStyle = this.getBorderStyle(borderColor, borderWidth);

    if (!isGroup && initials) {
      return (
        <div
          className={classNames(
            'module-avatar__label',
            `module-avatar__label--${size}`
          )}
          style={borderStyle}
        >
          {initials}
        </div>
      );
    }

    return (
      <div
        className={classNames(
          'module-avatar__icon',
          `module-avatar__icon--${conversationType}`,
          `module-avatar__icon--${size}`
        )}
        style={borderStyle}
      />
    );
  }

  public render() {
    const { avatarPath, color, size, noteToSelf } = this.props;
    const { imageBroken } = this.state;

    const hasImage = !noteToSelf && avatarPath && !imageBroken;

    if (size !== 28 && size !== 36 && size !== 48 && size !== 80) {
      throw new Error(`Size ${size} is not supported!`);
    }

    return (
      <div
        className={classNames(
          'module-avatar',
          `module-avatar--${size}`,
          hasImage ? 'module-avatar--with-image' : 'module-avatar--no-image',
          !hasImage ? `module-avatar--${color}` : null
        )}
      >
        {hasImage ? this.renderImage() : this.renderNoImage()}
      </div>
    );
  }

  private getBorderStyle(color?: string, width?: number) {
    const borderWidth = typeof width === 'number' ? width : 3;

    return color
      ? {
          borderColor: color,
          borderStyle: 'solid',
          borderWidth: borderWidth,
        }
      : undefined;
  }
}
