import React, { useMemo } from 'react';
import accounting from 'accounting';
import {
    Canvas,
    BlobProvider,
    Document,
    Page,
    StyleSheet,
    Text,
    View,
    Font,
} from '@react-pdf/renderer';
import { Identity } from '@orchard/frontend-workstation';
import { formatMessage } from '@orchard/frontend-localization';
import { DownloadGlyph, LoadingButton } from '@orchard/frontend-react-components';
import { map, includes } from 'lodash';
import {
    RoyaltiesPageCollaborator_collaborator
} from 'src/pages/collaborator-royalties-page/queries/__definitions__/RoyaltiesPageCollaborator';
import { renderTransactionType } from '../transaction-type/transaction-type';
import {
    TW_TRANSFER_STATUS_COLORS,
    TW_TRANSFER_STATUS_MESSAGES,
    TW_TRANSFER_PENDING_STATUSES,
    NUMBER_FORMATS,
    RUBIK_SRC_URLS,
    COLORS
} from '../../../constants';
import messages from '../i18n';

type Props = {
    collaborator: RoyaltiesPageCollaborator_collaborator;
    identity: Identity;
};

export const Report: React.FC<Props> = ({
    collaborator,
    identity
}) => {
    Font.register({
        family: 'Rubik',
        fonts: [
            { src: RUBIK_SRC_URLS.NORMAL, fontStyle: 'normal', fontWeight: 'normal' },
            { src: RUBIK_SRC_URLS.MEDIUM, fontStyle: 'normal', fontWeight: 'medium' },
            { src: RUBIK_SRC_URLS.SEMIBOLD, fontStyle: 'normal', fontWeight: 'semibold' },
            { src: RUBIK_SRC_URLS.BOLD, fontStyle: 'normal', fontWeight: 'bold' }
        ]
    });

    const styles = StyleSheet.create({
        page: {
            fontFamily: 'Rubik',
            display: 'flex',
            marginBottom: 56,
            marginRight: 14,
            marginTop: 56
        },
        row: {
            color: COLORS.GRAY_800,
            borderBottomColor: COLORS.GRAY_200,
            borderBottomStyle: 'solid',
            borderBottomWidth: 1,
            display: 'flex',
            flexDirection: 'row',
            justifyContent: 'space-between',
            width: 500
        },
        headerRow: {
            borderBottomColor: COLORS.GRAY_300,
            color: COLORS.GRAY_500,
            fontWeight: 'medium'
        },
        rowItem: {
            display: 'flex',
            flexDirection: 'row',
            fontSize: 8,
            padding: 10,
            textOverflow: 'ellipsis',
            width: '16%',
        },
        amountItem: {
            textAlign: 'right'
        },
        amountValue: {
            color: COLORS.GRAY_800,
            fontWeight: 'medium',
            textAlign: 'right'
        },
        statusItem: {
            textAlign: 'center'
        },
        descriptionItem: {
            width: '27%'
        },
        typeItem: {
            width: '27%'
        },
        dateItem: {
            width: '12%'
        },
        sectionHeading: {
            color: COLORS.GRAY_800,
            fontSize: 10,
        },
        transactionSection: {
            alignItems: 'center',
            display: 'flex',
        },
        titleSection: {
            display: 'flex',
            flexDirection: 'row',
            marginBottom: 5,
            marginLeft: 50,
            marginRight: 50,
        },
        titleRow: {
            display: 'flex'
        },
        collaboratorSection: {
            display: 'flex',
            flexDirection: 'row',
            marginBottom: 28,
            marginLeft: 50,
            marginRight: 50,
        },
        company: {
            fontSize: 10,
            fontWeight: 'medium',
            textAlign: 'right'
        },
        address: {
            fontSize: 7,
            textAlign: 'right'
        },
        rightPanel: {
            marginLeft: 'auto',
            width: '33%'
        },
        transactionHeading: {
            marginBottom: 5,
            marginLeft: 50
        },
        balanceHeading: {
            color: COLORS.GRAY_500,
            fontSize: 7,
            fontWeight: 'medium',
            marginTop: 8
        },
        balanceSection: {
            display: 'flex',
            flexDirection: 'column',
        },
        balanceAmount: {
            color: COLORS.GRAY_800,
            fontWeight: 'medium',
            fontSize: 10,
            marginTop: 4
        },
        date: {
            color: COLORS.GRAY_800,
            fontSize: 6
        },
        pageNumber: {
            bottom: 60,
            color: COLORS.GRAY_800,
            fontSize: 6,
            position: 'absolute',
            right: 15
        },
        heading: {
            fontSize: 11,
            marginBottom: 30
        },
        statusIndicatorItem: {
            marginLeft: 'auto',
            paddingLeft: 0,
            paddingRight: 15,
            width: '1%'
        },
        statusIndicator: {
            marginLeft: 0,
            height: 15,
            width: 15
        },
        transactionMessage: {
            textAlign: 'center'
        }
    });

    const todaysDate = Date.now();
    const currentTime = Intl.DateTimeFormat(
        'en-US',
        { hour: 'numeric', minute: 'numeric', timeZoneName: 'short', hour12: false }
    ).format(todaysDate);
    const currentDate = Intl.DateTimeFormat(
        'en-US',
        { year: 'numeric', day: 'numeric', month: 'numeric' }
    ).format(todaysDate);

    const formatAmount = (amount: number) => identity.vendor.numberFormat !== NUMBER_FORMATS.US
        ? accounting.formatNumber(amount, 2, '.', ',')
        : accounting.formatNumber(amount, 2, ',', '.');

    const { transactions } = collaborator;

    return (
        <Document>
            <Page style={ styles.page }>
                <View style={ styles.titleSection }>
                    <View>
                        <Text style={ styles.date }>
                            { `${currentTime} • ${currentDate}` }
                        </Text>
                        <Text style={ styles.heading }>
                            { formatMessage(messages.collaboratorTransactionHistory) }
                        </Text>
                    </View>
                    <View style={ styles.rightPanel }>
                        <Text style={ styles.company }>
                            { identity.vendor.company }
                        </Text>
                    </View>
                </View>
                <View style={ styles.collaboratorSection }>
                    <View style={ styles.balanceSection }>
                        <Text style={ styles.sectionHeading }>
                            { collaborator.name }
                        </Text>
                        <Text style={ [styles.balanceHeading] }>
                            { formatMessage(messages.balance) }
                        </Text>
                        <Text style={ styles.balanceAmount }>
                            { `${formatAmount(collaborator.balance)} ${collaborator.currency}` }
                        </Text>
                    </View>
                </View>
                <View style={ styles.transactionHeading }>
                    <Text style={ styles.sectionHeading }>
                        { formatMessage(messages.transactions) }
                    </Text>
                </View>
                <View style={ styles.transactionSection }>
                    <View style={ [styles.row, styles.headerRow] }>
                        <Text style={ [styles.rowItem, styles.dateItem] }>
                            { formatMessage(messages.date) }
                        </Text>
                        <Text style={ [styles.rowItem, styles.typeItem] }>
                            { formatMessage(messages.type) }
                        </Text>
                        <Text style={ [styles.rowItem, styles.descriptionItem] }>
                            { formatMessage(messages.description) }
                        </Text>
                        <Text style={ [styles.rowItem, styles.statusItem] } />
                        <Text style={ [styles.rowItem, styles.statusIndicatorItem] } />
                        <Text style={ [styles.rowItem, styles.amountItem] }>
                            { formatMessage(messages.amount) }
                        </Text>
                    </View>
                    { map(transactions, (transaction) => {
                        const transactionStatus = transaction.transferwiseTransactionStatus
                            ? transaction.transferwiseTransactionStatus.toLowerCase() : null;

                        const transactionColor = transactionStatus && includes(TW_TRANSFER_PENDING_STATUSES, transactionStatus)
                            ? TW_TRANSFER_STATUS_COLORS[transactionStatus as keyof typeof TW_TRANSFER_STATUS_COLORS] : null;

                        const transactionMessage = transactionStatus && includes(TW_TRANSFER_PENDING_STATUSES, transactionStatus)
                            ? TW_TRANSFER_STATUS_MESSAGES[transactionStatus as keyof typeof TW_TRANSFER_STATUS_MESSAGES] : null;

                        return (
                            <View key={ transaction.id } style={ styles.row } wrap={ false }>
                                <Text style={ [styles.rowItem, styles.dateItem] }>
                                    { transaction.date }
                                </Text>
                                <Text style={ [styles.rowItem, styles.typeItem] }>
                                    { renderTransactionType(transaction) }
                                </Text>
                                <Text style={ [styles.rowItem, styles.descriptionItem] }>
                                    { transaction.description }
                                </Text>
                                <View style={ styles.rowItem }>
                                    { transactionMessage && (
                                        <Text style={ styles.transactionMessage }>
                                            { formatMessage(transactionMessage || '') }
                                        </Text>
                                    ) }
                                </View>
                                <View style={ [styles.rowItem, styles.statusIndicatorItem] }>
                                    { transactionColor && (
                                        <Canvas
                                            style={ styles.statusIndicator }
                                            paint={ painter => (painter.rect(4, 4, 4, 4).fill(transactionColor)) }
                                        />
                                    ) }
                                </View>
                                <Text style={ [styles.rowItem, styles.amountValue] }>
                                    { `${formatAmount(transaction.chargeableAmount)} ${transaction.currency}` }
                                </Text>
                            </View>
                        );
                    }) }
                </View>
                <Text
                    style={ styles.pageNumber }
                    render={ ({ pageNumber, totalPages }) => (
                        `${pageNumber} of ${totalPages}`
                    ) }
                    fixed
                />
            </Page>
        </Document>
    );
};

const RoyaltyPdfDownload: React.FC<Props> = ({ collaborator, identity }) =>
    useMemo(
        () => {
            if (!collaborator?.transactions || !collaborator?.transactions.length)
                return null;
            return (
                <div className="CollaboratorRoyaltiesPage-RoyaltyPdfDownload">
                    <BlobProvider document={ <Report collaborator={ collaborator } identity={ identity } /> }>
                        { ({ loading, url }) => (
                            <LoadingButton
                                loading={ loading }
                                href={ url }
                                download={ `${collaborator.name}_balance_report.pdf` }
                            >
                                <DownloadGlyph />
                                { formatMessage(messages.exportPdf) }
                            </LoadingButton>
                        ) }
                    </BlobProvider>
                </div>
            );
        }, [collaborator, identity]
    );

export default RoyaltyPdfDownload;
