import React, {
    useEffect,
    useState,
    type Dispatch,
    type SetStateAction,
} from 'react';
import { Button, GridTable, Modal } from '@theorchard/suite-components';
import { ABACUS_ACTION_STATUSES } from '@theorchard/accounting-apps-shared';
import { isEmpty, sumBy } from 'lodash-es';
import { useCreateSalesFileAbacusEvent } from 'src/apollo/mutations/sales-file-abacus-event';
import { EligibleSalesTableColumns } from 'src/components/accounting-period/eligible-sales-table-columns';
import CurrencyFormat from 'src/components/shared/currency-format';
import { formatNumber } from 'src/utils/number-helper';
import { ABACUS_ACTION_STATUSES_MAP } from 'src/apollo/type-constants/accounting-period';
import type {
    AbacusEvent,
    AbacusSalesFiles,
    AbacusSalesFile,
    AbacusSalesFileTableRow,
} from 'src/types/accounting-period';

export interface EligibleSalesTablePropTypes {
    sales: AbacusSalesFiles;
    isPeriodLocked: boolean;
    onStatusUpdate: () => void;
    setError: Dispatch<SetStateAction<string>>;
}

export const EligibleSalesTable: React.FC<EligibleSalesTablePropTypes> = ({
    sales,
    isPeriodLocked,
    onStatusUpdate,
    setError,
}) => {
    const formatRevenue = (amount: number | null) => {
        if (amount)
            return <CurrencyFormat amount={amount} currencyCode="USD" />;
        return '';
    };
    const [rows, setRows] = useState<Array<AbacusSalesFileTableRow>>([]);
    const [approveSalesFileId, setApproveSalesFileId] = useState<string>('');
    const [salesFileActionStates, setSalesFileActionStates] = useState([]);
    const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
    const [isSaveButtonDisabled, setIsSaveButtonDisabled] =
        useState<boolean>(false);
    const [disableSalesApproval, setDisableSalesApproval] = useState<
        Record<string, boolean>
    >({});

    const createSalesFileAbacusEvent = useCreateSalesFileAbacusEvent();

    const toggleModal = (salesFileId: string) => () => {
        setApproveSalesFileId(salesFileId);
        setIsModalOpen(!isModalOpen);
    };

    const confirmApproveHandler = () => {
        setIsSaveButtonDisabled(true);
        const variables = {
            eventName: 'approve_sales',
            targetId: parseInt(approveSalesFileId ?? '', 10),
        };
        setDisableSalesApproval({
            ...disableSalesApproval,
            [approveSalesFileId]: true,
        });
        createSalesFileAbacusEvent({ variables })
            .then(() => {
                onStatusUpdate();
                setIsSaveButtonDisabled(false);
                toggleModal('')();
            })
            .catch(err => {
                delete disableSalesApproval[approveSalesFileId];
                setDisableSalesApproval({ ...disableSalesApproval });
                setError(err);
            });
    };

    const createApproveLink = (
        salesFileId: string,
        isApproveSalesEventExist: boolean
    ) => (
        <span className="approveBtnColumn">
            <Button
                data-testid="approveSalesFileBtn"
                onClick={toggleModal(salesFileId)}
                disabled={
                    disableSalesApproval[salesFileId] ||
                    isApproveSalesEventExist
                }
                size="sm"
                type="button"
                variant="quartenary"
            >
                Approve
            </Button>
        </span>
    );

    const getStatusContent = (sale: AbacusSalesFile | null) => {
        if (isEmpty(sale?.actionStates)) return '';

        if (sale?.actionStates?.length !== 2) return '';

        const getEligibleSalesActionStatus =
            sale?.actionStates[0]?.actionStatus;
        const approveSalesActionStatus = sale?.actionStates[1]?.actionStatus;
        const isApproveSalesEventExist =
            sale?.abacusEvents?.some(
                (abacusEvent: AbacusEvent) =>
                    abacusEvent?.eventName === 'approve_sales'
            ) || false;

        if (
            getEligibleSalesActionStatus === ABACUS_ACTION_STATUSES.COMPLETE &&
            approveSalesActionStatus === ABACUS_ACTION_STATUSES.INIT &&
            isPeriodLocked
        )
            return createApproveLink(
                sale.salesFileId,
                isApproveSalesEventExist
            );

        if (
            getEligibleSalesActionStatus === ABACUS_ACTION_STATUSES.COMPLETE &&
            approveSalesActionStatus
        )
            return ABACUS_ACTION_STATUSES_MAP[approveSalesActionStatus];

        if (getEligibleSalesActionStatus)
            return ABACUS_ACTION_STATUSES_MAP[getEligibleSalesActionStatus];

        return '';
    };

    useEffect(() => {
        const saleRows: Array<AbacusSalesFileTableRow> = [];

        sales
            ?.filter((sale): sale is AbacusSalesFile => sale !== null)
            .forEach((sale: AbacusSalesFile) => {
                const row: AbacusSalesFileTableRow = {
                    fileName: sale.fileName,
                    amountUsd: formatRevenue(sale.amountUsd),
                    rowCount: sale.rowCount && formatNumber(sale.rowCount),
                    status: getStatusContent(sale),
                };
                saleRows.push(row);
                const firstState = sale.actionStates?.[0];

                if (firstState?.abacusStateId)
                    setSalesFileActionStates({
                        ...salesFileActionStates,
                        [firstState?.abacusStateId]: firstState?.actionStatus,
                    });
            });
        const totalSales = sumBy(sales, 'amountUsd');

        const totalSalesFilesRows = sumBy(sales, 'rowCount');

        const totalRow = {
            fileName: 'Total Eligible Sales',
            amountUsd: formatRevenue(totalSales),
            rowCount: formatNumber(totalSalesFilesRows),
            status: '',
        };

        setRows([...saleRows, totalRow]);
    }, [sales, disableSalesApproval]);

    const modalContent = (
        <div
            className="ApproveSalesFile-modal"
            data-testid="ApproveSalesFilePopUp"
        >
            <p>Are you sure you want to approve the sales file?</p>
            <p className="warning">You cannot undo this action!</p>
        </div>
    );

    return (
        <>
            <GridTable
                className="EligibleSalesTable"
                columnDefs={EligibleSalesTableColumns()}
                data={rows}
                hideColumnSeparators
                highlightSelectedRows={true}
                rowKey="fileName"
                shadowed
                testId="EligibleSalesTableTestId"
            />
            <Modal
                isOpen={isModalOpen}
                onRequestClose={
                    isSaveButtonDisabled ? () => false : toggleModal('')
                }
                title="WARNING"
                confirmButtonProps={{
                    disabled: isSaveButtonDisabled,
                    variant: 'primary',
                    loading: isSaveButtonDisabled,
                    title: 'Yes, Approve the Sales File',
                    onClick: () => confirmApproveHandler(),
                }}
            >
                {modalContent}
            </Modal>
        </>
    );
};
