import { ApolloProvider } from "@apollo/client/react";
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 { useDispatch, useSelector } from "react-redux";
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 (import.meta.env.DEV && splitClient && imexshopid) {
      console.log(`Split client initialized with key: ${imexshopid}, isReady: ${splitClient.isReady}`);
    }
  }, [splitClient, imexshopid]);

  return children;
}

function AppContainer() {
  const { t } = useTranslation();
  const dispatch = useDispatch();

  const currentUser = useSelector(selectCurrentUser);
  const isDarkMode = useSelector(selectDarkMode);

  const theme = useMemo(() => getTheme(isDarkMode), [isDarkMode]);

  const antdInput = useMemo(() => ({ autoComplete: "new-password" }), []);

  const antdForm = useMemo(
    () => ({
      validateMessages: {
        required: t("general.validation.required", { label: "${label}" })
      }
    }),
    [t]
  );

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

      // Only accept messages from the parent window
      if (event.source !== window.parent) return;

      const targetOrigin = event.origin || "*";

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

      dispatch(signOutStart());
      window.parent?.postMessage({ type: "seamlessLogoutResponse", status: "logged_out" }, targetOrigin);
    };

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

  // Update data-theme attribute (no cleanup to avoid transient style churn)
  useEffect(() => {
    document.documentElement.dataset.theme = isDarkMode ? "dark" : "light";
  }, [isDarkMode]);

  // Sync darkMode with localStorage
  useEffect(() => {
    const uid = currentUser?.uid;

    if (!uid) {
      dispatch(setDarkMode(false));
      return;
    }

    const key = `dark-mode-${uid}`;
    const raw = localStorage.getItem(key);

    if (raw == null) {
      dispatch(setDarkMode(false));
      return;
    }

    try {
      dispatch(setDarkMode(Boolean(JSON.parse(raw))));
    } catch {
      dispatch(setDarkMode(false));
    }
  }, [currentUser?.uid, dispatch]);

  // Persist darkMode
  useEffect(() => {
    const uid = currentUser?.uid;
    if (!uid) return;

    localStorage.setItem(`dark-mode-${uid}`, JSON.stringify(isDarkMode));
  }, [isDarkMode, currentUser?.uid]);

  return (
    <CookiesProvider>
      <ApolloProvider client={client}>
        <ConfigProvider input={antdInput} locale={enLocale} theme={theme} form={antdForm}>
          <GlobalLoadingBar />
          <SplitFactoryProvider config={config}>
            <SplitClientProvider>
              <App />
            </SplitClientProvider>
          </SplitFactoryProvider>
        </ConfigProvider>
      </ApolloProvider>
    </CookiesProvider>
  );
}

export default Sentry.withProfiler(AppContainer);
