import React from 'react';
import { screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import * as statementPeriodQueries from 'src/apollo/queries/statement-periods';
import CollaboratorPayments from '../collaborators';
import type { GetStatementPeriodsQuery } from 'src/apollo/queries/statement-periods/__generated__/statement-periods';
import { ApolloError } from '@apollo/client';

jest.mock('@theorchard/suite-components', () => ({
    ...jest.requireActual('@theorchard/suite-components'),
    useToast: jest.fn(),
}));

describe('<CollaboratorPayments>', () => {
    const mockStatementPeriodsData: GetStatementPeriodsQuery = {
        abacusStatementPeriods: {
            recentPeriods: [
                {
                    actionStates: null,
                    statementPeriodId: '322',
                    statementPeriodName: 'October 2025',
                    statementPeriodStatus: 'current',
                    closedDate: null,
                    closedBy: null,
                    __typename: 'AbacusStatementPeriod',
                },
                {
                    actionStates: null,
                    statementPeriodId: '321',
                    statementPeriodName: 'September 2025',
                    statementPeriodStatus: 'closed',
                    closedDate: '2025-10-31',
                    closedBy: null,
                    __typename: 'AbacusStatementPeriod',
                },
            ],
            upcomingPeriods: [],
            __typename: 'AbacusStatementPeriods',
        },
    };

    beforeEach(() => {
        jest.clearAllMocks();

        jest.spyOn(
            statementPeriodQueries,
            'useStatementPeriods'
        ).mockReturnValue({
            data: mockStatementPeriodsData,
            fetchMore: jest.fn(),
            loading: false,
            error: undefined,
        });
    });

    afterEach(() => {
        jest.clearAllMocks();
    });

    const render = () => renderInAppContext(<CollaboratorPayments />);

    it('renders page title', () => {
        render();
        expect(screen.getByText('Collaborator Payments')).toBeDefined();
    });

    it('renders loader when data is loading', () => {
        jest.spyOn(
            statementPeriodQueries,
            'useStatementPeriods'
        ).mockReturnValue({
            data: undefined,
            fetchMore: jest.fn(),
            loading: true,
            error: undefined,
        });

        const { container } = render();
        expect(container.querySelector('.LoadingPageIndicator')).toBeDefined();
    });

    it('renders error message on error', () => {
        jest.spyOn(
            statementPeriodQueries,
            'useStatementPeriods'
        ).mockReturnValue({
            data: undefined,
            fetchMore: jest.fn(),
            error: new ApolloError({
                errorMessage: 'Failed to fetch data',
                graphQLErrors: [],
                clientErrors: [],
                networkError: null,
            }),
            loading: false,
        });

        render();
        expect(screen.getByText('Failed to fetch data')).toBeDefined();
    });

    it('render all table columns', () => {
        render();
        expect(screen.getByText('Status')).toBeDefined();
        expect(screen.getByText('Statement Period')).toBeDefined();
        expect(screen.getByText('Period ID')).toBeDefined();
        expect(screen.getByText('Statement Period Closed')).toBeDefined();
    });

    it('displays recent statement periods in the table', () => {
        render();
        const table = screen.getByTestId('collaboratorsPeriodsTable');

        expect(table).toContainElement(screen.getByText('October 2025'));
        expect(screen.queryByText('September 2025')).not.toBeInTheDocument();
    });

    it('navigates to current period detail on first statement click', () => {
        render();
        const firstStatementLink = screen.getByText(
            'October 2025'
        ) as HTMLAnchorElement;

        expect(firstStatementLink).toBeDefined();
        expect(firstStatementLink.href).toContain('/collaborator-payments/322');
    });
});
