import React from "react";
import { shallow } from "enzyme";
import SummaryMap, {
  RoundSelect,
} from "../components/screens/GameSummary/SummaryMap/SummaryMap";

jest.mock("iso-3166-1");
jest.mock("../domain/flagLookup");
jest.mock("../hooks/useGameInfo");
jest.mock("../hooks/useMap");
jest.mock("../hooks/useMapBounds");
jest.mock("../hooks/useMarkersFromGuesses");

import iso from "iso-3166-1";
import useMarkersFromGuesses from "../hooks/useMarkersFromGuesses";
import useMap from "../hooks/useMap";
import useMapBounds from "../hooks/useMapBounds";
import { useGameConfig } from "../hooks/useGameInfo";

describe("SummaryMap", () => {
  beforeEach(() => {
    iso.whereAlpha2.mockReturnValue({ country: "test-country" });
  });

  it("renders", () => {
    useMap.mockReturnValue("map");
    useGameConfig.mockReturnValue({ countryLock: "lock" });
    const rendered = shallow(
      <SummaryMap
        players="players"
        coords={{
          1: {},
          2: {},
          3: {},
        }}
      />
    );
    expect(rendered).toMatchSnapshot();
    expect(useMapBounds).toHaveBeenCalledWith("map", "lock");
    expect(useMarkersFromGuesses).toHaveBeenCalledWith(
      "map",
      "players",
      "0",
      null
    );
  });

  it("renders without selector if single round", () => {
    useMap.mockReturnValue("map");
    useGameConfig.mockReturnValue({ countryLock: "lock" });
    const rendered = shallow(
      <SummaryMap
        players="players"
        coords={{
          1: "round",
        }}
      />
    );
    expect(rendered).toMatchSnapshot();
    expect(useMapBounds).toHaveBeenCalledWith("map", "lock");
    expect(useMarkersFromGuesses).toHaveBeenCalledWith(
      "map",
      "players",
      "1",
      "round"
    );
  });

  it("handles having the round changed", () => {
    const panTo = jest.fn();
    useMap.mockReturnValue({ current: { panTo } });
    useGameConfig.mockReturnValue({ countryLock: "lock" });
    const rendered = shallow(
      <SummaryMap
        players="players"
        coords={{
          1: { lat: 1, lng: 2 },
          2: { lat: 3, lng: 4 },
          3: { lat: 5, lng: 6 },
        }}
      />
    );
    rendered.find("RoundSelect").prop("onSelect")(2);
    expect(panTo).toMatchSnapshot();
    expect(rendered).toMatchSnapshot();
  });

  it("handles invalid round change", () => {
    const panTo = jest.fn();
    useMap.mockReturnValue({ current: { panTo } });
    useGameConfig.mockReturnValue({ countryLock: "lock" });
    const rendered = shallow(
      <SummaryMap
        players="players"
        coords={{
          1: { lat: 1, lng: 2 },
          2: { lat: 3, lng: 4 },
          3: { lat: 5, lng: 6 },
        }}
      />
    );
    rendered.find("RoundSelect").prop("onSelect")(5);
    expect(panTo).toMatchSnapshot();
    expect(rendered).toMatchSnapshot();
  });

  describe("RoundSelect", () => {
    it("renders", () => {
      const onSelect = jest.fn();
      const rendered = shallow(
        <RoundSelect
          rounds={3}
          coords={{
            1: { country: "country1" },
            2: { country: "country2" },
            3: { country: "country3" },
          }}
          onSelect={onSelect}
        />
      );
      expect(rendered).toMatchSnapshot();
    });

    it("can be selected", () => {
      const onSelect = jest.fn();
      const rendered = shallow(
        <RoundSelect
          rounds={3}
          coords={{
            1: { country: "country1" },
            2: { country: "country2" },
            3: { country: "country3" },
          }}
          selected="2"
          onSelect={onSelect}
        />
      );
      expect(rendered).toMatchSnapshot();
    });

    it("calls onSelect when clicked", () => {
      const onSelect = jest.fn();
      const rendered = shallow(
        <RoundSelect
          rounds={3}
          coords={{
            1: { country: "country1" },
            2: { country: "country2" },
            3: { country: "country3" },
          }}
          onSelect={onSelect}
        />
      );
      rendered.find("div.tab").first().simulate("click");
      expect(onSelect).toHaveBeenCalledWith("1");
    });

    it("calls onSelect when enter pressed", () => {
      const onSelect = jest.fn();
      const rendered = shallow(
        <RoundSelect
          rounds={3}
          coords={{
            1: { country: "country1" },
            2: { country: "country2" },
            3: { country: "country3" },
          }}
          onSelect={onSelect}
        />
      );
      rendered.find("div.tab").first().simulate("keydown", { key: "Enter" });
      expect(onSelect).toHaveBeenCalledWith("1");
    });

    it("does not call onSelect when other keys pressed", () => {
      const onSelect = jest.fn();
      const rendered = shallow(
        <RoundSelect
          rounds={3}
          coords={{
            1: { country: "country1" },
            2: { country: "country2" },
            3: { country: "country3" },
          }}
          onSelect={onSelect}
        />
      );
      rendered.find("div.tab").first().simulate("keydown", { key: "Escape" });
      expect(onSelect).not.toHaveBeenCalledWith("1");
    });

    it("calls onSelect with 0 when X clicked", () => {
      const onSelect = jest.fn();
      const rendered = shallow(
        <RoundSelect
          rounds={3}
          coords={{
            1: { country: "country1" },
            2: { country: "country2" },
            3: { country: "country3" },
          }}
          onSelect={onSelect}
        />
      );
      rendered
        .findWhere(x => x.text() === "X")
        .first()
        .simulate("click");
      expect(onSelect).toHaveBeenCalledWith("0");
    });

    it("calls onSelect with 0 when enter pressed on X", () => {
      const onSelect = jest.fn();
      const rendered = shallow(
        <RoundSelect
          rounds={3}
          coords={{
            1: { country: "country1" },
            2: { country: "country2" },
            3: { country: "country3" },
          }}
          onSelect={onSelect}
        />
      );
      rendered
        .findWhere(x => x.text() === "X")
        .first()
        .simulate("keydown", { key: "Enter" });
      expect(onSelect).toHaveBeenCalledWith("0");
    });

    it("does not call onSelect with 0 when other keys pressed on X", () => {
      const onSelect = jest.fn();
      const rendered = shallow(
        <RoundSelect
          rounds={3}
          coords={{
            1: { country: "country1" },
            2: { country: "country2" },
            3: { country: "country3" },
          }}
          onSelect={onSelect}
        />
      );
      rendered
        .findWhere(x => x.text() === "X")
        .first()
        .simulate("keydown", { key: "Escape" });
      expect(onSelect).not.toHaveBeenCalledWith("0");
    });
  });
});
