import { RootState } from '@/app/store';
import globalMessage from '@/components/message';
import { Locale, Theme } from '@/enum';
import * as langs from '@/langs';
import * as themes from '@/themes';
import { CSSVariablesStyle } from '@/themes/CSSVariablesStyle';
import { ConfigProvider } from '@df/toco-ui';
import { Store } from '@reduxjs/toolkit';
import { message as tocoMessage } from 'antd';
import enUS from 'antd/locale/en_US';
import zhCN from 'antd/locale/zh_CN';
import React, { useEffect, useMemo } from 'react';
import { HelmetProvider } from 'react-helmet-async';
import { IntlProvider } from 'react-intl';
import { Provider, useSelector } from 'react-redux';

const helmetContext = {};

type AppWrapperProps = {
  children: React.ReactNode;
  store: Store;
};
const AppWrapper = (props: AppWrapperProps) => {
  const { children, store } = props;
  return (
    <Provider store={store}>
      <Insider>{children}</Insider>
    </Provider>
  );
};

type InsiderProps = {
  children: React.ReactNode;
};
const Insider = (props: InsiderProps) => {
  const { children } = props;
  const [message, messageContextHolder] = tocoMessage.useMessage();

  const locale = useSelector((state: RootState) => state.common.locale);
  const theme = useSelector((state: RootState) => state.common.theme);
  const primaryColor = useSelector(
    (state: RootState) => state.common.primaryColor,
  );

  const antdLocaleMap = {
    [Locale.zh_CN]: zhCN,
    [Locale.en_US]: enUS,
  };
  const langsMap = {
    [Locale.zh_CN]: langs.zh_CN,
    [Locale.en_US]: langs.en_US,
  };

  const themeConfig = useMemo(() => {
    const themeMap = {
      [Theme.DEFAULT]: themes.defaultTheme,
      [Theme.DARK]: themes.darkTheme,
    };
    const config = themeMap[theme];
    if (primaryColor) {
      return {
        ...config,
        token: {
          ...(config.token ?? {}),
          colorPrimary: primaryColor,
        },
      };
    }
    return config;
  }, [primaryColor, theme]);

  useEffect(() => {
    globalMessage.setMessage(message);
  }, [message]);

  return (
    <HelmetProvider context={helmetContext}>
      <IntlProvider locale={locale} messages={langsMap[locale]}>
        <ConfigProvider locale={antdLocaleMap[locale]} theme={themeConfig}>
          <CSSVariablesStyle />
          {messageContextHolder}
          {children}
        </ConfigProvider>
      </IntlProvider>
    </HelmetProvider>
  );
};

export default AppWrapper;
