import React, { useContext, useEffect, useRef, useState } from 'react';
import { useApolloClient } from '@apollo/client';
import {
    Alert,
    Button,
    Card,
    FullscreenModal,
    HelpTooltip,
    Tag,
    useToast,
} from '@theorchard/suite-components';
import { Page } from '@theorchard/suite-frontend';
import { GlyphIcon } from '@theorchard/suite-icons';
import { isEmpty } from 'lodash-es';
import { ABACUS_ACTION_STATUSES } from '@theorchard/accounting-apps-shared';

import { useCreateAbacusEvent } from 'src/apollo/mutations/abacus-event';
import { useSoftDeleteStatementPeriodAdjustmentFile } from 'src/apollo/mutations/statement-period-adjustment-file';
import { useGetAbacusState } from 'src/apollo/queries/abacus-state';
import { AdjustmentsContext } from 'src/contexts/adjustments-context';
import { STATEMENT_PERIOD_ADJUSTMENT_UPLOAD_ACTIONS } from 'src/constants';

import type { GetAbacusStateQuery } from 'src/apollo/queries/__generated__/abacus-state';

type AbacusState = GetAbacusStateQuery['abacusState'][0];

export const AdjustmentsUploadSuccessScreen = () => {
    const { adjustmentFile, handleModalClose } = useContext(AdjustmentsContext);
    const client = useApolloClient();

    const { data, startPolling, stopPolling } = useGetAbacusState(
        adjustmentFile!.statementPeriodAdjustmentFileId!.toString(),
        'statement_period_adjustment_file'
    );

    const [importState, setImportState] = useState<
        AbacusState | undefined | null
    >(undefined);

    const [isImporting, setIsImporting] = useState<boolean>(false);
    const isDeleted = useRef<boolean>(false);

    const softDeleteStatementPeriodAdjustmentFile =
        useSoftDeleteStatementPeriodAdjustmentFile();

    const toast = useToast();
    const createAbacusEvent = useCreateAbacusEvent();

    useEffect(() => {
        if (!isEmpty(importState)) {
            if (
                importState!.actionStatus === ABACUS_ACTION_STATUSES.INIT ||
                importState!.actionStatus === ABACUS_ACTION_STATUSES.RUNNING
            ) {
                startPolling(2000);
            }

            if (importState!.actionStatus === ABACUS_ACTION_STATUSES.ERROR) {
                stopPolling();
                handleModalClose();

                toast(
                    <div>
                        Batch {adjustmentFile!.statementPeriodAdjustmentFileId}{' '}
                        has failed to import.
                    </div>,
                    { variant: 'danger' }
                );
            }

            if (importState!.actionStatus === ABACUS_ACTION_STATUSES.COMPLETE) {
                stopPolling();
                handleModalClose();

                toast(
                    <div>
                        You have successfully imported your adjustments/expenses
                        as Batch&nbsp;
                        {adjustmentFile!.statementPeriodAdjustmentFileId}
                        .&nbsp;
                        <a
                            data-testid="toastBatchPageURL"
                            href={`/adjustments/${adjustmentFile!.statementPeriodAdjustmentFileId!.toString()}`}
                        >
                            View it here.
                        </a>
                    </div>
                );

                const refreshBatchList = () => {
                    void client.refetchQueries({
                        include: ['GetStatementPeriodAdjustmentFilesList'],
                    });
                };

                refreshBatchList();
            }
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [importState]);

    useEffect(() => {
        if (data && data.abacusState) {
            const abacusStates = data.abacusState;

            if (!isEmpty(abacusStates)) {
                setImportState(
                    abacusStates!.find(
                        action =>
                            action!.actionName ===
                            STATEMENT_PERIOD_ADJUSTMENT_UPLOAD_ACTIONS.IMPORT_FILE
                    )
                );
            }
        }
    }, [data, isImporting]);

    const cancelImportStatementPeriodAdjustmentFile = async (
        statementPeriodAdjustmentFileId: number
    ) => {
        await softDeleteStatementPeriodAdjustmentFile({
            variables: {
                statementPeriodAdjustmentFileId:
                    statementPeriodAdjustmentFileId.toString(),
            },
        });

        isDeleted.current = true;
        handleModalClose();
    };

    const onImportClick = async () => {
        setIsImporting(true);

        await createAbacusEvent({
            variables: {
                eventName: 'adjustment_file_worksheet_import',
                targetId: adjustmentFile!.statementPeriodAdjustmentFileId!,
                targetType: 'statement_period_adjustment_file',
            },
        });
    };

    return (
        <>
            <FullscreenModal.Title title="Upload Successful" />
            <FullscreenModal.Body>
                <Alert
                    variant="success"
                    testId="AdjustmentsSuccessfulUploadAlert"
                    text={
                        <span>
                            All data has passed validation successfully. You can
                            now proceed with the import.
                        </span>
                    }
                />
                <Page.Grid>
                    <Page.Col sm={12} md={6} lg={6}>
                        <Card testId="AdjustmentsDataUploadedSummary" suite>
                            <Card.Header>
                                <Card.Title>
                                    <b>Data Uploaded</b>
                                </Card.Title>
                            </Card.Header>
                            <Card.Body>
                                <div>
                                    Total Amount (MUL):&nbsp;
                                    {adjustmentFile!.totalFileAmountMulticurrency!.toString()}
                                </div>
                                <div style={{ marginTop: '5px' }}>
                                    Valid Rows:&nbsp;&nbsp;
                                    <Tag
                                        className="AdjustmentsImportModal-Tag-Valid"
                                        text={adjustmentFile!.validRowCount!.toString()}
                                    />
                                </div>
                            </Card.Body>
                        </Card>
                    </Page.Col>
                    <Page.Col sm={12} md={6} lg={6}>
                        <Card testId="AdjustmentsDataToBeImportedSummary" suite>
                            <Card.Header>
                                <Card.Title>
                                    <b>Data To Be Imported</b>
                                    <HelpTooltip
                                        className="AdjustmentsImportModal-ImportTooltip"
                                        id="AdjustmentUploadSuccessImportToolTip"
                                        tooltipPlacement="top"
                                        testId="AdjustmentUploadSuccessImportToolTip"
                                        message="Small variations may occur between the Total Amount uploaded and the
                                        Total Amount to be imported due to rounding."
                                    />
                                </Card.Title>
                            </Card.Header>
                            <Card.Body>
                                <div>
                                    Total Amount (MUL):&nbsp;
                                    {adjustmentFile!.totalRoundedAmountMulticurrency!.toString()}
                                </div>
                                <div style={{ marginTop: '5px' }}>
                                    Valid Rows:&nbsp;&nbsp;
                                    <Tag
                                        className="AdjustmentsImportModal-Tag-Valid"
                                        text={adjustmentFile!.validRowCount!.toString()}
                                    />
                                </div>
                            </Card.Body>
                        </Card>
                    </Page.Col>
                </Page.Grid>
                <div>
                    <Button
                        className="AdjustmentsImportModal-ImportButton"
                        variant="primary"
                        disabled={isImporting}
                        onClick={() => {
                            void onImportClick();
                        }}
                    >
                        {isImporting ? (
                            <>
                                <GlyphIcon name="inProgress" size={16} />
                                &nbsp;IMPORTING DATA
                            </>
                        ) : (
                            <>IMPORT DATA</>
                        )}
                    </Button>
                    <Button
                        className="AdjustmentsImportModal-CancelButton"
                        variant="secondary"
                        disabled={isImporting}
                        onClick={() => {
                            void cancelImportStatementPeriodAdjustmentFile(
                                adjustmentFile!.statementPeriodAdjustmentFileId!
                            );
                        }}
                    >
                        CANCEL IMPORT
                    </Button>
                </div>
            </FullscreenModal.Body>
        </>
    );
};

export default AdjustmentsUploadSuccessScreen;
