import React, { useEffect, useState } from 'react';
import { Button } from '@theorchard/suite-components';
import { useCreateAbacusEvent } from 'src/apollo/mutations/abacus-event';
import { ACCOUNTING_PERIOD_CLOSE_EVENT } from 'src/apollo/type-constants/accounting-period';
import { ActionStatusIcon } from 'src/components/shared/action-status-icon';
import { PopupModal } from 'src/components/shared/popup-modal';
import type { AbacusAccountingPeriodActionState } from 'src/types/accounting-period';
import { ABACUS_ACTION_STATUSES } from '@theorchard/accounting-apps-shared';

export interface ClosePeriodModalPropTypes {
    /* eslint-disable no-unused-vars */
    accountingPeriodId: number;
    actionStatus: string;
    closeState: AbacusAccountingPeriodActionState;
    isButtonDisabled: boolean;
    updatePeriodState: (
        newStates: Partial<AbacusAccountingPeriodActionState>[]
    ) => void;
    setError: (error: string) => void;
    /* eslint-enable no-unused-vars */
}

const closeStates = [
    ABACUS_ACTION_STATUSES.RUNNING,
    ABACUS_ACTION_STATUSES.COMPLETE,
    ABACUS_ACTION_STATUSES.ERROR,
];

export const ClosePeriodModal: React.FC<ClosePeriodModalPropTypes> = ({
    accountingPeriodId,
    actionStatus,
    closeState,
    isButtonDisabled,
    updatePeriodState,
    setError,
}) => {
    const [isModalOpen, setIsModalOpen] = useState(false);
    const [isSaveButtonDisabled, setIsSaveButtonDisabled] = useState(false);
    const [isCloseButtonTriggered, setIsCloseButtonTriggered] =
        useState<boolean>(closeStates.includes(closeState.actionStatus));

    const createAbacusEvent = useCreateAbacusEvent();

    const modalContent = (
        <div
            className="ClosePeriod-modal"
            data-testid="close-period-modal-content"
        >
            <p>Are you sure you want to close the accounting period?</p>
            <p>
                Closing an accounting period advances any unallocated sales to
                the next accounting period. <br /> You will not be able to take
                any further action once the period is closed.
            </p>
            <p className="warning">You cannot undo this action!</p>
        </div>
    );

    const handleSave = async () => {
        setError('');
        setIsSaveButtonDisabled(true);
        setIsCloseButtonTriggered(true);
        try {
            updatePeriodState([
                {
                    ...closeState,
                    actionStatus: ABACUS_ACTION_STATUSES.RUNNING,
                },
            ]);
            await createAbacusEvent({
                variables: {
                    eventName: ACCOUNTING_PERIOD_CLOSE_EVENT.EVENT_NAME,
                    targetType: ACCOUNTING_PERIOD_CLOSE_EVENT.TARGET_TYPE,
                    targetId: accountingPeriodId,
                },
            });
        } catch (err) {
            if (err instanceof Error) {
                setError(err.message);
            }
            setIsCloseButtonTriggered(false);
            setIsSaveButtonDisabled(false);
            setIsModalOpen(false);
            window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
        }
    };

    useEffect(() => {
        if (closeState && closeState.actionStatus) {
            const { actionStatus } = closeState;
            setIsCloseButtonTriggered(closeStates.includes(actionStatus));
        }
    }, [closeState]);

    return (
        <div className="ClosePeriod">
            <Button
                id="closePeriodBtn"
                data-testid="closePeriodBtn"
                disabled={isButtonDisabled || isCloseButtonTriggered}
                onClick={() => setIsModalOpen(true)}
                variant="quartenary"
            >
                {closeStates.includes(closeState.actionStatus) && (
                    <ActionStatusIcon
                        actionStatus={actionStatus}
                        data-testid="action-status-icon"
                    />
                )}
                Close Period
            </Button>

            {isModalOpen && (
                <PopupModal
                    closeHandler={() => setIsModalOpen(false)}
                    headerLabel="WARNING"
                    isOpen={isModalOpen}
                    isSaveButtonDisabled={isSaveButtonDisabled}
                    modalContent={modalContent}
                    saveHandler={handleSave}
                    saveButtonText="Yes, Close This Period"
                />
            )}
        </div>
    );
};
