// Copyright 2017-2019 @polkadot/app-staking authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces';
import { BareProps } from './types';

import BN from 'bn.js';
import React from 'react';
import styled from 'styled-components';
import { KeyringItemType } from '@polkadot/ui-keyring/types';

import { classes, getAddressName, toShortAddress } from './util';
import BalanceDisplay from './Balance';
import BondedDisplay from './Bonded';
import IdentityIcon from './IdentityIcon';

interface Props extends BareProps {
  balance?: BN | BN[];
  bonded?: BN | BN[];
  children?: React.ReactNode;
  iconInfo?: React.ReactNode;
  isPadded?: boolean;
  isShort?: boolean;
  type?: KeyringItemType;
  value?: AccountId | AccountIndex | Address | string | null;
  withAddress?: boolean;
  withBalance?: boolean;
  withBonded?: boolean;
}

function renderAddressOrName ({ isShort = false, withAddress = true, type }: Props, address: string): React.ReactNode {
  if (!withAddress) {
    return null;
  }

  const name = getAddressName(address, type);

  return (
    <div className={`ui--AddressMini-address ${name ? 'withName' : 'withAddr'}`}>{
      name || (
        isShort
          ? toShortAddress(address)
          : address
      )
    }</div>
  );
}

function renderBalance ({ balance, value, withBalance = false }: Props): React.ReactNode {
  if (!withBalance || !value) {
    return null;
  }

  return (
    <BalanceDisplay
      balance={balance}
      params={value}
    />
  );
}

function renderBonded ({ bonded, value, withBonded = false }: Props): React.ReactNode {
  if (!withBonded || !value) {
    return null;
  }

  return (
    <BondedDisplay
      bonded={bonded}
      label=''
      params={value}
    />
  );
}

function AddressMini (props: Props): React.ReactElement<Props> | null {
  const { children, className, iconInfo, isPadded = true, style, value } = props;

  if (!value) {
    return null;
  }

  const address = value.toString();

  return (
    <div
      className={classes('ui--AddressMini', isPadded ? 'padded' : '', className)}
      style={style}
    >
      <div className='ui--AddressMini-info'>
        {renderAddressOrName(props, address)}
        {children}
      </div>
      <div className='ui--AddressMini-icon'>
        <IdentityIcon
          size={24}
          value={address}
        />
        {iconInfo && (
          <div className='ui--AddressMini-icon-info'>
            {iconInfo}
          </div>
        )}
      </div>
      <div className='ui--AddressMini-balances'>
        {renderBalance(props)}
        {renderBonded(props)}
      </div>
    </div>
  );
}

export default styled(AddressMini)`
  display: inline-block;
  padding: 0 0.25rem 0 1rem;
  white-space: nowrap;

  &.padded {
    display: inline-block;
    padding: 0.25rem 0 0 1rem;
  }

  &.summary {
    position: relative;
    top: -0.2rem;
  }

  .ui--AddressMini-address {
    &.withAddr,
    &.withName {
      font-family: monospace;
      max-width: 9rem;
      min-width: 4em;
      overflow: hidden;
      text-align: right;
      text-overflow: ellipsis;
    }

    &.withName {
      text-transform: uppercase;
    }
  }

  .ui--AddressMini-balances {
    display: grid;

    .ui--Bonded {
      font-size: 0.75rem;
      margin-right: 2.25rem;
      margin-top: -0.5rem;
      text-align: right;
    }
  }

  .ui--AddressMini-icon {
    margin: 0 0 0 0.5rem;

    .ui--AddressMini-icon-info {
      position: absolute;
      right: -0.5rem;
      top: -0.5rem;
      z-index: 1;
    }

    .ui--IdentityIcon {
      margin: 0;
      vertical-align: middle;
    }
  }

  .ui--AddressMini-icon,
  .ui--AddressMini-info {
    display: inline-block;
    position: relative;
    vertical-align: middle;
  }
`;
