import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { getTokenTrackerLink } from '@metamask/etherscan-link';
import { isEqual } from 'lodash';
import Box from '../../ui/box';
import Card from '../../ui/card';
import Typography from '../../ui/typography/typography';
import {
  COLORS,
  TYPOGRAPHY,
  FONT_WEIGHT,
  JUSTIFY_CONTENT,
  FLEX_DIRECTION,
  OVERFLOW_WRAP,
  DISPLAY,
  BLOCK_SIZES,
} from '../../../helpers/constants/design-system';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { getAssetImageURL, shortenAddress } from '../../../helpers/utils/util';
import {
  getCurrentChainId,
  getIpfsGateway,
  getRpcPrefsForCurrentProvider,
  getSelectedIdentity,
} from '../../../selectors';
import AssetNavigation from '../../../pages/asset/components/asset-navigation';
import Copy from '../../ui/icon/copy-icon.component';
import { getCollectibleContracts } from '../../../ducks/metamask/metamask';
import { DEFAULT_ROUTE, SEND_ROUTE } from '../../../helpers/constants/routes';
import {
  checkAndUpdateSingleCollectibleOwnershipStatus,
  removeAndIgnoreCollectible,
} from '../../../store/actions';
import {
  GOERLI_CHAIN_ID,
  KOVAN_CHAIN_ID,
  MAINNET_CHAIN_ID,
  POLYGON_CHAIN_ID,
  RINKEBY_CHAIN_ID,
  ROPSTEN_CHAIN_ID,
} from '../../../../shared/constants/network';
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app';
import CollectibleOptions from '../collectible-options/collectible-options';
import Button from '../../ui/button';
import { ASSET_TYPES, updateSendAsset } from '../../../ducks/send';
import InfoTooltip from '../../ui/info-tooltip';
import { ERC721 } from '../../../helpers/constants/common';
import { usePrevious } from '../../../hooks/usePrevious';
import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard';
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';

export default function CollectibleDetails({ collectible }) {
  const {
    image,
    imageOriginal,
    name,
    description,
    address,
    tokenId,
    standard,
    isCurrentlyOwned,
  } = collectible;
  const t = useI18nContext();
  const history = useHistory();
  const dispatch = useDispatch();
  const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
  const ipfsGateway = useSelector(getIpfsGateway);
  const collectibleContracts = useSelector(getCollectibleContracts);
  const currentNetwork = useSelector(getCurrentChainId);
  const [copied, handleCopy] = useCopyToClipboard();

  const collectibleContractName = collectibleContracts.find(
    ({ address: contractAddress }) =>
      isEqualCaseInsensitive(contractAddress, address),
  )?.name;
  const selectedAccountName = useSelector(
    (state) => getSelectedIdentity(state).name,
  );
  const collectibleImageURL = getAssetImageURL(
    imageOriginal ?? image,
    ipfsGateway,
  );

  const onRemove = () => {
    dispatch(removeAndIgnoreCollectible(address, tokenId));
    history.push(DEFAULT_ROUTE);
  };

  const prevCollectible = usePrevious(collectible);
  useEffect(() => {
    if (!isEqual(prevCollectible, collectible)) {
      checkAndUpdateSingleCollectibleOwnershipStatus(collectible);
    }
  }, [collectible, prevCollectible]);

  const getOpenSeaLink = () => {
    switch (currentNetwork) {
      case MAINNET_CHAIN_ID:
        return `https://opensea.io/assets/${address}/${tokenId}`;
      case POLYGON_CHAIN_ID:
        return `https://opensea.io/assets/matic/${address}/${tokenId}`;
      case GOERLI_CHAIN_ID:
      case KOVAN_CHAIN_ID:
      case ROPSTEN_CHAIN_ID:
      case RINKEBY_CHAIN_ID:
        return `https://testnets.opensea.io/assets/${address}/${tokenId}`;
      default:
        return null;
    }
  };

  const openSeaLink = getOpenSeaLink();
  const sendDisabled = standard !== ERC721;
  const inPopUp = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP;

  const onSend = async () => {
    await dispatch(
      updateSendAsset({
        type: ASSET_TYPES.COLLECTIBLE,
        details: collectible,
      }),
    );
    history.push(SEND_ROUTE);
  };

  const renderSendButton = () => {
    if (isCurrentlyOwned === false) {
      return <div style={{ height: '30px' }} />;
    }
    return (
      <Box
        display={DISPLAY.FLEX}
        width={inPopUp ? BLOCK_SIZES.FULL : BLOCK_SIZES.HALF}
        margin={inPopUp ? [4, 0] : null}
      >
        <Button
          type="primary"
          onClick={onSend}
          disabled={sendDisabled}
          className="collectible-details__send-button"
        >
          {t('send')}
        </Button>
        {sendDisabled ? (
          <InfoTooltip position="top" contentText={t('sendingDisabled')} />
        ) : null}
      </Box>
    );
  };

  return (
    <>
      <AssetNavigation
        accountName={selectedAccountName}
        assetName={collectibleContractName}
        onBack={() => history.push(DEFAULT_ROUTE)}
        optionsButton={
          <CollectibleOptions
            onViewOnOpensea={
              openSeaLink
                ? () => global.platform.openTab({ url: openSeaLink })
                : null
            }
            onRemove={onRemove}
          />
        }
      />
      <Box className="collectible-details">
        <div className="collectible-details__top-section">
          <Card
            padding={0}
            justifyContent={JUSTIFY_CONTENT.CENTER}
            className="collectible-details__card"
          >
            <img className="collectible-details__image" src={image} />
          </Card>
          <Box
            flexDirection={FLEX_DIRECTION.COLUMN}
            className="collectible-details__info"
            justifyContent={JUSTIFY_CONTENT.SPACE_BETWEEN}
          >
            <div>
              <Typography
                color={COLORS.TEXT_DEFAULT}
                variant={TYPOGRAPHY.H4}
                fontWeight={FONT_WEIGHT.BOLD}
                boxProps={{ margin: 0, marginBottom: 2 }}
              >
                {name}
              </Typography>
              <Typography
                color={COLORS.TEXT_MUTED}
                variant={TYPOGRAPHY.H5}
                boxProps={{ margin: 0, marginBottom: 4 }}
                overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
              >
                #{tokenId}
              </Typography>
            </div>
            {description ? (
              <div>
                <Typography
                  color={COLORS.TEXT_DEFAULT}
                  variant={TYPOGRAPHY.H6}
                  fontWeight={FONT_WEIGHT.BOLD}
                  className="collectible-details__description"
                  boxProps={{ margin: 0, marginBottom: 2 }}
                >
                  {t('description')}
                </Typography>
                <Typography
                  color={COLORS.TEXT_ALTERNATIVE}
                  variant={TYPOGRAPHY.H6}
                  boxProps={{ margin: 0, marginBottom: 4 }}
                >
                  {description}
                </Typography>
              </div>
            ) : null}
            {inPopUp ? null : renderSendButton()}
          </Box>
        </div>
        <Box marginBottom={2}>
          <Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.ROW}>
            <Typography
              color={COLORS.TEXT_DEFAULT}
              variant={TYPOGRAPHY.H6}
              fontWeight={FONT_WEIGHT.BOLD}
              boxProps={{
                margin: 0,
                marginBottom: 4,
                marginRight: 2,
              }}
              className="collectible-details__link-title"
            >
              {t('source')}
            </Typography>
            <Typography
              color={COLORS.PRIMARY_DEFAULT}
              variant={TYPOGRAPHY.H6}
              boxProps={{
                margin: 0,
                marginBottom: 4,
              }}
              className="collectible-details__image-link"
            >
              <a
                target="_blank"
                rel="noopener noreferrer"
                href={collectibleImageURL}
                title={collectibleImageURL}
              >
                {collectibleImageURL}
              </a>
            </Typography>
          </Box>
          <Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.ROW}>
            <Typography
              color={COLORS.TEXT_DEFAULT}
              variant={TYPOGRAPHY.H6}
              fontWeight={FONT_WEIGHT.BOLD}
              boxProps={{
                margin: 0,
                marginBottom: 4,
                marginRight: 2,
              }}
              className="collectible-details__link-title"
            >
              {t('contractAddress')}
            </Typography>
            <Box
              display={DISPLAY.FLEX}
              flexDirection={FLEX_DIRECTION.ROW}
              className="collectible-details__contract-wrapper"
            >
              <Typography
                color={COLORS.PRIMARY_DEFAULT}
                variant={TYPOGRAPHY.H6}
                overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
                boxProps={{
                  margin: 0,
                  marginBottom: 4,
                }}
                className="collectible-details__contract-link"
              >
                <a
                  target="_blank"
                  rel="noopener noreferrer"
                  href={getTokenTrackerLink(
                    address,
                    currentNetwork,
                    null,
                    null,
                    rpcPrefs,
                  )}
                  title={address}
                >
                  {inPopUp ? shortenAddress(address) : address}
                </a>
              </Typography>
              <button
                className="collectible-details__contract-copy-button"
                onClick={() => {
                  handleCopy(address);
                }}
              >
                {copied ? (
                  t('copiedExclamation')
                ) : (
                  <Copy size={15} color="#6a737d" />
                )}
              </button>
            </Box>
          </Box>
          {inPopUp ? renderSendButton() : null}
        </Box>
      </Box>
    </>
  );
}

CollectibleDetails.propTypes = {
  collectible: PropTypes.shape({
    address: PropTypes.string.isRequired,
    tokenId: PropTypes.string.isRequired,
    isCurrentlyOwned: PropTypes.bool,
    name: PropTypes.string,
    description: PropTypes.string,
    image: PropTypes.string,
    standard: PropTypes.string,
    imageThumbnail: PropTypes.string,
    imagePreview: PropTypes.string,
    imageOriginal: PropTypes.string,
    creator: PropTypes.shape({
      address: PropTypes.string,
      config: PropTypes.string,
      profile_img_url: PropTypes.string,
    }),
  }),
};