import React from 'react';
import { fireEvent, screen, waitFor } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import ContributionItems from 'src/components/schedule-form/contribution-items';

describe('<ContributionItems>', () => {
    const render = (props: any) =>
        renderInAppContext(<ContributionItems {...props} />);

    const props = {
        filterValues: {
            assignedContributions: { limit: 100, offset: 0 },
            unassignedContributions: { limit: 100, offset: 0 },
        },
        setFilterValues: jest.fn(),
        itemList: [
            {
                label: '! (Take No) - Fibes, Oh Fibes!',
                value: 'd45a76bd-d868-4a3e-ba4d-75d4b2f203e1',
            },
            {
                label: '!franchesckarr! - Charli XCX',
                value: 'd9d53a58-d38c-40ca-aceb-613b0816a3f4',
            },
        ],
        forward: true,
        headerText: 'Unassigned Contributions',
        listType: 'unassignedContributions',
        message: 'Assigned Contributions',
        onClickMoveTo: jest.fn(),
        searchInputName: 'Contributions',
        searchPlaceholder: 'Search by Contribution Name or ID',
        itemMoveList: {
            unassignedContributions: ['d45a76bd-d868-4a3e-ba4d-75d4b2f203e1'],
        },
        setItemMoveList: jest.fn(),
        totalCount: 2,
        undoMessage: '',
        undoMovedList: {},
        undoHandler: jest.fn(),
        areContributionsLoading: {},
        setAreContributionsLoading: jest.fn(),
        filterCount: 2,
        setContainerRef: jest.fn(),
        setSearchFilterApplied: jest.fn(),
        contributionsOriginalCount: 2,
        setScrollApplied: jest.fn(),
        scrollApplied: {},
        setSelectAll: jest.fn(),
        setSelectedContainer: jest.fn(),
        isDisabled: false,
        isInitialPageLoading: false,
    };

    it('renders <ContributionItems>', () => {
        render(props);
        expect(screen.getByText('Unassigned Contributions')).toBeDefined();
    });

    it('renders a list', () => {
        render(props);

        const checkboxes = screen.getAllByTestId(
            'ItemList-unassignedContributions-Checkbox'
        );
        expect(
            screen.getByText('! (Take No) - Fibes, Oh Fibes!')
        ).toBeDefined();
        expect(
            screen.getByText('d45a76bd-d868-4a3e-ba4d-75d4b2f203e1')
        ).toBeDefined();
        expect(screen.getByText('!franchesckarr! - Charli XCX')).toBeDefined();
        expect(
            screen.getByText('d9d53a58-d38c-40ca-aceb-613b0816a3f4')
        ).toBeDefined();
        expect(checkboxes.length).toEqual(2);
    });

    it('renders search filter', () => {
        render(props);
        expect(
            screen.getByPlaceholderText('Search by Contribution Name or ID')
        ).toBeDefined();
    });

    it('searches on by name input change', async () => {
        render(props);
        const input = screen.getByTestId('searchFieldInput');
        fireEvent.change(input, { target: { value: '(Take No)' } });
        await waitFor(() => {
            expect(props.setSelectAll).toHaveBeenCalledWith(false);
            expect(props.setItemMoveList).toHaveBeenCalled();
            expect(props.setFilterValues).toHaveBeenCalledWith({
                assignedContributions: { limit: 100, offset: 0 },
                unassignedContributions: {
                    limit: 100,
                    offset: 0,
                    term: '(Take No)',
                },
            });
        });
    });

    it('searches by id on input change', async () => {
        render(props);
        const input = screen.getByTestId('searchFieldInput');
        fireEvent.change(input, {
            target: { value: 'd9d53a58-d38c-40ca-aceb-613b0816a3f4' },
        });
        await waitFor(() => {
            expect(props.setSelectAll).toHaveBeenCalledWith(false);
            expect(props.setItemMoveList).toHaveBeenCalled();
            expect(props.setFilterValues).toHaveBeenCalledWith({
                assignedContributions: { limit: 100, offset: 0 },
                unassignedContributions: {
                    limit: 100,
                    offset: 0,
                    term: 'd9d53a58-d38c-40ca-aceb-613b0816a3f4',
                },
            });
        });
    });

    it('renders move item button', () => {
        render(props);
        const text = screen.getByTestId('ItemList-MoveItemsButton-Text');
        expect(text.innerHTML).toEqual(
            '<span>Move Selected (1) to</span><br><span>Assigned Contributions</span>'
        );
    });

    it('shows moving from status', () => {
        const newProps = {
            ...props,
            movingFrom: true,
            movingTo: false,
            movingFromMessage: 'test moving from message',
            movingToMessage: '',
        };
        render(newProps);
        expect(screen.getByText(newProps.movingFromMessage)).toBeDefined();
        expect(screen.getByTestId('ItemList-MoveItemsButton')).toHaveClass(
            'ItemList-ButtonDisable'
        );
    });

    it('shows moving to status', () => {
        const newProps = {
            ...props,
            movingFrom: false,
            movingTo: true,
            movingFromMessage: '',
            movingToMessage: 'test moving to message',
        };
        render(newProps);
        expect(screen.getByText(newProps.movingToMessage)).toBeDefined();
        expect(screen.getByTestId('ItemList-MoveItemsButton')).toHaveClass(
            'ItemList-ButtonDisable'
        );
    });

    it('disables search on page load', () => {
        const newProps = {
            ...props,
            isInitialPageLoading: true,
        };
        render(newProps);
        const searchInput = screen.getByTestId('searchFieldInput');
        expect(searchInput).toHaveAttribute('disabled');
    });
});
