import * as React from "react";
import {
    renderIntoDocument,
    render,
    cleanup,
    fireEvent,
    wait,
    Simulate,
} from "react-testing-library";
import { elementsArray } from "./utils";
import { getRadioItems } from "./utils/radioGroup";
import RadioButton, { mergeStyles } from "../components/RadioGroup";
import * as DefaultStyles from "../components/RadioGroup/style";
import { shallow } from "enzyme";

describe("radio input", () => {
    test("01 - renders radio inputs", () => {
        const items = getRadioItems();
        const clicked = jest.fn();

        const { container } = renderIntoDocument(
            <RadioButton
                items={items}
                styles={{}}
                title={"testing"}
                onRadioButtonChange={clicked}
                selectedId={items[0].id}
            />
        );
        const inputs = elementsArray(container, "input").map(c =>
            c.getAttribute("type")
        );
        expect(inputs.every(t => t === "radio")).toBe(true);
    });
    test("02 - renders labels with names", () => {
        const items = getRadioItems();
        const clicked = jest.fn();
        const { container } = render(
            <RadioButton
                items={items}
                onRadioButtonChange={clicked}
                title={"snapshot"}
                selectedId={items[0].id}
            />
        );
        const labels = elementsArray(container, "label");
        expect(
            labels.every((l, idx) => l.textContent === items[idx].name)
        ).toBe(true);
    });

    test("03 - selected button changes with props", () => {
        const items = getRadioItems();
        const clicked = jest.fn();
        const { container, rerender } = render(
            <RadioButton
                items={items}
                onRadioButtonChange={clicked}
                title={"snapshot"}
                selectedId={items[0].id}
            />
        );
        const defaultInputs = elementsArray(container, "input");
        expect(defaultInputs[0].checked).toBe(true);
        rerender(
            <RadioButton
                items={items}
                onRadioButtonChange={clicked}
                title={"snapshot"}
                selectedId={items[3].id}
            />
        );
        const inputs = elementsArray(container, "input");
        expect(inputs[3].checked).toBe(true);
    });
    test("04 - matches snapshot", () => {
        const items = getRadioItems(true);
        const clicked = jest.fn();
        const { container } = render(
            <RadioButton
                items={items}
                selectedId={items[0].id}
                onRadioButtonChange={clicked}
                title={"snapshot"}
            />
        );
        expect(container).toMatchSnapshot();
    });

    test("05 - matches enzyme snapshot", () => {
        const items = getRadioItems(true);
        const clicked = jest.fn();
        const { container } = render(
            <RadioButton
                items={items}
                onRadioButtonChange={clicked}
                title={"snapshot"}
                selectedId={items[0].id}
            />
        );
        expect(container).toMatchSnapshot();
    });

    test("05 - on radio button change prop called when inputs are changed", async () => {
        const items = getRadioItems();
        const clicked = jest.fn();
        const { getByLabelText } = render(
            <RadioButton
                items={items}
                onRadioButtonChange={clicked}
                title={"snapshot"}
                selectedId={items[0].id}
            />
        );

        Simulate.change(getByLabelText(items[0].name));
        expect(clicked).toHaveBeenCalledWith(items[0]);
        expect(clicked).toHaveBeenCalledTimes(1);

        Simulate.change(getByLabelText(items[1].name));
        expect(clicked).toHaveBeenCalledTimes(2);

        Simulate.change(getByLabelText(items[2].name));
        expect(clicked).toHaveBeenCalledTimes(3);

        Simulate.change(getByLabelText(items[3].name));
        expect(clicked).toHaveBeenCalledTimes(4);

        Simulate.change(getByLabelText(items[4].name));
        expect(clicked).toHaveBeenCalledTimes(5);
    });
});

describe("merge styles", () => {
    test("01 - styles undefined leaves default styles", () => {
        expect(mergeStyles(DefaultStyles)).toEqual(DefaultStyles);
    });
});
