import React from "react";
import { render, waitFor, cleanup } from "@testing-library/react";
import { AuthContext } from "../../../App";
import { useAuth } from "../useAuthentication";

const MockedComponent: React.FC = () => {
  const { authenticated } = useAuth();
  return <div>{authenticated}</div>;
};

let authenticated = false;
const setAuthenticated = (args: boolean) => (authenticated = args);

describe("useAuth", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    cleanup();
  });

  afterEach(() => {
    jest.clearAllMocks();
    cleanup();
  });

  it("should set authenticated to true when fetch returns ok", async () => {
    global.fetch = jest.fn(() => Promise.resolve({ ok: true })) as jest.Mock;

    render(
      <AuthContext.Provider value={{ authenticated, setAuthenticated }}>
        <MockedComponent />
      </AuthContext.Provider>
    );

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));

    expect(authenticated).toBe(true);
  });

  it("should set authenticated to false when fetch returns not ok", async () => {
    global.fetch = jest.fn(() => Promise.resolve({ ok: false })) as jest.Mock;

    render(
      <AuthContext.Provider value={{ authenticated, setAuthenticated }}>
        <MockedComponent />
      </AuthContext.Provider>
    );

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));

    expect(authenticated).toBe(false);
  });

  it("should call fetch once", async () => {
    global.fetch = jest.fn(() => Promise.resolve({ ok: false })) as jest.Mock;

    render(
      <AuthContext.Provider value={{ authenticated, setAuthenticated }}>
        <MockedComponent />
      </AuthContext.Provider>
    );

    await waitFor(() => {
      expect(fetch).toHaveBeenCalledTimes(1);
    });
  });
});