import { Toaster as Sonner } from '@/components/ui/sonner';
import { Toaster } from '@/components/ui/toaster';
import i18n, { changeLanguageAsync } from '@/locales/config';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { configResponsive } from 'ahooks';
import { ConfigProvider, ConfigProviderProps, theme } from 'antd';
import pt_BR from 'antd/lib/locale/pt_BR';
import arEG from 'antd/locale/ar_EG';
import deDE from 'antd/locale/de_DE';
import enUS from 'antd/locale/en_US';
import ru_RU from 'antd/locale/ru_RU';
import vi_VN from 'antd/locale/vi_VN';
import zhCN from 'antd/locale/zh_CN';
import zh_HK from 'antd/locale/zh_HK';
import dayjs from 'dayjs';
import 'dayjs/locale/ar';
import 'dayjs/locale/zh-cn';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import localeData from 'dayjs/plugin/localeData';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import weekYear from 'dayjs/plugin/weekYear';
import weekday from 'dayjs/plugin/weekday';
import React, { useEffect, useState } from 'react';
import { RouterProvider } from 'react-router';
import { ThemeProvider, useTheme } from './components/theme-provider';
import { TooltipProvider } from './components/ui/tooltip';
import { ThemeEnum } from './constants/common';
import { routers } from './routes';
import storage from './utils/authorization-util';

import 'react-photo-view/dist/react-photo-view.css';

configResponsive({
  sm: 640,
  md: 768,
  lg: 1024,
  xl: 1280,
  '2xl': 1536,
  '3xl': 1780,
  '4xl': 1980,
});

dayjs.extend(customParseFormat);
dayjs.extend(advancedFormat);
dayjs.extend(weekday);
dayjs.extend(localeData);
dayjs.extend(weekOfYear);
dayjs.extend(weekYear);

const AntLanguageMap = {
  en: enUS,
  zh: zhCN,
  'zh-TRADITIONAL': zh_HK,
  ru: ru_RU,
  vi: vi_VN,
  'pt-BR': pt_BR,
  de: deDE,
  ar: arEG,
};

if (process.env.NODE_ENV === 'development') {
  import('@welldone-software/why-did-you-render').then(
    (whyDidYouRenderModule) => {
      const whyDidYouRender = whyDidYouRenderModule.default;
      whyDidYouRender(React, {
        trackAllPureComponents: true,
        trackExtraHooks: [],
        logOnDifferentValues: true,
        exclude: [/^RouterProvider$/],
      });
    },
  );
}

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnWindowFocus: false,
      retry: 2,
    },
  },
});

type Locale = ConfigProviderProps['locale'];

function Root({ children }: React.PropsWithChildren) {
  const { theme: themeragflow } = useTheme();
  const getLocale = (lng: string) =>
    AntLanguageMap[lng as keyof typeof AntLanguageMap] ?? enUS;
  const updateDocumentLocale = (lng: string) => {
    document.documentElement.lang = lng;
    document.documentElement.dir = 'ltr';
    dayjs.locale(lng === 'zh' ? 'zh-cn' : lng);
  };

  const [locale, setLocal] = useState<Locale>(getLocale(storage.getLanguage()));

  useEffect(() => {
    const handleLanguageChanged = (lng: string) => {
      storage.setLanguage(lng);
      setLocal(getLocale(lng));
      updateDocumentLocale(lng);
    };

    updateDocumentLocale(storage.getLanguage() || i18n.language || 'en');
    i18n.on('languageChanged', handleLanguageChanged);

    return () => {
      i18n.off('languageChanged', handleLanguageChanged);
    };
  }, []);
  return (
    <>
      <ConfigProvider
        theme={{
          token: {
            fontFamily:
              "'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif",
          },
          algorithm:
            themeragflow === 'dark'
              ? theme.darkAlgorithm
              : theme.defaultAlgorithm,
        }}
        locale={locale}
        direction={'ltr'}
      >
        {children}

        <Sonner position="top-right" expand richColors closeButton />

        <Toaster />
      </ConfigProvider>
    </>
  );
}

const RootProvider = ({ children }: React.PropsWithChildren) => {
  useEffect(() => {
    const lng = storage.getLanguage();
    if (lng) {
      void changeLanguageAsync(lng);
    }
  }, []);

  return (
    <TooltipProvider>
      <QueryClientProvider client={queryClient}>
        <ThemeProvider
          defaultTheme={ThemeEnum.Dark}
          storageKey="ragflow-ui-theme"
        >
          <Root>{children}</Root>
        </ThemeProvider>
      </QueryClientProvider>
    </TooltipProvider>
  );
};

const RouterProviderWrapper: React.FC<{ router: typeof routers }> = ({
  router,
}) => {
  return <RouterProvider router={router}></RouterProvider>;
};
RouterProviderWrapper.whyDidYouRender = false;

export default function AppContainer() {
  return (
    <RootProvider>
      <RouterProviderWrapper router={routers} />
    </RootProvider>
  );
}
