import React from 'react';
import { screen } from '@testing-library/react';
import { createIdentity, renderInAppContext } from '@theorchard/suite-testing';
import { BrowserRouter as Router } from 'react-router-dom';
import * as customPaymentsQuery from 'src/apollo/queries/custom-payment';
import { NO_PAYMENTS_RESULTS, USER_FEATURES } from 'src/constants';
import CustomPayments from '../custom-payments';
import type { GetCustomPaymentsQuery } from 'src/apollo/queries/custom-payment/__generated__/get-custom-payments';
import type { Identity } from '@theorchard/suite-frontend';

describe('<CustomPayments />', () => {
    const responseData: GetCustomPaymentsQuery = {
        customPayments: {
            totalCount: 2,
            items: [
                {
                    worksheetPaymentCustomId: '1',
                    paymentName: 'CUSTOM PAYMENT DESCRIPTION 1',
                    amount: 22,
                    amountAfterWithholdingAndVat: 23,
                    currencyCode: 'USD',
                    createdAt: '2024-02-20T00:00:00Z',
                    contract: {
                        contractName: 'Test Contract Name 1',
                        contractId: 'TC1',
                    },
                    account: {
                        accountName: 'Test Account Name 1',
                        accountId: 'TA1',
                    },
                    abacusEvents: [
                        {
                            abacusEventId: '1',
                            eventDate: '2024-02-21T00:00:00Z',
                            eventName: 'send_payments',
                            targetId: 1,
                            targetType: 'worksheet_payment_custom',
                        },
                    ],
                    actionStates: [
                        {
                            actionName: 'send_payments',
                            actionStatus: 'error',
                            message: 'test error',
                            parentTableId: '1',
                            parentTableName: 'worksheet_payment_custom',
                            lastModified: '2024-02-21T00:00:00Z',
                            lastModifiedByIdentity: { name: 'test name' },
                        },
                    ],
                },
                {
                    worksheetPaymentCustomId: '2',
                    paymentName: 'CUSTOM PAYMENT DESCRIPTION 2',
                    amount: 244,
                    amountAfterWithholdingAndVat: 245,
                    currencyCode: 'USD',
                    createdAt: '2024-01-11T00:00:00Z',
                    contract: {
                        contractName: 'Test Contract Name 2',
                        contractId: 'TC2',
                    },
                    account: {
                        accountName: 'Test Account Name 2',
                        accountId: 'TA2',
                    },
                    abacusEvents: [],
                    actionStates: [],
                },
            ],
        },
    };

    beforeEach(() => {
        jest.spyOn(customPaymentsQuery, 'useCustomPayments').mockReturnValue({
            data: responseData,
            loading: false,
            error: undefined,
        } as any);
    });

    afterEach(jest.restoreAllMocks);

    const renderComponent = (identity?: Identity) =>
        renderInAppContext(
            <Router>
                <CustomPayments />
            </Router>,
            { identity }
        );

    it('displays no results found', () => {
        jest.spyOn(customPaymentsQuery, 'useCustomPayments').mockReturnValue({
            data: { customPayments: { items: [], totalCount: 0 } },
            loading: false,
            error: undefined,
        } as any);

        renderComponent();
        expect(screen.getByText(NO_PAYMENTS_RESULTS)).toBeDefined();
    });

    it('renders pagination', () => {
        renderComponent();
        const totalCount = responseData.customPayments.totalCount;
        expect(
            screen.getAllByText(`1 - ${totalCount} of ${totalCount}`)
        ).toBeTruthy();
    });

    it('renders a table with headers', () => {
        renderComponent();
        expect(screen.getAllByText('Status')).toBeDefined();
        expect(screen.getAllByText('Date Sent')).toBeDefined();
        expect(screen.getAllByText('Payment Name')).toBeDefined();
        expect(screen.getAllByText('Contract (Name & ID)')).toBeDefined();
        expect(screen.getAllByText('Account (Name & ID)')).toBeDefined();
        expect(screen.getAllByText('Pre-Tax Amount')).toBeDefined();
        expect(screen.getAllByText('Post-Tax Amount')).toBeDefined();
        expect(screen.getAllByText('Status Details')).toBeDefined();
        expect(screen.getAllByText('Date Created')).toBeDefined();
    });

    it('displays data in the table', () => {
        renderComponent();

        expect(
            screen.getByText('CUSTOM PAYMENT DESCRIPTION 1')
        ).toHaveAttribute('href', '/payment/custom/1');
        expect(screen.getByText('Test Contract Name 1 (TC1)')).toBeTruthy();
        expect(screen.getByText('Test Account Name 1 (TA1)')).toBeTruthy();
        expect(screen.getByText('$22.00')).toBeTruthy();
        expect(screen.getByText('$23.00')).toBeTruthy();
        expect(screen.getByText('2024-02-20')).toBeTruthy();
        expect(screen.getByText('2024-02-21')).toBeTruthy();
        expect(screen.getByText('test error')).toBeTruthy();

        expect(
            screen.getByText('CUSTOM PAYMENT DESCRIPTION 2')
        ).toHaveAttribute('href', '/payment/custom/2');
        expect(screen.getByText('Test Contract Name 2 (TC2)')).toBeTruthy();
        expect(screen.getByText('Test Account Name 2 (TA2)')).toBeTruthy();
        expect(screen.getByText('$244.00')).toBeTruthy();
        expect(screen.getByText('$245.00')).toBeTruthy();
        expect(screen.getByText('2024-01-11')).toBeTruthy();
    });

    describe('TAP_PAYMENT_TABLES_REVAMP feature flag', () => {
        describe('when flag is on', () => {
            const mockIdentity = createIdentity({
                features: {
                    [USER_FEATURES.TAP_PAYMENT_TABLES_REVAMP]: true,
                },
            });

            it('renders table inside Section wrapper and applies zebra variant when flag is on', () => {
                const { container } = renderComponent(mockIdentity);

                expect(container.querySelector('.SuiteSection')).not.toBeNull();
                expect(
                    container.querySelector('.CustomPaymentsTable')
                ).not.toBeNull();
                expect(
                    container.querySelector('.zebra-variant')
                ).not.toBeNull();
            });
        });

        describe('when flag is off', () => {
            it('renders table without Section wrapper and does not apply zebra variant when flag is off', () => {
                const { container } = renderComponent();

                expect(container.querySelector('.SuiteSection')).toBeNull();
                expect(
                    container.querySelector('.CustomPaymentsTable')
                ).not.toBeNull();
                expect(container.querySelector('.zebra-variant')).toBeNull();
            });
        });
    });
});
