import React from 'react';
import { screen, waitFor } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import {
    openSelect,
    selectOption,
    selectStatusOption,
} from 'lib/test-utils/select';
import { ABACUS_ACTION_STATUSES } from '@theorchard/accounting-apps-shared';
import { PayeeManagement } from '../payee-management';
import {
    useGetPayeesList,
    useGetPayeeCollaboratorContact,
    useGetPayeeDetailsById,
} from 'src/apollo/queries/payees';
import { useBaseAccountsSearchQuery } from 'src/apollo/queries/account';

jest.mock('src/apollo/queries/payees', () => ({
    useGetPayeesList: jest.fn(),
    useGetPayeeCollaboratorContact: jest.fn(),
    useGetPayeeDetailsById: jest.fn(),
}));

jest.mock('src/apollo/mutations/payee', () => ({
    useReleaseAbacusPayee: jest.fn(() => ({
        releaseAbacusPayee: jest.fn(),
    })),
}));

jest.mock('src/apollo/mutations/delete-payee-kyc-notification', () => ({
    useDeletePayeeKycNotificationMutation: jest.fn(() => ({
        deletePayeeKycNotification: jest.fn(),
    })),
}));

jest.mock('src/apollo/queries/account', () => ({
    useBaseAccountsSearchQuery: jest.fn(),
}));

jest.mock('src/apollo/mutations/abacus-state', () => ({
    useUpdateAbacusState: jest.fn(() => ({
        updateAbacusState: jest.fn(),
    })),
}));

describe('<PayeeManagement />', () => {
    const fetchMore = jest.fn();
    const refetch = jest.fn();

    const payeeFixture: any = {
        payeeId: 'p-1',
        payeeName: 'Test Payee',
        payoneerProgramId: '99',
        payoneerClientReferenceId: 'ext-abc',
        payeeKycNotification: { fileUploadLink: 'https://example.test/kyc' },
        bankDetails: null,
        actionStates: [
            {
                abacusStateId: 's-1',
                actionStatus: ABACUS_ACTION_STATUSES.RUNNING,
                message: 'Needs review',
            },
        ],
        payeeCollaborator: {
            collaborator: {
                id: 'c-1',
                label: {
                    __typename: 'Vendor',
                    name: 'Test Vendor',
                    id: { vendorId: 'v-1' },
                },
            },
        },
    };

    beforeEach(() => {
        fetchMore.mockClear();
        refetch.mockClear();

        (useGetPayeeCollaboratorContact as jest.Mock).mockReturnValue({
            contact: undefined,
            collaborator: {
                id: 'c-1',
                name: 'Collaborator Name',
                currentBalance: null,
            },
            loading: false,
        });

        (useGetPayeeDetailsById as jest.Mock).mockReturnValue({
            payee: undefined,
            bankDetails: null,
            loading: false,
        });

        (useGetPayeesList as jest.Mock).mockReturnValue({
            data: {
                abacusPayees: {
                    items: [payeeFixture],
                    totalCount: 1,
                },
            },
            loading: false,
            fetchMore,
            refetch,
        });

        (useBaseAccountsSearchQuery as jest.Mock).mockReturnValue(
            jest.fn().mockResolvedValue({
                abacusAccounts: {
                    items: [{ accountId: 'v-1', accountName: 'Test Vendor' }],
                },
            })
        );

        jest.spyOn(window, 'open').mockImplementation(() => null);
    });

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

    it('renders with data and filters', async () => {
        renderInAppContext(<PayeeManagement />);

        expect(screen.getByTestId('BankEligibilityFilter')).toBeInTheDocument();
        expect(screen.getByTestId('AccountFilter')).toBeInTheDocument();

        // Basic table content from fixture
        expect(await screen.findByText('Test Payee')).toBeInTheDocument();
        expect(screen.getByText('p-1')).toBeInTheDocument();
        expect(screen.getByText('Test Vendor')).toBeInTheDocument();
        expect(screen.getByText('v-1')).toBeInTheDocument();
        expect(screen.getByText('ext-abc')).toBeInTheDocument();
    });

    it('calls useGetPayeesList with correct defaults', async () => {
        renderInAppContext(<PayeeManagement />);

        expect(useGetPayeesList).toHaveBeenCalledWith({
            limit: 100,
            offset: 0,
            requiresReview: false,
            searchTerm: '',
            abacusStates: [],
            accountIds: [],
        });
    });

    it('filters by bank eligibility', async () => {
        renderInAppContext(<PayeeManagement />);

        await openSelect('BankEligibilityFilter');
        selectStatusOption({ label: 'In review' });

        await waitFor(() => {
            expect(useGetPayeesList).toHaveBeenCalledWith(
                expect.objectContaining({
                    abacusStates: [
                        { actionStatus: ABACUS_ACTION_STATUSES.RUNNING },
                    ],
                })
            );
        });
    });

    it('filters by account name', async () => {
        renderInAppContext(<PayeeManagement />);

        await openSelect('AccountFilter');
        await screen.findByText('Test Vendor', {
            selector: '.SuiteListView .SuiteListView-option-label',
        });
        selectOption({ label: 'Test Vendor' });

        await waitFor(() => {
            expect(useGetPayeesList).toHaveBeenCalledWith(
                expect.objectContaining({
                    accountIds: ['v-1'],
                })
            );
        });
    });
});
