// src/App.tsx
import React, { useState, useCallback, useEffect } from 'react';
import { Routes, Route, useParams, useLocation } from 'react-router-dom'; 
import { Toaster } from 'react-hot-toast';
import * as pdfjsLib from 'pdfjs-dist';
import { Header } from './components/Header';
import { logger } from './services/logger.client'; 
import type { Flyer, Profile, User } 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 { ResetPasswordPage } from './pages/ResetPasswordPage';
import { VoiceLabPage } from './pages/VoiceLabPage';
import { WhatsNewModal } from './components/WhatsNewModal';
import { FlyerCorrectionTool } from './components/FlyerCorrectionTool';
import { QuestionMarkCircleIcon } from './components/icons/QuestionMarkCircleIcon';
import { useAuth } from './hooks/useAuth';
import { useFlyers } from './hooks/useFlyers'; // Assuming useFlyers fetches all flyers
import { useFlyerItems } from './hooks/useFlyerItems'; // Import the new hook for flyer items
import { useModal } from './hooks/useModal';
import { MainLayout } from './layouts/MainLayout';
import config from './config';
import { HomePage } from './pages/HomePage';

// 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();

function App() {
  const { user, profile, authStatus, login, logout, updateProfile } = useAuth();
  const { flyers } = useFlyers();
  const [selectedFlyer, setSelectedFlyer] = useState<Flyer | null>(null);
  const { openModal, closeModal, isModalOpen } = useModal();
  const location = useLocation();
  const params = useParams<{ flyerId?: string }>();

  const [isDarkMode, setIsDarkMode] = useState(false);
  const { flyerItems } = useFlyerItems(selectedFlyer);
  const [unitSystem, setUnitSystem] = useState<'metric' | 'imperial'>('imperial');

  const handleDataExtractedFromCorrection = (type: 'store_name' | 'dates', value: string) => {
    if (!selectedFlyer) return;

    // This is a simplified update. A real implementation would involve
    // making another API call to update the flyer record in the database.
    // For now, we just update the local state for immediate visual feedback.
    const updatedFlyer = { ...selectedFlyer };
    if (type === 'store_name') {
      updatedFlyer.store = { ...updatedFlyer.store!, name: value };
    } else if (type === 'dates') {
      // A more robust solution would parse the date string properly.
    }
    setSelectedFlyer(updatedFlyer);
  };

  const handleProfileUpdate = (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);
  };

  // --- State Synchronization and Error Handling ---

  // Effect to set initial theme based on user profile, local storage, or system preference
  useEffect(() => {
    if (profile && profile.preferences?.darkMode !== undefined) {
        // Preference from DB
        const dbDarkMode = profile.preferences.darkMode;
        setIsDarkMode(dbDarkMode);
        document.documentElement.classList.toggle('dark', dbDarkMode);
    } else {
        // Fallback to local storage or system preference
        const savedMode = localStorage.getItem('darkMode');
        const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
        const initialDarkMode = savedMode !== null ? savedMode === 'true' : prefersDark;
        setIsDarkMode(initialDarkMode);
        document.documentElement.classList.toggle('dark', initialDarkMode);
    }
  }, [profile]);

  // Effect to set initial unit system based on user profile or local storage
  useEffect(() => {
    if (profile && profile.preferences?.unitSystem) {
        setUnitSystem(profile.preferences.unitSystem);
    } else {
        const savedSystem = localStorage.getItem('unitSystem') as 'metric' | 'imperial' | null;
        if (savedSystem) {
            setUnitSystem(savedSystem);
        }
    }
  }, [profile]);

  // This is the login handler that will be passed to the ProfileManager component.
  const handleLoginSuccess = async (loggedInUser: User, token: string) => {
    try {
      await login(loggedInUser, token);
      // After successful login, fetch user-specific data
      // The useData hook will automatically refetch user data when `user` changes.
      // We can remove the explicit fetch here.
    } 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.');
    }
  };

  // Effect to handle the token from Google OAuth redirect
  useEffect(() => {
    const urlParams = new URLSearchParams(location.search);
    const googleToken = urlParams.get('googleAuthToken');

    if (googleToken) {
      logger.info('Received Google Auth token from URL. Authenticating...');
      // The login flow is now handled by the useAuth hook. We just need to trigger it.
      // We can't know the user object yet, so we'll let the login function fetch it.
      // A dummy user object is passed, the real one will be set inside login().
      login({ user_id: '', email: '' }, googleToken)
        .catch(err => logger.error('Failed to log in with Google token', { error: err }));
      // Clean the token from the URL
      window.history.replaceState({}, document.title, "/");
    }

    const githubToken = urlParams.get('githubAuthToken');
    if (githubToken) {
      logger.info('Received GitHub Auth token from URL. Authenticating...');
      // Same logic as for Google
      login({ user_id: '', email: '' }, githubToken)
        .catch(err => {
          logger.error('Failed to log in with GitHub token', { error: err });
          // Optionally, redirect to a page with an error message
          // navigate('/login?error=github_auth_failed');
        });
      
      // Clean the token from the URL
      window.history.replaceState({}, document.title, "/");
    }
  }, [login, location.search]);


  const handleFlyerSelect = useCallback(async (flyer: Flyer) => {
    setSelectedFlyer(flyer);
  }, []);

  useEffect(() => {
    if (!selectedFlyer && flyers.length > 0) {
      handleFlyerSelect(flyers[0]);
    }
  }, [flyers, selectedFlyer, handleFlyerSelect]);

  // New effect to handle routing to a specific flyer ID from the URL
  useEffect(() => {
    const flyerIdFromUrl = params.flyerId;

    if (flyerIdFromUrl && flyers.length > 0) {
      const flyerId = parseInt(flyerIdFromUrl, 10);
      const flyerToSelect = flyers.find(f => f.flyer_id === flyerId);
      if (flyerToSelect && flyerToSelect.flyer_id !== selectedFlyer?.flyer_id) {
        handleFlyerSelect(flyerToSelect);
      }
    };
  }, [flyers, handleFlyerSelect, selectedFlyer, params.flyerId]);

    // 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;
  const commitMessage = config.app.commitMessage;
  useEffect(() => {
    if (appVersion) {
      logger.info(`Application version: ${appVersion}`);
      const lastSeenVersion = localStorage.getItem('lastSeenVersion');
      // If the current version is new, show the "What's New" modal.
      if (appVersion !== lastSeenVersion) {
        openModal('whatsNew');
        localStorage.setItem('lastSeenVersion', appVersion);
      }
    }
  }, [appVersion]);

  return (
    <div className="bg-gray-100 dark:bg-gray-950 min-h-screen font-sans text-gray-800 dark:text-gray-200">
      {/* Toaster component for displaying notifications. It's placed at the top level. */}
      <Toaster position="top-center" reverseOrder={false} />
      {/* Add CSS variables for toast theming based on dark mode */}
      <style>{`
        :root {
          --toast-bg: ${isDarkMode ? '#4B5563' : '#FFFFFF'};
          --toast-color: ${isDarkMode ? '#F9FAFB' : '#1F2937'};
        }
      `}</style>


      <Header 
        isDarkMode={isDarkMode} // Still pass for display, but toggling happens in ProfileManager
        // toggleDarkMode removed
        unitSystem={unitSystem} // Still pass for display
        // toggleUnitSystem removed
        profile={profile}
        authStatus={authStatus}
        user={user}
        onOpenProfile={() => openModal('profile')}
        onOpenVoiceAssistant={() => openModal('voiceAssistant')} 
        onSignOut={logout}
      />

      {/* The ProfileManager is now always available to be opened, handling both login and profile management. */}
      <ProfileManager
          isOpen={isModalOpen('profile')}
          onClose={() => closeModal('profile')}
          user={user}
          authStatus={authStatus}
          profile={profile}
          onProfileUpdate={handleProfileUpdate}
          onLoginSuccess={handleLoginSuccess}
          onSignOut={logout} // Pass the signOut handler
      />
      {user && (
          <VoiceAssistant 
              isOpen={isModalOpen('voiceAssistant')}
              onClose={() => closeModal('voiceAssistant')}
          />
      )}

      {/* "What's New" modal, shown automatically on new versions */}
      {appVersion && commitMessage && (
        <WhatsNewModal
          isOpen={isModalOpen('whatsNew')}
          onClose={() => closeModal('whatsNew')}
          version={appVersion}
          commitMessage={commitMessage}
        />
      )}

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

      <Routes>
        {/* Layout Route for main application view */}
        <Route element={
          <MainLayout 
            onFlyerSelect={handleFlyerSelect} 
            selectedFlyerId={selectedFlyer?.flyer_id || null}
            onOpenProfile={() => openModal('profile')} // Pass the profile opener function
          />
        }>
          <Route index element={
            <HomePage selectedFlyer={selectedFlyer} flyerItems={flyerItems} onOpenCorrectionTool={() => openModal('correctionTool')} />
          } />
          <Route path="/flyers/:flyerId" element={
            <HomePage selectedFlyer={selectedFlyer} flyerItems={flyerItems} onOpenCorrectionTool={() => openModal('correctionTool')} />
          } />
        </Route>

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

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

      {/* Display the build version number at the bottom-left of the screen */}
      {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={() => openModal('whatsNew')} 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>
      )}
    </div>
  );
}

export default App;