import { memo, useCallback, useMemo } from '../../../../lib/teact/teact';
import { getActions } from '../../../../global';

import type {
  ApiPeer,
  ApiStarsTransaction,
} from '../../../../api/types';
import type { GlobalState } from '../../../../global/types';
import type { CustomPeer } from '../../../../types';

import { NNBSP, STARS_CURRENCY_CODE, TON_CURRENCY_CODE } from '../../../../config';
import { buildStarsTransactionCustomPeer,
  formatStarsTransactionAmount,
  shouldUseCustomPeer } from '../../../../global/helpers/payments';
import { getPeerTitle } from '../../../../global/helpers/peers';
import { selectPeer } from '../../../../global/selectors';
import buildClassName from '../../../../util/buildClassName';
import { formatDateTimeToString } from '../../../../util/dates/oldDateFormat';
import { CUSTOM_PEER_PREMIUM } from '../../../../util/objects/customPeer';
import { getGiftAttributes, getStickerFromGift } from '../../../common/helpers/gifts';
import renderText from '../../../common/helpers/renderText';
import { getTransactionTitle, isNegativeAmount } from '../helpers/transaction';

import useSelector from '../../../../hooks/data/useSelector';
import useLang from '../../../../hooks/useLang';
import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang';

import AnimatedIconFromSticker from '../../../common/AnimatedIconFromSticker';
import Avatar from '../../../common/Avatar';
import Icon from '../../../common/icons/Icon';
import StarIcon from '../../../common/icons/StarIcon';
import RadialPatternBackground from '../../../common/profile/RadialPatternBackground';
import PaidMediaThumb from './PaidMediaThumb';

import styles from './StarsTransactionItem.module.scss';

type OwnProps = {
  transaction: ApiStarsTransaction;
  className?: string;
};

const GIFT_STICKER_SIZE = 36;
const AVATAR_SIZE = 42;

const StarsTransactionItem = ({ transaction, className }: OwnProps) => {
  const { openStarsTransactionModal } = getActions();
  const {
    date,
    amount,
    photo,
    peer: transactionPeer,
    extendedMedia,
    subscriptionPeriod,
  } = transaction;
  const lang = useLang();
  const oldLang = useOldLang();

  const peerId = transactionPeer.type === 'peer' ? transactionPeer.id : undefined;

  const peerSelector = useCallback((global: GlobalState) => {
    return peerId ? selectPeer(global, peerId) : undefined;
  }, [peerId]);
  const peer = useSelector(peerSelector);
  const starGift = transaction.starGift;
  const isUniqueGift = starGift?.type === 'starGiftUnique';
  const giftSticker = starGift && getStickerFromGift(starGift);

  const data = useMemo(() => {
    let title = getTransactionTitle(oldLang, lang, transaction);
    let description;
    let status: string | undefined;
    let avatarPeer: ApiPeer | CustomPeer | undefined;

    if (!shouldUseCustomPeer(transaction)) {
      description = peer && getPeerTitle(oldLang, peer);
      avatarPeer = peer || CUSTOM_PEER_PREMIUM;
    } else {
      const customPeer = buildStarsTransactionCustomPeer(transaction);
      title = customPeer.title || oldLang(customPeer.titleKey!);
      description = oldLang(customPeer.subtitleKey!);
      avatarPeer = customPeer;
    }

    if ((transaction.isGiftUpgrade || transaction.isDropOriginalDetails)
      && transaction.starGift?.type === 'starGiftUnique') {
      description = lang('GiftUnique', { title: transaction.starGift.title, number: transaction.starGift.number });
    }

    if (transaction.isGiftResale && transaction.starGift?.type === 'starGiftUnique') {
      description = lang('GiftUnique', { title: transaction.starGift.title, number: transaction.starGift.number });
    }

    if (transaction.isPostsSearch) {
      title = getTransactionTitle(oldLang, lang, transaction);
      description = undefined;
    }

    if (transaction.photo) {
      avatarPeer = undefined;
    }

    if (transaction.isRefund) {
      status = oldLang('StarsRefunded');
    }

    if (transaction.hasFailed) {
      status = oldLang('StarsFailed');
    }

    if (transaction.isPending) {
      status = oldLang('StarsPending');
    }

    return {
      title,
      description,
      avatarPeer,
      status,
    };
  }, [oldLang, lang, peer, transaction]);

  const previewContent = useMemo(() => {
    if (isUniqueGift) {
      const { backdrop } = getGiftAttributes(starGift)!;
      const backgroundColors = [backdrop!.centerColor, backdrop!.edgeColor];

      return (
        <>
          <RadialPatternBackground
            className={styles.uniqueGiftBackground}
            backgroundColors={backgroundColors}
          />
          <AnimatedIconFromSticker
            className={styles.giftSticker}
            sticker={giftSticker}
            size={GIFT_STICKER_SIZE}
            play={false}
          />
        </>
      );
    }

    if (giftSticker) {
      return (
        <AnimatedIconFromSticker
          className={styles.giftSticker}
          sticker={giftSticker}
          size={GIFT_STICKER_SIZE}
          play={false}
        />
      );
    }

    if (extendedMedia) {
      return <PaidMediaThumb media={extendedMedia} isTransactionPreview />;
    }

    return (
      <>
        <Avatar size={AVATAR_SIZE} webPhoto={photo} peer={data.avatarPeer} />
        {Boolean(subscriptionPeriod) && (
          <StarIcon className={styles.subscriptionStar} type="gold" size="small" />
        )}
      </>
    );
  }, [isUniqueGift, extendedMedia, photo, data.avatarPeer, subscriptionPeriod, starGift, giftSticker]);

  const handleClick = useLastCallback(() => {
    openStarsTransactionModal({ transaction });
  });

  const amountColorClass = isNegativeAmount(amount) ? styles.negative : styles.positive;

  return (
    <div className={buildClassName(styles.root, className)} onClick={handleClick}>
      <div className={styles.preview}>
        {previewContent}
      </div>
      <div className={styles.info}>
        <h3 className={styles.title}>{data.title}</h3>
        {data.description && (
          <p className={styles.description}>{renderText(data.description)}</p>
        )}
        <p className={styles.date}>
          {formatDateTimeToString(date * 1000, oldLang.code, true)}
          {data.status && ` — (${data.status})`}
        </p>
      </div>
      <span className={styles.stars}>
        <span
          className={buildClassName(styles.amount, amountColorClass)}
        >
          {formatStarsTransactionAmount(lang, amount)}
        </span>
        {NNBSP}
        {amount.currency === STARS_CURRENCY_CODE && <StarIcon type="gold" size="adaptive" />}
        {amount.currency === TON_CURRENCY_CODE && (
          <Icon name="toncoin" className={buildClassName('in-text-icon', amountColorClass)} />
        )}
      </span>
    </div>
  );
};

export default memo(StarsTransactionItem);
