import * as React from "react";
import {
    render,
    renderIntoDocument,
    fireEvent,
    cleanup,
    Simulate,
    wait,
} from "react-testing-library";
import HierarchyList from "../components/HierarchyList";
import { generateCheckItems } from "./utils/hierarchyList";
import { elementsArray } from "./utils";

beforeEach(cleanup);

describe("Hierarchy List Component", () => {
    test("01 - it renders", () => {
        const items = generateCheckItems();
        const rowClicked = jest.fn();
        const { container } = render(
            <HierarchyList
                items={items}
                checkedItems={items}
                checkClicked={rowClicked}
            />
        );
        expect(container).not.toBeNull();
    });

    test("02 - check click call back called", () => {
        const items = generateCheckItems();
        const rowClicked = jest.fn();
        const { container } = render(
            <HierarchyList
                items={items}
                checkedItems={items}
                checkClicked={rowClicked}
            />
        );
        const input = elementsArray(container, "input")[0];
        expect(input).not.toBeNull();
        Simulate.change(input);
        expect(rowClicked).toHaveBeenCalled();
        expect(rowClicked).toHaveBeenCalledWith(items[0]);
    });

    test("03 - Check items change with prop updates", () => {
        const items = generateCheckItems();
        const rowClicked = jest.fn();
        const { rerender, container } = render(
            <HierarchyList
                items={items}
                checkedItems={[]}
                checkClicked={rowClicked}
            />
        );
        const initialInputs = elementsArray(container, "input");
        expect(initialInputs.every(input => !input.checked)).toBe(true);
        rerender(
            <HierarchyList
                items={items}
                checkedItems={items}
                checkClicked={rowClicked}
            />
        );
        const inputs = elementsArray(container, "input");
        expect(inputs.every(input => input.checked)).toBe(true);
    });

    test("04 - Click arrow show children", async () => {
        let items = generateCheckItems();
        while (items.every(i => !i.children.length)) {
            items = generateCheckItems();
        }
        const rowClicked = jest.fn();
        const { getByTestId } = render(
            <HierarchyList
                items={items}
                checkedItems={items}
                checkClicked={rowClicked}
            />
        );
        const withChildren = items.find(item => Boolean(item.children.length));
        const row = getByTestId(withChildren.id);
        Simulate.click(row);
        await wait(() =>
            expect(getByTestId(withChildren.children[0].id)).not.toBeNull()
        );
        expect(getByTestId(withChildren.children[0].id)).not.toBeNull();
    });
    test("05 - Hierarchy list snapshot", () => {
        const items: CheckItem[] = [
            {
                id: "123",
                name: "joe",
                children: [],
            },
            {
                id: "234",
                name: "montana",
                children: [
                    {
                        id: "236",
                        name: "john",
                        children: [],
                    },
                ],
            },
        ];
        const clicked = jest.fn();
        const { container } = render(
            <HierarchyList
                items={items}
                checkedItems={[]}
                checkClicked={clicked}
            />
        );
        expect(container).toMatchSnapshot();
    });
});
