import * as React from "react";
import { View } from "react-native";
import { render } from "@testing-library/react-native";

const Mocked_RouteManager = jest.fn((props) => (
  <View testID="routeManager" {...props} />
));

const mock_navBarVisibleFlag = true;

const mockIsNavBarVisible = jest.fn(() => mock_navBarVisibleFlag);

const mockIsOrientationCompatible = jest.fn(() => true);

jest.mock("react-native-safe-area-context", () => ({
  useSafeAreaInsets: () => ({ top: 44 }),
  useSafeAreaFrame: () => ({ x: 0, y: 0, width: 375, height: 812 }),
}));

jest.mock("../../RouteManager", () => ({
  RouteManager: Mocked_RouteManager,
}));

jest.mock(
  "@applicaster/zapp-react-native-utils/appUtils/orientationHelper",
  () => ({
    isOrientationCompatible: mockIsOrientationCompatible,
    allowedOrientationsForScreen: jest.fn(),
    getOrientation: jest.fn(),
    getScreenOrientation: jest.fn(),
    useGetScreenOrientation: jest.fn(),
    ORIENTATIONS: jest.requireActual(
      "@applicaster/zapp-react-native-utils/appUtils/orientationHelper"
    ).ORIENTATIONS,
  })
);

jest.mock("@applicaster/zapp-react-native-utils/analyticsUtils", () => ({
  useAnalytics: jest.fn(() => ({
    sendScreenEvent: jest.fn(),
  })),
}));

jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
  useTheme: jest.fn(() => ({
    app_background_color: "blue",
  })),
}));

const mockNavBar = jest.fn((props) => {
  const View = jest.requireActual("react-native").View;

  return <View testID="navBar" {...props} />;
});

jest.mock(
  "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers",
  () => ({
    getNavigationPluginModule: () => mockNavBar,
  })
);

jest.mock(
  "@applicaster/zapp-react-native-utils/reactHooks/screen/useCurrentScreenData",
  () => ({
    useCurrentScreenData: jest.fn(() => ({
      id: "testId",
    })),
  })
);

jest.mock(
  "@applicaster/zapp-react-native-utils/reactHooks/state/useRivers",
  () => ({
    useRivers: jest.fn(() => ({
      rivers: [{ id: "testId", name: "Test River" }],
    })),
  })
);

jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
  isNavBarVisible: mockIsNavBarVisible,
  useIsScreenActive: jest.fn().mockReturnValue(true),
  useNavigation: jest.fn(() => ({
    canGoBack: () => false,
    currentRoute: "/river/testId",
    activeRiver: { id: "testId" },
    screenData: { id: "testId" },
    data: { screen: { id: "testId" } },
  })),
  useRoute: jest.fn(() => ({
    pathname: "/river/testId",
    screenData: { id: "testId" },
  })),
}));

jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
  ...jest.requireActual("@applicaster/zapp-react-native-utils/reactHooks"),
  useCurrentScreenData: jest.fn(() => ({
    id: "testId",
  })),
  useNavbarState: jest.fn(() => ({
    title: "Test Title",
  })),
  useScreenData: jest.fn(() => ({
    id: "testId",
    navigations: [{ id: "testId", category: "nav_bar" }],
  })),
  useDimensions: jest.fn(() => ({
    width: 1920,
    height: 1080,
  })),
  useIsTablet: jest.fn(() => false),
}));

jest.mock("@applicaster/zapp-react-native-redux/hooks", () => {
  const View = jest.requireActual("react-native").View;

  return {
    ...jest.requireActual("@applicaster/zapp-react-native-redux/hooks"),
    usePickFromState: () => ({
      plugins: [
        {
          name: "Offline Plugin",
          identifier: "offline-experience",
          type: "general",
          module: {
            OfflineFallbackScreen: ({ children }) => <View>{children}</View>, // eslint-disable-line
          },
        },
      ],
    }),
  };
});

const {
  allowedOrientationsForScreen,
  getOrientation,
  useGetScreenOrientation,
} = require("@applicaster/zapp-react-native-utils/appUtils/orientationHelper");

const navigator = {};
const navBarProps = { nav_items: [] };
const screenData = {};

const screenProps = {
  pathname: "/foo/path",
  navigator,
  navBarProps,
  screenData,
};

const { Screen } = require("..");

describe("<Screen Component />", () => {
  beforeEach(() => {
    allowedOrientationsForScreen.mockClear();
    getOrientation.mockClear();
    useGetScreenOrientation.mockClear();
  });

  describe("when the navbar should show", () => {
    it("renders correctly", () => {
      const { toJSON } = render(<Screen {...screenProps} />);
      expect(toJSON()).toMatchSnapshot();
    });
  });

  describe("when the navbar should be hidden", () => {
    it("renders correctly", () => {
      const { toJSON } = render(<Screen {...screenProps} />);
      expect(toJSON()).toMatchSnapshot();
    });
  });
});
