import React from 'react';
import { fireEvent, screen, waitFor } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import * as accountingPeriodDetailResponse from 'src/__fixtures__/graphql/accounting-period-detail-response.json';
import * as salesFileAbacusEventMutations from 'src/apollo/mutations/sales-file-abacus-event';
import {
    EligibleSalesTable,
    type EligibleSalesTablePropTypes,
} from 'src/components/accounting-period/eligible-sales-table';

describe('<EligibleSales>', () => {
    const render = (props: EligibleSalesTablePropTypes) =>
        renderInAppContext(<EligibleSalesTable {...props} />);

    const {
        abacusAccountingPeriod: { salesFile },
    } = accountingPeriodDetailResponse;

    const defaultProps: EligibleSalesTablePropTypes = {
        sales: salesFile,
        isPeriodLocked: true,
        onStatusUpdate: jest.fn(),
        setError: jest.fn(),
    };

    describe('Eligible Sales table', () => {
        it('renders sales data', () => {
            render(defaultProps);
            const bodyText: any = [];
            document
                .querySelectorAll('div.GridTable-cell')
                .forEach((body: any) => bodyText.push(body.textContent));
            expect(bodyText).toEqual([
                'Troys Data',
                '$2,406.29',
                '44',
                'Complete',
                'Total Eligible Sales',
                '$2,406.29',
                '44',
                '',
            ]);
        });
    });

    describe('getStatusContent', () => {
        it('renders empty string when both states are init', () => {
            const salesFileData = {
                ...salesFile[0],
                actionStates: [
                    {
                        abacusStateId: '4',
                        actionName: 'get_eligible_sales',
                        actionStatus: 'init',
                    },
                    {
                        abacusStateId: '5',
                        actionName: 'approve_sales',
                        actionStatus: 'init',
                    },
                ],
                abacusEvents: [],
            };
            const customProps = {
                ...defaultProps,
                isPeriodLocked: false,
                sales: [salesFileData],
            };
            render(customProps);

            const bodyText: any = [];
            document
                .querySelectorAll('div.GridTable-cell')
                .forEach((body: any) => bodyText.push(body.textContent));
            expect(bodyText).toEqual([
                'Troys Data',
                '$2,406.29',
                '44',
                '',
                'Total Eligible Sales',
                '$2,406.29',
                '44',
                '',
            ]);

            const approveLink = screen.queryByTestId('approveSalesFileBtn');
            expect(approveLink).toBeFalsy();
        });

        it('renders Processing when get_eligible_sales is running', () => {
            const salesFileData = {
                ...salesFile[0],
                actionStates: [
                    {
                        abacusStateId: '4',
                        actionName: 'get_eligible_sales',
                        actionStatus: 'running',
                    },
                    {
                        abacusStateId: '5',
                        actionName: 'approve_sales',
                        actionStatus: 'init',
                    },
                ],
                abacusEvents: [
                    {
                        eventName: 'get_eligible_sales',
                        targetId: 1,
                    },
                ],
            };
            const customProps = {
                ...defaultProps,
                isPeriodLocked: false,
                sales: [salesFileData],
            };
            render(customProps);

            const bodyText: any = [];
            document
                .querySelectorAll('div.GridTable-cell')
                .forEach((body: any) => bodyText.push(body.textContent));
            expect(bodyText).toEqual([
                'Troys Data',
                '$2,406.29',
                '44',
                'Processing',
                'Total Eligible Sales',
                '$2,406.29',
                '44',
                '',
            ]);

            const approveLink = screen.queryByTestId('approveSalesFileBtn');
            expect(approveLink).toBeFalsy();
        });

        it('renders error when get_eligible_sales is errored', () => {
            const salesFileData = {
                ...salesFile[0],
                actionStates: [
                    {
                        abacusStateId: '4',
                        actionName: 'get_eligible_sales',
                        actionStatus: 'error',
                    },
                    {
                        abacusStateId: '5',
                        actionName: 'approve_sales',
                        actionStatus: 'init',
                    },
                ],
                abacusEvents: [
                    {
                        eventName: 'get_eligible_sales',
                        targetId: 1,
                    },
                ],
            };
            const customProps = {
                ...defaultProps,
                isPeriodLocked: false,
                sales: [salesFileData],
            };

            render(customProps);
            const bodyText: any = [];
            document
                .querySelectorAll('div.GridTable-cell')
                .forEach((body: any) => bodyText.push(body.textContent));
            expect(bodyText).toEqual([
                'Troys Data',
                '$2,406.29',
                '44',
                'Error',
                'Total Eligible Sales',
                '$2,406.29',
                '44',
                '',
            ]);

            const approveLink = screen.queryByTestId('approveSalesFileBtn');
            expect(approveLink).toBeFalsy();
        });

        it('renders Processing when approve_sales is running', () => {
            const salesFileData = {
                ...salesFile[0],
                actionStates: [
                    {
                        abacusStateId: '4',
                        actionName: 'get_eligible_sales',
                        actionStatus: 'complete',
                    },
                    {
                        abacusStateId: '5',
                        actionName: 'approve_sales',
                        actionStatus: 'running',
                    },
                ],
                abacusEvents: [
                    {
                        eventName: 'get_eligible_sales',
                        targetId: 1,
                    },
                    {
                        eventName: 'approve_sales',
                        targetId: 2,
                    },
                ],
            };
            const customProps = {
                ...defaultProps,
                isPeriodLocked: false,
                sales: [salesFileData],
            };
            render(customProps);

            const bodyText: any = [];
            document
                .querySelectorAll('div.GridTable-cell')
                .forEach((body: any) => bodyText.push(body.textContent));
            expect(bodyText).toEqual([
                'Troys Data',
                '$2,406.29',
                '44',
                'Processing',
                'Total Eligible Sales',
                '$2,406.29',
                '44',
                '',
            ]);

            const approveLink = screen.queryByTestId('approveSalesFileBtn');
            expect(approveLink).toBeFalsy();
        });

        it('renders error when approve_sales is errored', () => {
            const salesFileData = {
                ...salesFile[0],
                actionStates: [
                    {
                        abacusStateId: '4',
                        actionName: 'get_eligible_sales',
                        actionStatus: 'complete',
                    },
                    {
                        abacusStateId: '5',
                        actionName: 'approve_sales',
                        actionStatus: 'error',
                    },
                ],
                abacusEvents: [
                    {
                        eventName: 'get_eligible_sales',
                        targetId: 1,
                    },
                    {
                        eventName: 'approve_sales',
                        targetId: 2,
                    },
                ],
            };
            const customProps = {
                ...defaultProps,
                isPeriodLocked: false,
                sales: [salesFileData],
            };
            render(customProps);
            const bodyText: any = [];
            document
                .querySelectorAll('div.GridTable-cell')
                .forEach((body: any) => bodyText.push(body.textContent));
            expect(bodyText).toEqual([
                'Troys Data',
                '$2,406.29',
                '44',
                'Error',
                'Total Eligible Sales',
                '$2,406.29',
                '44',
                '',
            ]);

            const approveLink = screen.queryByTestId('approveSalesFileBtn');
            expect(approveLink).toBeFalsy();
        });
    });

    describe('Approve sales file button', () => {
        const createSalesFileAbacusEvent = jest.fn().mockResolvedValue({});

        const salesFileData = {
            ...salesFile[0],
            actionStates: [
                {
                    abacusStateId: '4',
                    actionName: 'get_eligible_sales',
                    actionStatus: 'complete',
                },
                {
                    abacusStateId: '5',
                    actionName: 'approve_sales',
                    actionStatus: 'init',
                },
            ],
            abacusEvents: [],
        };

        const customProps = {
            ...defaultProps,
            isPeriodLocked: true,
            sales: [salesFileData],
        };

        beforeEach(() => {
            jest.spyOn(
                salesFileAbacusEventMutations,
                'useCreateSalesFileAbacusEvent'
            ).mockReturnValue(createSalesFileAbacusEvent);
            render(customProps);
        });

        afterEach(jest.restoreAllMocks);

        it('renders enabled approve button when approve sales is init', () => {
            const approveLink = screen.getByTestId('approveSalesFileBtn');
            expect(approveLink).toBeDefined();
            expect(approveLink.disabled).toBeFalsy();
        });

        it('renders confirmation popup on approve click', () => {
            const approveLink = screen.getByTestId('approveSalesFileBtn');
            fireEvent.click(approveLink);
            expect(screen.getByTestId('ApproveSalesFilePopUp')).toBeDefined();
        });

        it('calls create event mutation on approve confirm', async () => {
            const approveLink = screen.getByTestId('approveSalesFileBtn');
            fireEvent.click(approveLink);
            const approveBtn = screen.getByText('Yes, Approve the Sales File');
            expect(approveBtn).toBeTruthy();

            fireEvent.click(approveBtn);

            await waitFor(() => {
                expect(createSalesFileAbacusEvent).toHaveBeenCalledWith({
                    variables: {
                        eventName: 'approve_sales',
                        targetId: parseInt(salesFileData.salesFileId, 10),
                    },
                });
            });
        });
    });
});
