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 worksheetPaymentContractAdvancesResponse from 'src/__fixtures__/graphql/worksheet-payment-contract-advances-response.json';
import * as worksheetPaymentContractAdvancesQuery from 'src/apollo/queries/payment-group-payment';
import { NO_PAYMENTS_RESULTS, USER_FEATURES } from 'src/constants';
import AdvancePayments from '../advance-payments';
import type { WorksheetPaymentContractAdvancesQuery } from 'src/apollo/queries/payment-group-payment/__generated__/worksheet-payment-contract-advances';
import type { Identity } from '@theorchard/suite-frontend';

describe('<PaymentsList />', () => {
    beforeEach(() => {
        jest.spyOn(
            worksheetPaymentContractAdvancesQuery,
            'useWorksheetPaymentContractAdvances'
        ).mockReturnValue({
            data: worksheetPaymentContractAdvancesResponse as WorksheetPaymentContractAdvancesQuery,
            error: undefined,
            loading: false,
        });
    });

    afterEach(jest.restoreAllMocks);

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

    it('displays no results found', () => {
        jest.spyOn(
            worksheetPaymentContractAdvancesQuery,
            'useWorksheetPaymentContractAdvances'
        ).mockReturnValue({
            data: {
                worksheetPaymentContractAdvances: { items: [], totalCount: 0 },
            },
            error: undefined,
            loading: false,
        });
        renderComponent();

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

    it('renders pagination', () => {
        renderComponent();

        const totalCount =
            worksheetPaymentContractAdvancesResponse
                .worksheetPaymentContractAdvances.totalCount;

        expect(
            screen.getAllByText(`1 - ${totalCount} of ${totalCount}`)
        ).toBeTruthy();
    });

    it('renders a table with headers', () => {
        const { getAllByText } = renderComponent();

        expect(getAllByText('Status')).toBeDefined();
        expect(getAllByText('Status Details')).toBeDefined();
        expect(getAllByText('Payment Name')).toBeDefined();
        expect(getAllByText('Payment Type')).toBeDefined();
        expect(getAllByText('Contract Name')).toBeDefined();
        expect(getAllByText('Account Name')).toBeDefined();
        expect(getAllByText('Date created')).toBeDefined();
        expect(getAllByText('Amount')).toBeDefined();
    });

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

        expect(screen.getAllByText('Not paid')).toBeTruthy();
        expect(screen.getByText('PAYMENT DESCRIPTION 1')).toBeTruthy();
        expect(screen.getByText('PAYMENT DESCRIPTION 1')).toHaveAttribute(
            'href',
            '/payment/advance/1'
        );
        expect(screen.getByText('advance')).toBeTruthy();
        expect(screen.getByText('Test Contract Name 1')).toBeTruthy();
        expect(screen.getByText('Test Account Name 1')).toBeTruthy();
        expect(screen.getByText('2024-02-20')).toBeTruthy();
        expect(screen.getByText('£22.00')).toBeTruthy();

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

    it('displays status and error message', () => {
        renderComponent();

        expect(screen.getByText('Not paid')).toBeTruthy();
        expect(screen.getByText('Pending')).toBeTruthy();
        expect(screen.getByText('Failed')).toBeTruthy();
        expect(screen.getByText('Cancelled')).toBeTruthy();
        expect(screen.getByText('Paid')).toBeTruthy();

        expect(screen.getByText('Init message')).toBeTruthy();
        expect(screen.getByText('Running message')).toBeTruthy();
        expect(screen.getByText('Error message')).toBeTruthy();
        expect(screen.getByText('Rejected message')).toBeTruthy();
        expect(screen.getByText('Complete message')).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('.AdvancePaymentsTable')
                ).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('.AdvancePaymentsTable')
                ).not.toBeNull();
                expect(container.querySelector('.zebra-variant')).toBeNull();
            });
        });
    });
});
