import { ApolloProvider } from "@apollo/client";
import * as Sentry from "@sentry/react";
import { SplitFactoryProvider, useSplitClient } from "@splitsoftware/splitio-react";
import { ConfigProvider } from "antd";
import enLocale from "antd/es/locale/en_US";
import { useEffect, useMemo } from "react";
import { CookiesProvider } from "react-cookie";
import { useTranslation } from "react-i18next";
import { connect, useSelector } from "react-redux";
import { createStructuredSelector } from "reselect";
import GlobalLoadingBar from "../components/global-loading-bar/global-loading-bar.component";
import { setDarkMode } from "../redux/application/application.actions";
import { selectDarkMode } from "../redux/application/application.selectors";
import { selectCurrentUser } from "../redux/user/user.selectors.js";
import { signOutStart } from "../redux/user/user.actions";
import client from "../utils/GraphQLClient";
import App from "./App";
import getTheme from "./themeProvider";

// Base Split configuration
const config = {
  core: {
    authorizationKey: import.meta.env.VITE_APP_SPLIT_API,
    key: "anon"
  }
};

function SplitClientProvider({ children }) {
  const imexshopid = useSelector((state) => state.user.imexshopid);
  const splitClient = useSplitClient({ key: imexshopid || "anon" });
  useEffect(() => {
    if (splitClient && imexshopid) {
      console.log(`Split client initialized with key: ${imexshopid}, isReady: ${splitClient.isReady}`);
    }
  }, [splitClient, imexshopid]);
  return children;
}

const mapStateToProps = createStructuredSelector({
  currentUser: selectCurrentUser
});

const mapDispatchToProps = (dispatch) => ({
  setDarkMode: (isDarkMode) => dispatch(setDarkMode(isDarkMode)),
  signOutStart: () => dispatch(signOutStart())
});

function AppContainer({ currentUser, setDarkMode, signOutStart }) {
  const { t } = useTranslation();
  const isDarkMode = useSelector(selectDarkMode);
  const theme = useMemo(() => getTheme(isDarkMode), [isDarkMode]);

  // Global seamless logout listener with redirect to /signin
  useEffect(() => {
    const handleSeamlessLogout = (event) => {
      if (event.data?.type !== "seamlessLogoutRequest") return;

      const requestOrigin = event.origin;

      if (currentUser?.authorized !== true) {
        window.parent.postMessage(
          { type: "seamlessLogoutResponse", status: "already_logged_out" },
          requestOrigin || "*"
        );
        return;
      }

      signOutStart();
      window.parent.postMessage({ type: "seamlessLogoutResponse", status: "logged_out" }, requestOrigin || "*");
    };

    window.addEventListener("message", handleSeamlessLogout);
    return () => {
      window.removeEventListener("message", handleSeamlessLogout);
    };
  }, [signOutStart, currentUser]);

  // Update data-theme attribute
  useEffect(() => {
    document.documentElement.setAttribute("data-theme", isDarkMode ? "dark" : "light");
    return () => document.documentElement.removeAttribute("data-theme");
  }, [isDarkMode]);

  // Sync darkMode with localStorage
  useEffect(() => {
    if (currentUser?.uid) {
      const savedMode = localStorage.getItem(`dark-mode-${currentUser.uid}`);
      if (savedMode !== null) {
        setDarkMode(JSON.parse(savedMode));
      } else {
        setDarkMode(false);
      }
    } else {
      setDarkMode(false);
    }
  }, [currentUser?.uid, setDarkMode]);

  // Persist darkMode
  useEffect(() => {
    if (currentUser?.uid) {
      localStorage.setItem(`dark-mode-${currentUser.uid}`, JSON.stringify(isDarkMode));
    }
  }, [isDarkMode, currentUser?.uid]);

  return (
    <CookiesProvider>
      <ApolloProvider client={client}>
        <ConfigProvider
          input={{ autoComplete: "new-password" }}
          locale={enLocale}
          theme={theme}
          form={{
            validateMessages: {
              required: t("general.validation.required", { label: "${label}" })
            }
          }}
        >
          <GlobalLoadingBar />
          <SplitFactoryProvider config={config}>
            <SplitClientProvider>
              <App />
            </SplitClientProvider>
          </SplitFactoryProvider>
        </ConfigProvider>
      </ApolloProvider>
    </CookiesProvider>
  );
}

export default Sentry.withProfiler(connect(mapStateToProps, mapDispatchToProps)(AppContainer));
