import React from 'react';
import accounting from 'accounting';
import { find } from 'lodash';
import { NUMBER_FORMATS } from '../../constants';
import useIdentity from '../../utils/use-identity';


const CURRENCY_VARIANT_CODE = 'code';
const CURRENCY_VARIANT_SYMBOL = 'symbol';

type Variant = typeof CURRENCY_VARIANT_CODE | typeof CURRENCY_VARIANT_SYMBOL;

type Props = {
    amount?: number | null,
    code?: string | null,
    variant?: Variant,
    className? : string,
    amountClassName? : string,
    codeClassName?: string,
    fallback?: string,
    renderSpace?: boolean
};

const Currency: React.FC<Props> = (
    {
        amount,
        code,
        variant = CURRENCY_VARIANT_CODE,
        className,
        amountClassName,
        codeClassName,
        fallback = '-',
        renderSpace = false
    },
) => {
    const { numberFormat, language } = useIdentity();

    if (typeof amount !== 'number' || !code)
        return (
            <span className={ className }>
                <span className={ amountClassName }>{ fallback }</span>
            </span>
        );

    if (variant === CURRENCY_VARIANT_SYMBOL) {
        // Our number format system only supports 'us' or 'europe'
        // so using proper Intl formatting is not currently possible.
        // Instead, we use Intl to derive the currency symbol and explicitly format.
        const numberFormatParts = new Intl.NumberFormat(
            language,
            { style: 'currency', currency: code }
        ).formatToParts(amount);
        const symbol = find(numberFormatParts, ['type', 'currency']) || null;
        const formattedAmount = numberFormat !== NUMBER_FORMATS.US
            ? accounting.formatMoney(amount, symbol?.value, 2, '.', ',')
            : accounting.formatMoney(amount, symbol?.value, 2, ',', '.');
        return (
            <span className={ className }>
                { formattedAmount }
            </span>
        );
    }
    const formattedAmount = numberFormat !== NUMBER_FORMATS.US
        ? accounting.formatNumber(amount, 2, '.', ',')
        : accounting.formatNumber(amount, 2, ',', '.');

    return (
        <span className={ className }>
            <span className={ amountClassName }>
                { formattedAmount }
            </span>
            { renderSpace && ' ' }
            <span className={ codeClassName }>{ code }</span>
        </span>
    );
};

export default Currency;
