import React from "react";
import { shallow } from "enzyme";
import GuessPane from "../components/screens/GamePanel/GuessPane";

jest.mock("../domain/gameStore");
jest.mock("../domain/geocoding");
jest.mock("../components/screens/GamePanel/GuessPane/useMapResizeKeybindings");

import { dispatch } from "../domain/gameStore";
import { reverseGeocode } from "../domain/geocoding";

describe("GuessPane", () => {
  it("renders", () => {
    const rendered = shallow(<GuessPane />);
    expect(rendered).toMatchSnapshot();
  });

  it("resizes to large", () => {
    const handle = shallow(<GuessPane />);
    handle.find("div.resize").first().simulate("click");
    expect(handle).toMatchSnapshot();
  });

  it("resizes to large then back", () => {
    const handle = shallow(<GuessPane />);
    handle.find("div.resize").first().simulate("click");
    handle.find("div.resize").first().simulate("click");
    expect(handle).toMatchSnapshot();
  });

  it("resizes to medium", () => {
    const handle = shallow(<GuessPane />);
    handle.find("div.resize--medium").first().simulate("click");
    expect(handle).toMatchSnapshot();
  });

  it("resizes to medium then back", () => {
    const handle = shallow(<GuessPane />);
    handle.find("div.resize--medium").first().simulate("click");
    handle.find("div.resize--medium").first().simulate("click");
    expect(handle).toMatchSnapshot();
  });

  it("resizes to large on keydown Enter", () => {
    const handle = shallow(<GuessPane />);
    handle.find("div.resize").first().simulate("keydown", { key: "Enter" });
    expect(handle).toMatchSnapshot();
  });

  it("large resize ignores other keydowns", () => {
    const handle = shallow(<GuessPane />);
    handle.find("div.resize").first().simulate("keydown", { key: "Escape" });
    expect(handle).toMatchSnapshot();
  });

  it("resizes to medium on keydown Enter", () => {
    const handle = shallow(<GuessPane />);
    handle
      .find("div.resize--medium")
      .first()
      .simulate("keydown", { key: "Enter" });
    expect(handle).toMatchSnapshot();
  });

  it("medium resize ignores other keydowns", () => {
    const handle = shallow(<GuessPane />);
    handle
      .find("div.resize--medium")
      .first()
      .simulate("keydown", { key: "Escape" });
    expect(handle).toMatchSnapshot();
  });

  it("submits", async () => {
    reverseGeocode.mockReturnValue("geocoded");
    const handle = shallow(<GuessPane />);
    handle.find("ClickMarkerMap").first().prop("onMarkerMoved")({
      lat: "lat",
      lng: "lng",
    });
    // check submit enabled
    expect(handle).toMatchSnapshot();
    await handle.find("button").first().simulate("click");
    expect(reverseGeocode).toHaveBeenCalledWith(
      expect.objectContaining({ lat: "lat", lng: "lng" })
    );
    expect(dispatch.submitGuess).toHaveBeenCalledWith(
      expect.objectContaining({
        country: "geocoded",
        lat: "lat",
        lng: "lng",
      })
    );
    // check submit disabled again
    expect(handle).toMatchSnapshot();
  });

  it("cannot be tricked into resubmitting", async () => {
    reverseGeocode.mockReturnValue("geocoded");
    const handle = shallow(<GuessPane />);
    handle.find("ClickMarkerMap").first().prop("onMarkerMoved")({
      lat: "lat",
      lng: "lng",
    });
    // check submit enabled
    expect(handle).toMatchSnapshot();
    await handle.find("button").first().simulate("click");
    await handle.find("button").prop("onClick")();
    expect(reverseGeocode).toHaveBeenCalledTimes(1);
    expect(dispatch.submitGuess).toHaveBeenCalledTimes(1);
    // check submit disabled again
    expect(handle).toMatchSnapshot();
  });
});
