jest.mock("../../src/core/crashLog", () => ({
  recordCrash: jest.fn(),
}));

import React from "react";
import { Text } from "react-native";
import { fireEvent, render } from "@testing-library/react-native";
import ErrorBoundary from "../../src/shared/ErrorBoundary";
import { recordCrash } from "../../src/core/crashLog";

function Boom(): React.ReactElement {
  throw new Error("render boom");
}

describe("ErrorBoundary", () => {
  let errorSpy: jest.SpyInstance;

  beforeEach(() => {
    jest.clearAllMocks();
    // React loggue l'erreur captee : on tait le bruit pour garder la sortie propre.
    errorSpy = jest.spyOn(console, "error").mockImplementation(() => {});
  });

  afterEach(() => {
    errorSpy.mockRestore();
  });

  it("rend les enfants quand tout va bien", () => {
    const { getByText } = render(
      <ErrorBoundary>
        <Text>contenu-ok</Text>
      </ErrorBoundary>
    );
    expect(getByText("contenu-ok")).toBeTruthy();
  });

  it("affiche le repli et journalise quand un enfant throw", () => {
    const { getByText } = render(
      <ErrorBoundary>
        <Boom />
      </ErrorBoundary>
    );
    expect(getByText("Une erreur est survenue")).toBeTruthy();
    expect(recordCrash).toHaveBeenCalledWith(
      expect.objectContaining({ kind: "render", message: "render boom" })
    );
  });

  it("Reessayer remonte les enfants", () => {
    let crash = true;
    function Child(): React.ReactElement {
      if (crash) {
        throw new Error("x");
      }
      return <Text>recovered</Text>;
    }
    const { getByText, queryByText } = render(
      <ErrorBoundary>
        <Child />
      </ErrorBoundary>
    );
    expect(getByText("Une erreur est survenue")).toBeTruthy();

    crash = false;
    fireEvent.press(getByText("Reessayer"));

    expect(getByText("recovered")).toBeTruthy();
    expect(queryByText("Une erreur est survenue")).toBeNull();
  });
});
