import React from "react";
import { Provider } from "react-redux";
import { createMemoryHistory } from "history";
import { Router } from "react-router-dom";
import { render, waitFor } from "@testing-library/react";
import {
  UserIsAuthenticated,
  UserIsNotAuthenticated,
  getIsLoggedIn
} from "../authWrapper"; // Update the import path as needed
import { configureStore } from "@capillarytech/vulcan-react-sdk/utils";
import { initialReducer } from "../../initialReducer";

jest.mock('redux-auth-wrapper/history4/redirect', () => ({
    connectedRouterRedirect: jest.fn().mockImplementation((config) => {
      // A mock component to simulate the behavior
      const Component = ({ children }) => {
        if (!config.authenticatedSelector()) {
          // Handling redirectPath whether it's a string or a function
          const redirectPath = typeof config.redirectPath === 'function'
            ? config.redirectPath({})
            : config.redirectPath;
            if(config.redirectAction) config.redirectAction(redirectPath);
          
        }
        return <>{children}</>;
      };
      Component.displayName = config.wrapperDisplayName;
      return Component;
    }),
  }));

jest.mock("../../v2Containers/Cap/selectors", () => ({
  makeSelectAuthenticated: jest.fn(() => jest.fn().mockReturnValue(true)) // Mock as authenticated
}));
let store;
beforeAll(() => {
  store = configureStore({}, initialReducer, history);
});

describe("Authentication Redirects", () => {
  const localStorageMock = (function() {
    let store = {};
    return {
      getItem(key) {
        return store[key] || null;
      },
      setItem(key, value) {
        store[key] = value.toString();
      },
      clear() {
        store = {};
      }
    };
  })();
  Object.defineProperty(window, "localStorage", {
    value: localStorageMock
  });

  beforeEach(() => {
    window.localStorage.clear();
    jest.resetModules();
  });
  const history = createMemoryHistory();

  it("redirects an unauthenticated user to login", async () => {
    const { getByText } = render(
      <Provider store={store}>
        <Router history={history}>
          <UserIsAuthenticated>
            <div>Authenticated Content</div>
          </UserIsAuthenticated>
        </Router>
      </Provider>
    );

    await waitFor(() => {
      expect(history.location.pathname).toEqual("/");
    }, { timeout: 5000, interval: 100 });
  });


  it("handles redirection for not authenticated users based on query", async () => {
    history.push("/some-route?redirect=/custom");
    render(
      <Provider store={store}>
        <Router history={history}>
          <UserIsNotAuthenticated>
            <div>Not Authenticated Content</div>
          </UserIsNotAuthenticated>
        </Router>
      </Provider>
    );

    await waitFor(() => {
      expect(history.location.pathname).toEqual("/some-route");
    }, { timeout: 5000, interval: 100 });
  });
});

describe("getIsLoggedIn", () => {
  // Mocking localStorage
  const localStorageMock = (function() {
    let store = {};
    return {
      getItem(key) {
        return store[key] || null;
      },
      setItem(key, value) {
        store[key] = value.toString();
      },
      clear() {
        store = {};
      }
    };
  })();
  Object.defineProperty(window, "localStorage", {
    value: localStorageMock
  });

  beforeEach(() => {
    window.localStorage.clear();
    jest.resetModules();
  });

  it("returns true if in production environment and isLoggedIn is true", () => {
    process.env.NODE_ENV = "production";
    window.localStorage.setItem("isLoggedIn", JSON.stringify(true));

    expect(getIsLoggedIn()).toBeTruthy();
  });

  it("returns true if token is present in localStorage", () => {
    window.localStorage.setItem("token", "some-token");

    expect(getIsLoggedIn()).toBeTruthy();
  });

  it("returns false if neither token nor isLoggedIn are set", () => {
    expect(getIsLoggedIn()).toBeFalsy();
  });
});
