import * as React from "react";
import renderer from "react-test-renderer";
import { Alert } from "react-native";
import SignUp from "@/app/signup";

const mockSignUp = jest.fn();
const InputMock = (props: Record<string, unknown>) => React.createElement("Input", props);
const ButtonMock = (props: Record<string, unknown>) => React.createElement("Button", props);

jest.mock("@/stores/auth", () => ({
  useAuthStore: jest.fn((selector: (state: unknown) => unknown) =>
    selector({
      loading: false,
      signUp: mockSignUp,
    })
  ),
}));

jest.mock("@/hooks/useThemeColor", () => ({
  useThemeColor: ({ light }: { light: string }) => light,
}));

jest.mock("@/hooks/useColorScheme", () => ({
  useColorScheme: () => "light",
}));

jest.mock("@rn-vui/themed", () => {
  return {
    Button: ButtonMock,
    Input: InputMock,
  };
});

jest.mock("expo-router", () => {
  const React = require("react");

  return {
    Link: (props: Record<string, unknown> & { children?: React.ReactNode }) =>
      React.createElement("Link", props, props.children),
  };
});

jest.mock("lucide-react-native", () => {
  const React = require("react");
  const Icon = () => React.createElement("Icon");

  return {
    Building2: Icon,
    Lock: Icon,
    Mail: Icon,
    User: Icon,
  };
});

describe("SignUp screen", () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it("shows the signup error to the user when registration fails", async () => {
    mockSignUp.mockRejectedValueOnce(new Error("Adresse déjà utilisée"));
    const alertSpy = jest.spyOn(Alert, "alert").mockImplementation(jest.fn());

    let component: renderer.ReactTestRenderer;

    await renderer.act(async () => {
      component = renderer.create(<SignUp />);
    });

    const inputs = component!.root.findAllByType(InputMock);

    await renderer.act(async () => {
      inputs[0].props.onChangeText("Ada");
      inputs[1].props.onChangeText("Lovelace");
      inputs[2].props.onChangeText("Analytical Engines");
      inputs[3].props.onChangeText("ada@example.com");
      inputs[4].props.onChangeText("password123");
    });

    const button = component!.root.findByType(ButtonMock);

    await renderer.act(async () => {
      await button.props.onPress();
    });

    expect(mockSignUp).toHaveBeenCalledWith(
      "ada@example.com",
      "password123",
      "Ada",
      "Lovelace",
      "Analytical Engines"
    );
    expect(alertSpy).toHaveBeenCalledWith("Erreur", "Adresse déjà utilisée");
  });
});
