import { useLayoutEffect, useRef } from 'react';
import { DesignSystemProvider, Select } from '@bitfun/ui';
import { useTranslation } from 'react-i18next';
import { WindowControls } from './components/WindowControls';
import { StepIndicator } from './components/StepIndicator';
import { BitFunAppIcon } from '@bitfun/ui/brand';
import { LanguageSelect } from './pages/LanguageSelect';
import { Options } from './pages/Options';
import { ModelSetup } from './pages/ModelSetup';
import { ProgressPage } from './pages/Progress';
import { ThemeSetup } from './pages/ThemeSetup';
import { UninstallPage } from './pages/Uninstall';
import { useInstaller } from './hooks/useInstaller';
import type { InstallStep } from './types/installer';
import {
  DEFAULT_INSTALLER_UI_LANGUAGE,
  mapUiLanguageToAppLanguage,
  resolveInstallerUiLanguage,
  type InstallerUiLanguage,
} from './i18n/languages';
import { useSyncInstallerRootTheme } from './theme/installerThemeRuntime';
import './styles/global.css';

function App() {
  const installer = useInstaller();
  useSyncInstallerRootTheme(installer.options.themePreference);
  const { t, i18n } = useTranslation();
  const pageRef = useRef<HTMLElement>(null);

  useLayoutEffect(() => {
    const language = resolveInstallerUiLanguage(i18n.resolvedLanguage ?? i18n.language)
      ?? DEFAULT_INSTALLER_UI_LANGUAGE;
    document.documentElement.lang = mapUiLanguageToAppLanguage(language);
  }, [i18n.language]);

  useLayoutEffect(() => {
    pageRef.current?.focus({ preventScroll: true });
  }, [installer.step]);

  const handleLanguageSelect = (lang: InstallerUiLanguage) => {
    i18n.changeLanguage(lang);
    installer.setOptions((prev) => ({
      ...prev,
      appLanguage: mapUiLanguageToAppLanguage(lang),
    }));
    installer.next();
  };

  const renderPage = () => {
    switch (installer.step) {
      case 'lang':
        return <LanguageSelect onSelect={handleLanguageSelect} />;
      case 'options':
        return (
          <Options
            options={installer.options}
            setOptions={installer.setOptions}
            diskSpace={installer.diskSpace}
            error={installer.error}
            refreshDiskSpace={installer.refreshDiskSpace}
            existingInstall={installer.existingInstall}
            onLaunchRegisteredUninstaller={installer.launchRegisteredUninstaller}
            onBack={installer.back}
            onInstall={installer.install}
            isInstalling={installer.isInstalling}
            clearInstallError={installer.clearInstallError}
            previewOnly={installer.previewOnly}
          />
        );
      case 'model':
        return (
          <ModelSetup
            options={installer.options}
            setOptions={installer.setOptions}
            onSkip={installer.next}
            onTestConnection={installer.testModelConnection}
            previewOnly={installer.previewOnly}
            onNext={async () => {
              if (!installer.previewOnly) await installer.saveModelConfig();
              installer.next();
            }}
          />
        );
      case 'progress':
        return (
          <ProgressPage
            progress={installer.progress}
            error={installer.error}
            canConfirmProgress={installer.canConfirmProgress}
            onConfirmProgress={installer.confirmProgress}
            onRetry={installer.retryInstall}
            onBackToOptions={installer.backToOptions}
          />
        );
      case 'theme':
        return (
          <ThemeSetup
            options={installer.options}
            setOptions={installer.setOptions}
            onLaunch={installer.launchApp}
            onClose={installer.closeInstaller}
            previewOnly={installer.previewOnly}
          />
        );
      case 'uninstall':
        return (
          <UninstallPage
            installPath={installer.options.installPath}
            isUninstalling={installer.isUninstalling}
            uninstallCompleted={installer.uninstallCompleted}
            uninstallError={installer.uninstallError}
            uninstallProgress={installer.uninstallProgress}
            onUninstall={installer.startUninstall}
            onClose={installer.closeInstaller}
            previewOnly={installer.previewOnly}
          />
        );
      default:
        return null;
    }
  };

  return (
    <DesignSystemProvider
      locale={i18n.language}
      messages={{ noOptions: t('model.modelNoResults'), selectPlaceholder: t('model.selectProvider') }}
    >
      <div className="installer-app">
        <div className="titlebar" data-tauri-drag-region>
          <div className="titlebar-brand" data-tauri-drag-region>
            <BitFunAppIcon size={16} data-tauri-drag-region />
            <span className="titlebar-title" data-tauri-drag-region>{t('shared.product.name')}</span>
          </div>
          {installer.previewOnly && (
            <div className="installer-preview-controls">
              <span>{t('preview.badge')}</span>
              <Select
                size="sm"
                aria-label={t('preview.page')}
                value={installer.step}
                onValueChange={(value) => installer.goTo(value as InstallStep)}
                options={[
                  { value: 'lang', label: t('steps.language') },
                  { value: 'options', label: t('options.title') },
                  { value: 'progress', label: t('preview.progress') },
                  { value: 'model', label: t('model.title') },
                  { value: 'theme', label: t('themeSetup.title') },
                  { value: 'uninstall', label: t('uninstall.title') },
                ]}
              />
            </div>
          )}
          <WindowControls />
        </div>

        {installer.step !== 'lang' && installer.step !== 'uninstall' && (
          <StepIndicator step={installer.step} />
        )}

        <main className="installer-content" key={installer.step} ref={pageRef} tabIndex={-1}>
          {renderPage()}
        </main>
      </div>
    </DesignSystemProvider>
  );
}

export default App;