import React from "react";
import { Text } from "react-native";
import { render, waitFor } from "@testing-library/react-native";
import { ScreenFeedLoader } from "../ScreenFeedLoader";

const mockUseFeedLoader = jest.fn();
const mockUseScreenContextV2 = jest.fn();
const mockSetState = jest.fn();

jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
  useFeedLoader: (...args) => mockUseFeedLoader(...args),
}));

jest.mock(
  "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext",
  () => ({
    useScreenContextV2: (...args) => mockUseScreenContextV2(...args),
  })
);

describe("ScreenFeedLoader", () => {
  beforeEach(() => {
    jest.clearAllMocks();

    mockUseScreenContextV2.mockReturnValue({
      _feedStore: {
        setState: mockSetState,
      },
    });
  });

  it("hides children while loading", () => {
    mockUseFeedLoader.mockReturnValue({
      data: null,
      loading: true,
      error: null,
    });

    const { queryByText } = render(
      <ScreenFeedLoader id="test" feedData={{ source: "url", mapping: {} }}>
        <Text>child</Text>
      </ScreenFeedLoader>
    );

    expect(queryByText("child")).toBeNull();
  });

  it("writes loaded feed data to _feedStore", async () => {
    const data = { entry: { id: "1" } };

    mockUseFeedLoader.mockReturnValue({
      data,
      loading: false,
      error: null,
    });

    render(
      <ScreenFeedLoader id="test" feedData={{ source: "url", mapping: {} }}>
        <Text>child</Text>
      </ScreenFeedLoader>
    );

    await waitFor(() => {
      expect(mockSetState).toHaveBeenCalledWith({
        screenFeed: data,
        screenFeedError: null,
      });
    });
  });

  it("writes feed error to _feedStore", async () => {
    const error = new Error("feed failed");
    const data = { fallback: true };

    mockUseFeedLoader.mockReturnValue({
      data,
      loading: false,
      error,
    });

    render(
      <ScreenFeedLoader id="test" feedData={{ source: "url", mapping: {} }}>
        <Text>child</Text>
      </ScreenFeedLoader>
    );

    await waitFor(() => {
      expect(mockSetState).toHaveBeenCalledWith({
        screenFeed: data,
        screenFeedError: error,
      });
    });
  });
});
