import React from 'react';
import { HelpTooltip, Label } from '@theorchard/suite-components';
import { isEmpty } from 'lodash-es';
import { useAccountFullDetail } from 'src/apollo/queries/account';
import {
    PAYMENT_ENTITY_CRITERIA,
    PAYMENT_SCHEDULES_CRITERIA,
    CURRENCY_CODE_CRITERIA,
    PAYMENT_SCHEDULE_MAP,
} from 'src/constants';
import { getCurrencyLabel } from 'src/utils/currency';
import type { AccountPaymentTerm } from 'src/types/abacus-account';
import type {
    PaymentGroupCriteria,
    PaymentGroupPaymentDetails,
} from 'src/types/payment-group';

interface TooltipProps {
    accountId: string | null;
    accountIds: (string | null)[] | null;
    paymentGroupDetails: PaymentGroupPaymentDetails;
}

const Tooltip = ({
    accountId = null,
    accountIds = null,
    paymentGroupDetails = {} as PaymentGroupPaymentDetails,
}: TooltipProps) => {
    let accountPaymentTerm: Partial<AccountPaymentTerm> = {};

    // Tooltip only renders for <= 1 account (see PaymentGroupTooltip gate),
    // so prefer the single account from accountIds, falling back to the
    // legacy accountId field for groups created before multi-account support.
    const _accountId = accountIds?.[0] ?? accountId;

    if (_accountId) {
        // @ts-expect-error: ignore type error, passing number into hook that takes string
        const { data } = useAccountFullDetail(parseInt(_accountId, 10));
        if (data)
            accountPaymentTerm = {
                ...(data.abacusAccount?.accountPaymentTerm ?? {}),
            };
    }

    const checkIsPaymentScheduleEmpty = (
        value: keyof typeof PAYMENT_SCHEDULE_MAP
    ) => (isEmpty(value) ? '-' : PAYMENT_SCHEDULE_MAP[value]);

    const formattedCurrencyCodes = (
        currencyCodesArr: (string | null)[] | null
    ) =>
        currencyCodesArr
            ?.map(currencyCode => [getCurrencyLabel(currencyCode)])
            .join(', ') ?? '';

    const formattedPaymentSchedules = (
        PaymentSchedulesArr: (keyof typeof PAYMENT_SCHEDULE_MAP | null)[] | null
    ) =>
        PaymentSchedulesArr?.map(paymentSchedule => [
            PAYMENT_SCHEDULE_MAP[paymentSchedule ?? ''],
        ]).join(', ') ?? '';

    const isReusable =
        !isEmpty(paymentGroupDetails) && paymentGroupDetails.isReusable;

    const renderGroupCriteria = (
        groupCriteriaType: keyof NonNullable<PaymentGroupCriteria>
    ) => {
        let groupCriteriaInfo = 'ALL';
        const { groupCriteria } = paymentGroupDetails;

        if (
            groupCriteriaType in (groupCriteria ?? {}) &&
            groupCriteria?.[groupCriteriaType]
        )
            if (groupCriteriaType === CURRENCY_CODE_CRITERIA)
                groupCriteriaInfo = formattedCurrencyCodes([
                    ...(groupCriteria.currencyCodes ?? []),
                ]);
            else if (groupCriteriaType === PAYMENT_ENTITY_CRITERIA)
                groupCriteriaInfo =
                    groupCriteria?.[PAYMENT_ENTITY_CRITERIA]?.[0]
                        .paymentEntityName ?? 'ALL';
            else if (groupCriteriaType === PAYMENT_SCHEDULES_CRITERIA)
                groupCriteriaInfo = formattedPaymentSchedules(
                    groupCriteria[PAYMENT_SCHEDULES_CRITERIA] ?? []
                );
        return groupCriteriaInfo;
    };

    const renderPaidBy = () =>
        isReusable
            ? renderGroupCriteria(PAYMENT_ENTITY_CRITERIA)
            : accountPaymentTerm.paymentEntity?.paymentEntityName;

    return (
        <HelpTooltip
            id="payment-group-popup"
            message={
                <div className="PaymentGroupDetails-help-popup">
                    <div>
                        <Label text="Payment Currency" />
                        {isReusable
                            ? renderGroupCriteria(CURRENCY_CODE_CRITERIA)
                            : getCurrencyLabel(accountPaymentTerm.currencyCode)}
                    </div>
                    <hr />
                    <div>
                        <Label text="Paid By" />
                        {renderPaidBy()}
                    </div>
                    <hr />
                    <div>
                        <Label text="Payment Schedule" />
                        {isReusable
                            ? renderGroupCriteria(PAYMENT_SCHEDULES_CRITERIA)
                            : checkIsPaymentScheduleEmpty(
                                  accountPaymentTerm.paymentSchedule ?? ''
                              )}
                    </div>
                </div>
            }
            overlayType="popover"
            rootClose
            trigger={['click']}
            tooltipPlacement="bottom"
        />
    );
};

export interface PaymentGroupTooltipProps {
    accountId: string | null;
    accountIds: (string | null)[] | null;
    paymentGroupDetails: PaymentGroupPaymentDetails;
}

export default function PaymentGroupTooltip({
    accountId = null,
    accountIds = null,
    paymentGroupDetails = {} as PaymentGroupPaymentDetails,
}: PaymentGroupTooltipProps) {
    const isMultipleAccounts = accountIds && accountIds.length > 1;
    const hasTooltip = !isMultipleAccounts;

    return (
        <div data-testid="paymentGroupTooltip">
            <span>Group: </span>
            {paymentGroupDetails.groupName}
            {hasTooltip && (
                <Tooltip
                    paymentGroupDetails={paymentGroupDetails}
                    accountId={accountId}
                    accountIds={accountIds}
                />
            )}
        </div>
    );
}
