import GenericPaymentApproval from 'src/components/generic-payment-approval';
import React, { useMemo } from 'react';
import type { GetCustomPaymentQuery } from 'src/apollo/queries/custom-payment/__generated__/get-custom-payment';
import {
    getCompletedPaymentApprovalSteps,
    getPaymentApprovalAbacusEvents,
} from 'src/utils/payment-approval';
import {
    CUSTOM_PAYMENT_APPROVAL_STEPS,
    CUSTOM_PAYMENT_APPROVAL_STEPS_EVENTS,
} from 'src/constants';
import { flatten } from 'lodash-es';
import { AbacusUploadType } from 'src/apollo/definitions/globalTypes';
import GenericPaymentApprovalUploadAndConfirmStep from 'src/components/generic-payment-approval/components/steps/generic-payment-approval-upload-and-confirm-step';
import { useUpdateApprovalForCustomPayment } from 'src/apollo/mutations/custom-payment/update-approval-for-custom-payment';
import { useConfirmApprovalForCustomPayment } from 'src/apollo/mutations/custom-payment/confirm-approval-for-custom-payment';
import GenericPaymentApprovalConfirmFundsStep from 'src/components/generic-payment-approval/components/steps/generic-payment-approval-confirm-funds-step';
import { useConfirmFundsForCustomPayment } from 'src/apollo/mutations/custom-payment/confirm-funds-for-custom-payment';
import GenericPaymentApprovalSendPaymentStep from 'src/components/generic-payment-approval/components/steps/generic-payment-approval-send-payment-step';
import { useSendCustomPayment } from 'src/apollo/mutations/custom-payment/send-custom-payment';
import { useDeleteApprovalForCustomPayment } from 'src/apollo/mutations/custom-payment/delete-approval-for-custom-payment';
import { useCustomPaymentReportsAndEventsData } from 'src/apollo/queries/custom-payment';
import getCustomPaymentQuery from 'src/apollo/queries/custom-payment/get-custom-payment.gql';

interface CustomPaymentApprovalProps {
    paymentEntityId: string;
    isSidecarOpen: boolean;
    setIsSidecarOpen: (open: boolean) => void;
    paymentEntityDetails?: GetCustomPaymentQuery['customPayment'];
    onPaymentSent: () => void;
}

const CustomPaymentApproval: React.FC<CustomPaymentApprovalProps> = ({
    paymentEntityId,
    isSidecarOpen,
    setIsSidecarOpen,
    paymentEntityDetails,
    onPaymentSent,
}) => {
    const { updateApprovalForCustomPayment } =
        useUpdateApprovalForCustomPayment();
    const { confirmApprovalForCustomPayment } =
        useConfirmApprovalForCustomPayment();
    const { deleteApprovalForCustomPayment } =
        useDeleteApprovalForCustomPayment();
    const { confirmFundsForCustomPayment } = useConfirmFundsForCustomPayment();
    const { sendCustomPayment } = useSendCustomPayment();
    const actionStates = paymentEntityDetails?.actionStates;
    const abacusEvents = paymentEntityDetails?.abacusEvents || [];
    const { paymentApprovalEventsArray } = getPaymentApprovalAbacusEvents(
        abacusEvents,
        flatten(Object.values(CUSTOM_PAYMENT_APPROVAL_STEPS_EVENTS))
    );
    const completedSteps = getCompletedPaymentApprovalSteps(
        paymentApprovalEventsArray,
        actionStates,
        CUSTOM_PAYMENT_APPROVAL_STEPS_EVENTS,
        CUSTOM_PAYMENT_APPROVAL_STEPS
    );
    const stepsConfig = useMemo(
        () => [
            {
                id: CUSTOM_PAYMENT_APPROVAL_STEPS.UPLOAD_APPROVAL,
                title: 'Step 1 - Upload & Confirm Approval File',
                withDivider: true,
                hookProps: {
                    onAction: async () =>
                        await confirmApprovalForCustomPayment(
                            {
                                worksheetPaymentCustomId: paymentEntityId,
                            },
                            {
                                awaitRefetchQueries: true,
                                refetchQueries: [getCustomPaymentQuery],
                            }
                        ),
                    onDelete: async () =>
                        await deleteApprovalForCustomPayment(
                            {
                                worksheetPaymentCustomId: paymentEntityId,
                            },
                            {
                                awaitRefetchQueries: true,
                                refetchQueries: [getCustomPaymentQuery],
                            }
                        ),
                    onSuccessUpdateEntity: async ({
                        reportExportUrl,
                    }: {
                        reportExportUrl: string;
                    }) =>
                        await updateApprovalForCustomPayment({
                            reportExportUrl,
                            worksheetPaymentCustomId: paymentEntityId,
                        }),
                    useReportsAndEvents: useCustomPaymentReportsAndEventsData,
                    uploadType: AbacusUploadType.CUSTOM_PAYMENT_APPROVAL,
                    paymentEntityDetails,
                },
                Component: GenericPaymentApprovalUploadAndConfirmStep,
            },
            {
                id: CUSTOM_PAYMENT_APPROVAL_STEPS.CONFIRM_FUNDS,
                title: 'Step 2 - Confirm Funds',
                withDivider: true,
                hookProps: {
                    onAction: async () =>
                        await confirmFundsForCustomPayment(
                            {
                                worksheetPaymentCustomId: paymentEntityId,
                            },
                            {
                                awaitRefetchQueries: true,
                                refetchQueries: [getCustomPaymentQuery],
                            }
                        ),
                    paymentApprovalStepsEvents: flatten(
                        Object.values(CUSTOM_PAYMENT_APPROVAL_STEPS_EVENTS)
                    ),
                    paymentEntityDetails,
                },
                Component: GenericPaymentApprovalConfirmFundsStep,
            },
            {
                id: CUSTOM_PAYMENT_APPROVAL_STEPS.SEND_PAYMENTS,
                title: 'Step 3 - Send Payment to Payoneer',
                hookProps: {
                    onAction: async () => {
                        await sendCustomPayment({
                            worksheetPaymentCustomId: paymentEntityId,
                        });

                        onPaymentSent();
                    },
                    paymentEntityDetails,
                },
                Component: GenericPaymentApprovalSendPaymentStep,
            },
        ],
        [paymentEntityId, paymentEntityDetails]
    );

    return (
        <GenericPaymentApproval
            paymentEntityId={paymentEntityId}
            completedSteps={completedSteps}
            stepsConfig={stepsConfig}
            sidecarProps={{
                isOpen: isSidecarOpen,
                setIsOpen: setIsSidecarOpen,
            }}
        />
    );
};

export default CustomPaymentApproval;
