import { ConfigProvider as OldConfigProvider } from 'antd';
import { ConfigContext, ConfigProviderProps } from 'antd/lib/config-provider';
import { Theme } from 'antd/lib/config-provider/context';
import SizeContext from 'antd/lib/config-provider/SizeContext';
import React, { useEffect } from 'react';
import themeSwitcher, { SwitchConfig } from './utils/themeSwitcher';
import dark from './theme/dark';
import light from './theme/light';

type ThemeType = 'dark' | 'light';

interface ConfigProviderExtraProps {
  theme?: ThemeType;
  themeSrc?: { dark?: string; light?: string };
}

type setGlobalConfig = ({
  prefixCls,
  iconPrefixCls,
  theme,
}: Pick<ConfigProviderProps, 'prefixCls' | 'iconPrefixCls'> & {
  theme?: Theme | undefined;
}) => void;

const ConfigProvider: React.FC<
  ConfigProviderProps & ConfigProviderExtraProps
> & {
  ConfigContext: typeof ConfigContext;
  SizeContext: typeof SizeContext;
  config: setGlobalConfig;
  switchTheme: (config: SwitchConfig) => void;
  onThemeChange: (
    themeFn: (theme, themeName: ThemeType) => void,
  ) => MutationObserver;
  getTheme: () => [any, string];
} = (props) => {
  const { themeSrc = {}, theme } = props;
  const {
    dark = `https://btri-dev.midea.com/btri-ui/dark.css`,
    light = `https://btri-dev.midea.com/btri-ui/light.css`,
  } = themeSrc;

  const themeMap = {
    dark,
    light,
  };
  const themeConfig = {
    themeMap,
  };
  const { switcher } = themeSwitcher(themeConfig);
  useEffect(() => {
    theme &&
      switcher({
        theme,
      });
  }, [theme]);
  return <OldConfigProvider {...props}>{props.children}</OldConfigProvider>;
};

ConfigProvider.ConfigContext = OldConfigProvider.ConfigContext;
ConfigProvider.SizeContext = OldConfigProvider.SizeContext;
ConfigProvider.config = OldConfigProvider.config;
ConfigProvider.switchTheme = (
  config: SwitchConfig & { themeSrc?: { dark?: string; light?: string } },
) => {
  const { themeSrc = {} } = config;
  const {
    dark = `https://btri-dev.midea.com/btri-ui/dark.css`,
    light = `https://btri-dev.midea.com/btri-ui/light.css`,
  } = themeSrc;
  const themeMap = {
    dark,
    light,
  };
  const themeConfig = {
    themeMap,
  };
  const { switcher } = themeSwitcher(themeConfig);

  const styleElement = document.getElementById('theme-style');
  const curTheme = styleElement?.className;
  // 如果没有指定主题，并且当前已经有主题了，不做处理
  if (!config.theme && curTheme) {
    return;
  }
  switcher({ ...config, theme: config.theme || curTheme || 'light' });
};

ConfigProvider.onThemeChange = (themeFn) => {
  const styleElement = document.getElementById('theme-style');
  const modes = {
    dark: dark,
    light: light,
  };
  const callThemeFn = (themeName: ThemeType) => {
    const themeObj = modes[themeName];
    const resTheme: any = {};
    Object.keys(themeObj)?.forEach((key) => {
      let value: string = themeObj[key];
      // 递归遍历
      while (value.match(/@/g)) {
        value = value.replace(/(@)([\w|-]*)(,?.*)/g, (match, p1, p2, p3) => {
          return `${themeObj[p1 + p2]}${p3}`;
        });
      }

      resTheme[key] = value;
    });
    themeFn(resTheme, themeName);
  };
  if (!styleElement) {
    const style = document.createElement('link');
    style.type = 'text/css';
    style.rel = 'stylesheet';
    style.id = 'theme-style';
    document.body.append(style);
  }
  if (styleElement?.className) {
    callThemeFn(styleElement.className as ThemeType);
  }

  const observer = new MutationObserver((mutationsList) => {
    // @ts-ignore
    const themeName = mutationsList[0].target.className;
    callThemeFn(themeName);
  });

  observer.observe(document.getElementById('theme-style'), {
    attributes: true,
    attributeFilter: ['href'],
  });
  return observer;
};

ConfigProvider.getTheme = () => {
  const styleElement = document.getElementById('theme-style');
  const themeName = styleElement?.className;
  const modes = {
    dark: dark,
    light: light,
  };
  return [modes[themeName] || {}, themeName];
};
export { ConfigProvider };
