import React from 'react';
import { screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { useAbacusAccountTaxInfoHistoryQuery } from 'src/apollo/queries/account-payee-tax-info-history';
import { getFullCountryName } from '../components/taxFormInfoCompleted/helpers';
import { TaxInfoHistory, CLASS_NAME } from '../tax-info-history';

jest.mock('src/apollo/queries/account-payee-tax-info-history', () => ({
    useAbacusAccountTaxInfoHistoryQuery: jest.fn(),
}));

jest.mock('../components/taxFormInfoCompleted/helpers', () => ({
    getFullCountryName: jest.fn(),
}));

const mockuseTaxInfoHistoryQuery =
    useAbacusAccountTaxInfoHistoryQuery as jest.Mock;

describe('<TaxInfoHistory />', () => {
    const accountId = 'test-account';

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

    it('renders a skeleton loader when loading', () => {
        mockuseTaxInfoHistoryQuery.mockReturnValue({ loading: true });

        renderInAppContext(<TaxInfoHistory accountId={accountId} />);

        expect(screen.getByTestId('SkeletonLoader')).toBeInTheDocument();
    });

    it('renders an error alert if query fails', () => {
        mockuseTaxInfoHistoryQuery.mockReturnValue({
            loading: false,
            error: new Error('Error!'),
        });

        renderInAppContext(<TaxInfoHistory accountId={accountId} />);

        expect(
            screen.getByText('Error loading Tax Information history.')
        ).toBeInTheDocument();
    });

    it('renders empty GridTable when there is no tax info history', () => {
        mockuseTaxInfoHistoryQuery.mockReturnValue({
            loading: false,
            error: undefined,
            data: {
                abacusAccount: {
                    accountTaxInfoHistory: [],
                },
            },
        });

        renderInAppContext(<TaxInfoHistory accountId={accountId} />);

        expect(screen.getByTestId(CLASS_NAME)).toBeInTheDocument();
        expect(screen.getByText('History')).toBeInTheDocument();
        expect(
            screen.queryAllByRole('Error loading Tax Information history.')
        ).toEqual([]);
    });

    it('renders GridTable with formatted tax info history', () => {
        mockuseTaxInfoHistoryQuery.mockReturnValue({
            loading: false,
            error: undefined,
            data: {
                abacusAccount: {
                    accountTaxInfoHistory: [
                        {
                            accountTaxInfoHistoryId: '1',
                            countryOfTaxResidence: 'US',
                            createdAt: '2023-01-01',
                            lastModified: '2023-12-31',
                        },
                    ],
                },
            },
        });

        (getFullCountryName as jest.Mock).mockReturnValue('United States');

        renderInAppContext(<TaxInfoHistory accountId={accountId} />);

        expect(screen.getByTestId(CLASS_NAME)).toBeInTheDocument();
        expect(screen.getByText('United States')).toBeInTheDocument();
        expect(screen.getByText('2023-01-01')).toBeInTheDocument();
        expect(screen.getByText('2023-12-31')).toBeInTheDocument();
    });

    it('deduplicates tax info history entries with same country, created, and modified', () => {
        mockuseTaxInfoHistoryQuery.mockReturnValue({
            loading: false,
            error: undefined,
            data: {
                abacusAccount: {
                    accountTaxInfoHistory: [
                        {
                            accountTaxInfoHistoryId: '1',
                            countryOfTaxResidence: 'USA',
                            createdAt: '2023-01-01',
                            lastModified: '2023-12-31',
                        },
                        {
                            accountTaxInfoHistoryId: '2',
                            countryOfTaxResidence: 'USA',
                            createdAt: '2023-01-01',
                            lastModified: '2023-12-31',
                        },
                        {
                            accountTaxInfoHistoryId: '3',
                            countryOfTaxResidence: 'CAN',
                            createdAt: '2024-01-01',
                            lastModified: '2024-12-31',
                        },
                        {
                            accountTaxInfoHistoryId: '4',
                            countryOfTaxResidence: 'USA',
                            createdAt: '2023-01-01',
                            lastModified: '2023-12-31',
                        },
                        {
                            accountTaxInfoHistoryId: '5',
                            countryOfTaxResidence: 'USA',
                            createdAt: '2023-01-01',
                            lastModified: '2023-12-31',
                        },
                        {
                            accountTaxInfoHistoryId: '6',
                            countryOfTaxResidence: 'CAN',
                            createdAt: '2024-01-01',
                            lastModified: '2024-12-31',
                        },
                        {
                            accountTaxInfoHistoryId: '7',
                            countryOfTaxResidence: 'CAN',
                            createdAt: '2024-01-01',
                            lastModified: '2024-12-31',
                        },
                    ],
                },
            },
        });

        (getFullCountryName as jest.Mock).mockImplementation(code => {
            if (code === 'USA') return 'United States';
            if (code === 'CAN') return 'Canada';
            return code;
        });

        renderInAppContext(<TaxInfoHistory accountId={accountId} />);

        // Check both unique countries are rendered
        expect(screen.getByText('United States')).toBeInTheDocument();
        expect(screen.getByText('2023-01-01')).toBeInTheDocument();
        expect(screen.getByText('2023-12-31')).toBeInTheDocument();

        expect(screen.getByText('Canada')).toBeInTheDocument();
        expect(screen.getByText('2024-01-01')).toBeInTheDocument();
        expect(screen.getByText('2024-12-31')).toBeInTheDocument();

        // Ensure United States appears only once despite duplicate data
        const usaRows = screen.getAllByText('United States');
        expect(usaRows.length).toBe(1);

        // Ensure Canada appears only once despite duplicate data
        const canRows = screen.getAllByText('Canada');
        expect(canRows.length).toBe(1);
    });
});
