import { useState, useEffect, ReactNode } from 'react';
import { useLaunch } from '@tarojs/taro';
import { IntlProvider } from 'react-intl';
import { ConfigProvider } from 'antd';
import { Provider } from 'react-redux';
import store, { useAppDispatch, useAppSelector } from './states/store';
import { initializeProductState } from './states/productSlice';
import { loadI18nMessages } from './states/i18nSlice';
import './app.css';
import ProductSelector from './components/ProductSelector';
import ThemeSwitcher from './components/ThemeSwitcher';
import QuotaAlertModal from './pages/security/QuotaAlertModal';
import AcquisitionTracer from './pages/exam/components/acquisitionTracer';
import FeatureNotAvailableFeedback from './components/FeatureNotAvailableFeedback';
import { setFeatureNotAvailableOpen } from './states/featureNotAvailableSlice';
import { setBusinessFlow } from './states/BusinessFlowSlice';
import { logger } from './log/logger';
console.log = logger.log;
console.warn = logger.warn;
console.error = logger.error;
console.log(`process.env.USE_MSW: ${process.env.USE_MSW}`);
console.log(`process.env.NODE_ENV: ${process.env.NODE_ENV}`);

if (process.env.NODE_ENV === 'development' && process.env.USE_MSW === 'true') {
  import('../mocks/server')
    .then(({ server }): void => {
      server.start({
        onUnhandledRequest: 'error', // 未处理的请求触发网络错误
      });
      console.log(`启动了MSW`);
    })
    .catch((err): void => {
      console.warn('Mock server module not found:', err);
    });
}

function AppContent({ children }: { children: ReactNode }): JSX.Element {
  const dispatch = useAppDispatch();
  const { messages, loading, error, currentLocale } = useAppSelector(
    (state) => state.i18n
  );
  const isFeatureNotAvailableOpen = useAppSelector(
    (state) => state.featureNotAvailable.isOpen
  );
  const { currentTheme, themeType } = useAppSelector((state) => state.theme);
  const [isI18nReady, setIsI18nReady] = useState(false);

  useLaunch((): void => {
    console.log('App launched.');
  });

  useEffect(() => {
    // 先加载软件信息获取语言设置
    store
      .dispatch(initializeProductState())
      .unwrap()
      .then((productState) => {
        console.log(`初始化，拉取到产品信息：${JSON.stringify(productState)}`);
        // 从 current_locale 提取语言代码
        const languageCode = productState.language;

        return dispatch(loadI18nMessages(languageCode)).unwrap();
      })
      .then(() => {
        setIsI18nReady(true);
      })
      .catch((error) => {
        console.error('初始化失败:', error);
        // 阻止加载后面的页面
        setIsI18nReady(false);
      });
  }, [dispatch]);

  console.log('当前语言:', currentLocale);
  console.log('messages', messages);
  
  // children 是将要会渲染的页面
  // IntlProvider 始终存在，使用默认值避免 useIntl 报错
  return (
    <ConfigProvider theme={currentTheme}>
      <IntlProvider
        locale={currentLocale ? currentLocale.split('_')[0] : 'en'} // en_US -> en，提供默认值
        messages={(messages as Record<string, string>) || {}} // 提供空对象作为默认值
      >
        <style>
          {/*把theme中的colorPrimary转换成变量--color-primary，变量被tailwindcss使用*/}
          {`:root {
            --color-primary: ${currentTheme.token.colorPrimary};
            --color-bg-layout: ${currentTheme.token.colorBgLayout};
            --color-text: ${currentTheme.token.colorText};
            --button-bg-hover: ${currentTheme.token.buttonBgHover};
          }`}
        </style>
        
        {/* 加载状态覆盖层 */}
        {(loading || !isI18nReady) && (
          <div
            style={{
              position: 'fixed',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              zIndex: 9999,
              display: 'flex',
              justifyContent: 'center',
              alignItems: 'center',
              backgroundColor: currentTheme.token.colorBgLayout,
              color: currentTheme.token.colorText,
            }}
          >
            <div>加载多语言资源中...</div>
          </div>
        )}
        
        {/* 错误状态覆盖层 */}
        {error && (
          <div
            style={{
              position: 'fixed',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              zIndex: 9999,
              display: 'flex',
              justifyContent: 'center',
              alignItems: 'center',
              flexDirection: 'column',
              backgroundColor: currentTheme.token.colorBgLayout,
              color: currentTheme.token.colorText,
            }}
          >
            <div>多语言资源加载失败: {error}</div>
            <button
              onClick={() => window.location.reload()}
              style={{ marginTop: '16px', padding: '8px 16px' }}
            >
              重新加载
            </button>
          </div>
        )}
        
        {/* children 始终被渲染，满足 Taro 框架要求 */}
        <div
          style={{
            backgroundColor: currentTheme.token.colorBgLayout,
            color: currentTheme.token.colorText,
            borderRadius: '8px',
            boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
          }}
        >
          <AcquisitionTracer />
          <QuotaAlertModal />
          <FeatureNotAvailableFeedback
            open={isFeatureNotAvailableOpen}
            onClose={() => dispatch(setFeatureNotAvailableOpen(false))}
            onContinue={() => {
              dispatch(setFeatureNotAvailableOpen(false));
              dispatch(setBusinessFlow('continueAfterFeatureNotAvailable'));
            }}
          />
          {children}
          {process.env.NODE_ENV === 'development' && <ProductSelector />}
          <ThemeSwitcher />
        </div>
      </IntlProvider>
    </ConfigProvider>
  );
}

function App({ children }: { children: ReactNode }): JSX.Element {
  // 只在 Cypress 测试环境下暴露 store 到 window 对象
  if (
    typeof window !== 'undefined' &&
    (window as unknown as { Cypress: unknown }).Cypress
  ) {
    (window as unknown as { store: typeof store }).store = store;
  }

  return (
    <Provider store={store}>
      <AppContent>{children}</AppContent>
    </Provider>
  );
}

export default App;
