import { renderHook } from "@testing-library/react-hooks";
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
import { useTapSeek } from "../useTapSeek";

import { ON_PRESS_RESET_DURATION, SEEK_TYPE, SKIP_TIME_BASE } from "../const";

const rewind = jest.fn();
const forward = jest.fn();

jest
  .spyOn(playerManager, "getInstanceController")
  // @ts-ignore
  .mockImplementation(() => ({ rewind, forward }));

describe("useTapSeek", () => {
  beforeEach(() => {
    rewind.mockReset();
    forward.mockReset();
  });

  describe("forward", () => {
    it("should call forward method on playerManager", () => {
      const { result } = renderHook(() => useTapSeek());

      result.current(SEEK_TYPE.FORWARD);
      expect(forward).toBeCalled();
    });

    it("should call forward with default skip time", () => {
      const { result } = renderHook(() => useTapSeek());

      result.current(SEEK_TYPE.FORWARD);
      expect(forward).toBeCalledWith(SKIP_TIME_BASE);
    });

    it("should multiply skip time for every call", async () => {
      const { result } = renderHook(() => useTapSeek());

      result.current(SEEK_TYPE.FORWARD);
      expect(forward).toBeCalledWith(SKIP_TIME_BASE);
      result.current(SEEK_TYPE.FORWARD);
      expect(forward).toBeCalledWith(SKIP_TIME_BASE * 2);
    });

    it("should reset multiplier if waiting more then resetDuration between press actions", () => {
      const { result, waitFor } = renderHook(() => useTapSeek());

      result.current(SEEK_TYPE.FORWARD);
      expect(forward).toBeCalledWith(SKIP_TIME_BASE);
      waitFor(jest.fn(), { timeout: ON_PRESS_RESET_DURATION });
      result.current(SEEK_TYPE.FORWARD);
      expect(forward).toBeCalledWith(SKIP_TIME_BASE);
    });
  });

  describe("rewind", () => {
    it("should call rewind method on playerManager", () => {
      const { result } = renderHook(() => useTapSeek());

      result.current(SEEK_TYPE.REWIND);
      expect(rewind).toBeCalled();
    });

    it("should call rewind with default skip time", () => {
      const { result } = renderHook(() => useTapSeek());

      result.current(SEEK_TYPE.REWIND);
      expect(rewind).toBeCalledWith(SKIP_TIME_BASE);
    });

    it("should multiply skip time for every call", async () => {
      const { result } = renderHook(() => useTapSeek());

      result.current(SEEK_TYPE.REWIND);
      expect(rewind).toBeCalledWith(SKIP_TIME_BASE);
      result.current(SEEK_TYPE.REWIND);
      expect(rewind).toBeCalledWith(SKIP_TIME_BASE * 2);
    });
  });

  describe("mixed usage", () => {
    it("should reset timer if different type of event is emitted", () => {
      const { result } = renderHook(() => useTapSeek());
      result.current(SEEK_TYPE.REWIND);
      expect(rewind).toBeCalledWith(SKIP_TIME_BASE);

      result.current(SEEK_TYPE.REWIND);
      expect(rewind).toBeCalledWith(SKIP_TIME_BASE * 2);

      result.current(SEEK_TYPE.FORWARD);
      expect(forward).toBeCalledWith(SKIP_TIME_BASE);
    });
  });
});
