/**
 * TEAM: frontend_infra
 * @flow
 */

import * as React from "react";
import {act} from "react-dom/test-utils";
// TODO: Fix this eslint issue on next edit. This is an autogenerated comment.
// eslint-disable-next-line flexport/no-legacy-dependencies
import {mount, ReactWrapper} from "enzyme";
import ConditionalFilter from "../ConditionalFilter";
import SelectFilter from "../SelectFilter";

jest.mock("popper.js");

function mountConditionalFilter(
  propOverrides?: $Shape<React.ElementConfig<typeof ConditionalFilter>>
): ReactWrapper<any> {
  const defaultOptions = [
    {label: "A", value: "a"},
    {label: "B", value: "b"},
  ];
  const defaultValues = [
    {label: "1", value: 1},
    {label: "2", value: 2},
  ];
  const defaultProps = {
    label: "Conditional Filter",
    onApply: () => {},
    showOperatorFilter: true,
    typeFilter: {label: "Types", options: defaultOptions},
    valueFilterRenderer: (_type, value, updateValue) => (
      <SelectFilter
        label="Values"
        options={defaultValues}
        onChange={val => {
          updateValue(val);
        }}
        value={value}
      />
    ),
  };
  const Component = () => (
    <ConditionalFilter {...defaultProps} {...propOverrides} />
  );

  return mount(<Component />);
}

describe("ConditionalFilter", () => {
  it("adds and removes rows to dropdown", async () => {
    const wrapper = mountConditionalFilter();
    wrapper.find("FilterButton").simulate("click");
    const dropdown = wrapper.find("Popper").first();
    // should open w/ one row of filters
    expect(wrapper.find("BaseFilter").length).toEqual(4);
    // add a row of filters
    dropdown
      .find("Button")
      .find({children: "Add another"})
      .at(0)
      .simulate("click");
    wrapper.update();
    expect(wrapper.find("BaseFilter").length).toEqual(7);
    // remove second row
    wrapper.find("IconButton").at(1).simulate("click");
    expect(wrapper.find("BaseFilter").length).toEqual(4);
  });

  it("doesn't return rows missing fields", () => {
    let returnVal;
    const wrapper = mountConditionalFilter({
      onApply: val => {
        returnVal = val;
      },
    });
    wrapper.find("FilterButton").simulate("click");
    const dropdown = wrapper.find("Popper").first();
    const filters = dropdown.find("BaseFilter");
    // select first item from 'operator' filter
    filters.at(0).find("FilterButton").simulate("click");
    act(() => {
      wrapper.find("li").at(1).props().onMouseDown();
    });
    expect(filters.at(0).find("FilterLabel").text()).toEqual("Exclude");

    // return val should be empty array because entire row is not populated
    const applyButton = dropdown.find("Button").at(2);
    applyButton.simulate("click");
    expect(Array.isArray(returnVal) && returnVal.length === 0).toEqual(true);
  });
});
