// src/App.tsx
import React, { useCallback, useEffect } from 'react';
import { Routes, Route } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import * as pdfjsLib from 'pdfjs-dist';
import { Footer } from './components/Footer';
import { Header } from './components/Header';
import { logger } from './services/logger.client';
import type { Profile, UserProfile } from './types';
import { ProfileManager } from './pages/admin/components/ProfileManager';
import { VoiceAssistant } from './features/voice-assistant/VoiceAssistant';
import { AdminPage } from './pages/admin/AdminPage';
import { AdminRoute } from './components/AdminRoute';
import { CorrectionsPage } from './pages/admin/CorrectionsPage';
import { AdminStatsPage } from './pages/admin/AdminStatsPage';
import { FlyerReviewPage } from './pages/admin/FlyerReviewPage';
import { ResetPasswordPage } from './pages/ResetPasswordPage';
import { VoiceLabPage } from './pages/VoiceLabPage';
import { FlyerCorrectionTool } from './components/FlyerCorrectionTool';
import { QuestionMarkCircleIcon } from './components/icons/QuestionMarkCircleIcon';
import { useAuth } from './hooks/useAuth';
import { useFlyers } from './hooks/useFlyers';
import { useFlyerItems } from './hooks/useFlyerItems';
import { useModal } from './hooks/useModal';
import { useFlyerSelection } from './hooks/useFlyerSelection';
import { useDataExtraction } from './hooks/useDataExtraction';
import { MainLayout } from './layouts/MainLayout';
import config from './config';
import { HomePage } from './pages/HomePage';
import { AppGuard } from './components/AppGuard';
import { useAppInitialization } from './hooks/useAppInitialization';

// pdf.js worker configuration
// This is crucial for allowing pdf.js to process PDFs in a separate thread, preventing the UI from freezing.
// We need to explicitly tell pdf.js where to load its worker script from.
// By importing pdfjs-dist, we can host the worker locally, which is more reliable.
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.mjs',
  import.meta.url,
).toString();

// Create a client
const queryClient = new QueryClient();

function App() {
  const { userProfile, authStatus, login, logout, updateProfile } = useAuth();
  const { flyers } = useFlyers();
  const { openModal, closeModal, isModalOpen } = useModal();

  // Use custom hook for flyer selection logic (auto-select, URL-based selection)
  const { selectedFlyer, handleFlyerSelect, flyerIdFromUrl } = useFlyerSelection({
    flyers,
  });

  // This hook now handles initialization effects (OAuth, version check, theme)
  // and returns the theme/unit state needed by other components.
  const { isDarkMode, unitSystem } = useAppInitialization();

  // Use custom hook for data extraction from correction tool
  const { handleDataExtracted } = useDataExtraction({
    selectedFlyer,
    onFlyerUpdate: handleFlyerSelect,
  });

  // Debugging: Log renders to identify infinite loops (only in test environment)
  useEffect(() => {
    if (process.env.NODE_ENV === 'test') {
      logger.debug(
        {
          flyersCount: flyers.length,
          selectedFlyerId: selectedFlyer?.flyer_id,
          flyerIdFromUrl,
          authStatus,
          profileId: userProfile?.user.user_id,
        },
        '[App] Render',
      );
    }
  });

  const { flyerItems } = useFlyerItems(selectedFlyer);

  // Modal handlers
  const handleOpenProfile = useCallback(() => openModal('profile'), [openModal]);
  const handleCloseProfile = useCallback(() => closeModal('profile'), [closeModal]);

  const handleOpenVoiceAssistant = useCallback(() => openModal('voiceAssistant'), [openModal]);
  const handleCloseVoiceAssistant = useCallback(() => closeModal('voiceAssistant'), [closeModal]);

  const handleOpenWhatsNew = useCallback(() => openModal('whatsNew'), [openModal]);

  const handleOpenCorrectionTool = useCallback(() => openModal('correctionTool'), [openModal]);
  const handleCloseCorrectionTool = useCallback(() => closeModal('correctionTool'), [closeModal]);

  const handleProfileUpdate = useCallback(
    (updatedProfileData: Profile) => {
      // When the profile is updated, the API returns a `Profile` object.
      // We need to merge it with the existing `user` object to maintain
      // the `UserProfile` type in our state.
      updateProfile(updatedProfileData);
    },
    [updateProfile],
  );

  // This is the login handler that will be passed to the ProfileManager component.
  const handleLoginSuccess = useCallback(
    async (userProfile: UserProfile, token: string, _rememberMe: boolean) => {
      try {
        await login(token, userProfile);
        // After successful login, fetch user-specific data
        // The useData hook will automatically refetch user data when `user` changes.
      } catch (e) {
        // The `login` function within the `useAuth` hook already handles its own errors
        // and notifications, so we just need to log any unexpected failures here.
        logger.error({ err: e }, 'An error occurred during the login success handling.');
      }
    },
    [login],
  );

  // Read the application version injected at build time.
  // This will only be available in the production build, not during local development.
  const appVersion = config.app.version;

  return (
    // AppGuard now handles the main page wrapper, theme styles, and "What's New" modal
    <AppGuard>
      <Header
        isDarkMode={isDarkMode}
        unitSystem={unitSystem}
        userProfile={userProfile}
        authStatus={authStatus}
        onOpenProfile={handleOpenProfile}
        onOpenVoiceAssistant={handleOpenVoiceAssistant}
        onSignOut={logout}
      />

      <ProfileManager
        isOpen={isModalOpen('profile')}
        onClose={handleCloseProfile}
        authStatus={authStatus}
        userProfile={userProfile}
        onProfileUpdate={handleProfileUpdate}
        onLoginSuccess={handleLoginSuccess}
        onSignOut={logout}
      />
      {userProfile && (
        <VoiceAssistant
          isOpen={isModalOpen('voiceAssistant')}
          onClose={handleCloseVoiceAssistant}
        />
      )}

      {selectedFlyer && (
        <FlyerCorrectionTool
          isOpen={isModalOpen('correctionTool')}
          onClose={handleCloseCorrectionTool}
          imageUrl={selectedFlyer.image_url}
          onDataExtracted={handleDataExtracted}
        />
      )}

      <Routes>
        <Route
          element={
            <MainLayout
              onFlyerSelect={handleFlyerSelect}
              selectedFlyerId={selectedFlyer?.flyer_id || null}
              onOpenProfile={handleOpenProfile}
            />
          }
        >
          <Route
            index
            element={
              <HomePage
                selectedFlyer={selectedFlyer}
                flyerItems={flyerItems}
                onOpenCorrectionTool={handleOpenCorrectionTool}
              />
            }
          />
          <Route
            path="/flyers/:flyerId"
            element={
              <HomePage
                selectedFlyer={selectedFlyer}
                flyerItems={flyerItems}
                onOpenCorrectionTool={handleOpenCorrectionTool}
              />
            }
          />
        </Route>

        {/* Admin Routes */}
        <Route element={<AdminRoute profile={userProfile} />}>
          <Route path="/admin" element={<AdminPage />} />
          <Route path="/admin/corrections" element={<CorrectionsPage />} />
          <Route path="/admin/stats" element={<AdminStatsPage />} />
          <Route path="/admin/flyer-review" element={<FlyerReviewPage />} />
          <Route path="/admin/voice-lab" element={<VoiceLabPage />} />
        </Route>
        <Route path="/reset-password/:token" element={<ResetPasswordPage />} />

        {/* Add other top-level routes here if needed */}
      </Routes>

      {appVersion && (
        <div className="fixed bottom-2 left-3 z-50 flex items-center space-x-2">
          <a
            href={config.app.commitUrl || '#'}
            target="_blank"
            rel="noopener noreferrer"
            title="View commit details on Gitea"
            className="text-xs text-gray-400 dark:text-gray-600 bg-gray-100 dark:bg-gray-950 px-2 py-1 rounded hover:text-brand-primary dark:hover:text-brand-primary transition-colors"
          >
            Version: {appVersion}
          </a>
          <button onClick={handleOpenWhatsNew} title="Show what's new in this version">
            <QuestionMarkCircleIcon className="w-5 h-5 text-gray-400 dark:text-gray-600 hover:text-brand-primary dark:hover:text-brand-primary transition-colors" />
          </button>
        </div>
      )}

      <Footer />
    </AppGuard>
  );
}

const WrappedApp = () => (
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>
);

export default WrappedApp;
