import React, { useEffect, useState } from 'react';
import { Button, Modal } from '@theorchard/suite-components';
import { isEmpty } from 'lodash-es';
import { ActionStatusIcon } from 'src/components/shared/action-status-icon';
import { ACCOUNTING_RUN_STATUSES as RUN_STATUSES } from 'src/constants';
import { ABACUS_ACTION_STATUSES } from '@theorchard/accounting-apps-shared';
import type {
    AbacusFormattedAccountingRun,
    AbacusAccountingPeriodActionState,
} from 'src/types/accounting-period';

export interface MarkRunsAsCompleteActionPropTypes {
    actionStatus: (typeof ABACUS_ACTION_STATUSES)[keyof typeof ABACUS_ACTION_STATUSES];
    abacusStateId: string;
    accountingRuns: AbacusFormattedAccountingRun;
    updatePeriodState: (
        // eslint-disable-next-line no-unused-vars
        newState: Partial<AbacusAccountingPeriodActionState>[]
    ) => Promise<void>;
    // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-explicit-any
    setError: (error: any) => void;
}

export const MarkRunsAsCompleteAction: React.FC<
    MarkRunsAsCompleteActionPropTypes
> = ({
    actionStatus,
    abacusStateId,
    accountingRuns,
    updatePeriodState,
    setError,
}) => {
    const [approvedCount, setApprovedCount] = useState<number>(0);
    const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
    const [skippedCount, setSkippedCount] = useState<number>(0);
    const [totalCompletedRuns, setTotalCompletedRuns] = useState<number>(0);
    const [isSaveButtonDisabled, setIsSaveButtonDisabled] =
        useState<boolean>(false);

    const canMarkRunsAsComplete =
        totalCompletedRuns === Object.values(accountingRuns).length &&
        actionStatus !== ABACUS_ACTION_STATUSES.COMPLETE;

    const filterRunsByStatus = (
        status: (typeof ABACUS_ACTION_STATUSES)[keyof typeof ABACUS_ACTION_STATUSES]
    ) =>
        (
            Object.values(
                accountingRuns
            ) as AbacusFormattedAccountingRun[string][]
        ).filter(
            (run: AbacusFormattedAccountingRun[string]) => run.status === status
        );

    useEffect(() => {
        const hasAccountingRuns = !isEmpty(Object.values(accountingRuns));

        if (hasAccountingRuns) {
            const { APPROVED, INVALID, SKIPPED } = RUN_STATUSES;

            setApprovedCount(filterRunsByStatus(APPROVED).length);
            setSkippedCount(filterRunsByStatus(SKIPPED).length);

            setTotalCompletedRuns(
                (
                    Object.values(
                        accountingRuns
                    ) as AbacusFormattedAccountingRun[string][]
                ).filter(
                    run =>
                        run.status === INVALID ||
                        run.status === SKIPPED ||
                        run.status === APPROVED
                ).length
            );
        }
    }, [accountingRuns]);

    const modalContent = (
        <div data-testid="MarkRunAsCompletePopupTestid">
            <p>Are you sure you want to mark run as complete?</p>

            <p>
                Marking a run complete finalizes all activity up until this
                point. You will not <br /> be able to go back and change the run
                any further.
            </p>

            {skippedCount > 0 && (
                <ul data-testid="skippedMessages">
                    <li>
                        You approved runs for <b> {approvedCount} </b>
                        out of <b> {totalCompletedRuns} </b> run controllers.
                    </li>
                    <li>
                        You skipped <b> {skippedCount} </b> run controller(s)
                        and will not generate accounting <br /> for their
                        associated contracts and payees this period.
                    </li>
                </ul>
            )}

            <p className="warning">You cannot undo this action!</p>
        </div>
    );

    const updateActionState = async () => {
        setError('');
        setIsSaveButtonDisabled(true);
        updatePeriodState([
            {
                abacusStateId,
                actionStatus: ABACUS_ACTION_STATUSES.COMPLETE,
            },
        ])
            .then(() => {
                setIsSaveButtonDisabled(false);
                setIsModalOpen(false);
            })
            .catch(() => {
                setIsSaveButtonDisabled(false);
                setIsModalOpen(false);
            });
    };

    return (
        <div className="MarkRunsAsComplete">
            <Button
                data-testid="markRunsAsCompleteBtn"
                disabled={!canMarkRunsAsComplete}
                id="markRunsAsCompleteBtn"
                onClick={() => setIsModalOpen(true)}
                variant="quartenary"
            >
                {actionStatus !== ABACUS_ACTION_STATUSES.INIT && (
                    <ActionStatusIcon actionStatus={actionStatus} />
                )}
                <span>
                    {actionStatus === ABACUS_ACTION_STATUSES.COMPLETE
                        ? 'Runs Complete'
                        : 'Mark Runs As Complete'}
                </span>
            </Button>
            <Modal
                isOpen={isModalOpen}
                onRequestClose={() =>
                    isSaveButtonDisabled ? false : setIsModalOpen(false)
                }
                title="WARNING"
                confirmButtonProps={{
                    disabled: isSaveButtonDisabled,
                    variant: 'primary',
                    loading: isSaveButtonDisabled,
                    title: 'Yes, Mark Runs As Complete',
                    onClick: () => updateActionState(),
                }}
            >
                {modalContent}
            </Modal>
        </div>
    );
};
