import React, { useState, useEffect } from 'react';
import {
    ABACUS_ACTION_STATUSES,
    ABACUS_ACTIONS,
} from '@theorchard/accounting-apps-shared';
import { Status } from '@theorchard/suite-components';
import { isEmpty, uniq, get, some } from 'lodash-es';
import { PaymentType } from 'src/apollo/definitions/globalTypes';
import { ELIGIBILITY_STATUSES, ELIGIBILITY_STATUS_NAMES } from 'src/constants';
import type { ActionState } from '../../types/action-state';

export type EligibilityStatuses = keyof typeof ELIGIBILITY_STATUSES;

export interface PaymentEligibilityStatusProps {
    accountDetails: {
        eligibilityStatus: EligibilityStatuses | null;
        accountPayee: {
            referencePaymentType: {
                paymentService: string;
            };
            actionStates: ActionState[];
        };
        accountPaymentTerm: {
            paymentType: string;
        };
    };
}

export default function PaymentEligibilityStatus({
    accountDetails,
}: PaymentEligibilityStatusProps) {
    const [eligibilityStatuses, setEligibilityStatuses] = useState<
        EligibilityStatuses[]
    >([]);

    const getPaymentType = () => {
        const paymentService = get(
            accountDetails,
            'accountPayee.referencePaymentType.paymentService'
        );

        return paymentService?.toUpperCase();
    };

    const isActionStateIneligible = (state: ActionState) => {
        switch (state.actionName) {
            case ABACUS_ACTIONS.PAYMENT_ELIGIBILITY:
                return state.actionStatus !== ABACUS_ACTION_STATUSES.APPROVED;
            case ABACUS_ACTIONS.TAX_ELIGIBILITY:
                return state.actionStatus !== ABACUS_ACTION_STATUSES.COMPLETE;
            case ABACUS_ACTIONS.BANKING_DETAILS_REVIEW:
                return (
                    getPaymentType() === PaymentType.PAYONEER_WHITELABEL &&
                    state.actionStatus !== ABACUS_ACTION_STATUSES.APPROVED
                );
            default:
                return true;
        }
    };

    useEffect(() => {
        if (!isEmpty(accountDetails)) {
            const statusesList = [];
            if (
                accountDetails.eligibilityStatus ===
                ELIGIBILITY_STATUSES.ON_HOLD
            )
                statusesList.push(ELIGIBILITY_STATUSES.ON_HOLD);
            const actionStatuses = get(
                accountDetails,
                'accountPayee.actionStates',
                []
            );
            if (
                isEmpty(actionStatuses) ||
                some(actionStatuses, isActionStateIneligible)
            )
                statusesList.push(ELIGIBILITY_STATUSES.INELIGIBLE);
            if (
                getPaymentType() === PaymentType.PAYONEER_WHITELABEL &&
                !actionStatuses.find(
                    item =>
                        item.actionName ===
                        ABACUS_ACTIONS.BANKING_DETAILS_REVIEW
                )
            )
                statusesList.push(ELIGIBILITY_STATUSES.INELIGIBLE);
            if (isEmpty(statusesList))
                statusesList.push(ELIGIBILITY_STATUSES.ACTIVE);
            setEligibilityStatuses(uniq(statusesList) as EligibilityStatuses[]);
        }
    }, [accountDetails]);

    const eligibilityStatusContext = (
        eligibilityStatus: EligibilityStatuses
    ) => {
        switch (eligibilityStatus) {
            case ELIGIBILITY_STATUSES.ACTIVE:
                return 'success';
            case ELIGIBILITY_STATUSES.ON_HOLD:
                return 'warning';
            case ELIGIBILITY_STATUSES.INELIGIBLE:
                return 'error';
            default:
                return 'neutral';
        }
    };

    const eligibilityStatusContent = (
        eligibilityStatus: EligibilityStatuses
    ) => {
        switch (eligibilityStatus) {
            case ELIGIBILITY_STATUSES.ACTIVE:
                return (
                    <span data-testid="eligibilityStatusActive">
                        {ELIGIBILITY_STATUS_NAMES.ACTIVE}
                    </span>
                );
            case ELIGIBILITY_STATUSES.ON_HOLD:
                return (
                    <span data-testid="eligibilityStatusOnHold">
                        {ELIGIBILITY_STATUS_NAMES.ON_HOLD}
                    </span>
                );
            case ELIGIBILITY_STATUSES.INELIGIBLE:
                return (
                    <span data-testid="eligibilityStatusIneligible">
                        {ELIGIBILITY_STATUS_NAMES.INELIGIBLE}
                    </span>
                );
            default:
                return (
                    <span data-testid="eligibilityStatusUnknown">
                        {`Unknown status (${eligibilityStatus})`}
                    </span>
                );
        }
    };

    const displayEligibilityStatuses = () =>
        !isEmpty(eligibilityStatuses) &&
        eligibilityStatuses.map(eligibilityStatus => (
            <span
                className="PaymentEligibilityStatus"
                data-testid={`paymentEligibilityStatus-${eligibilityStatus}`}
                key={`paymentEligibilityStatus-${eligibilityStatus}`}
            >
                <Status
                    variant={eligibilityStatusContext(eligibilityStatus)}
                    filled
                    text={''}
                >
                    {eligibilityStatusContent(eligibilityStatus)}
                </Status>
            </span>
        ));

    return (
        <span
            className="PaymentEligibilityStatusList"
            data-testid="paymentEligibilityStatuses"
        >
            {displayEligibilityStatuses()}
        </span>
    );
}
