import { useState, useCallback, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useSpaceData } from './hooks/useSpaceData';
import { useHistoricalData } from './hooks/useHistoricalData';
import { useTrajectory } from './hooks/useTrajectory';
import { useScreenshot } from './hooks/useScreenshot';
import { useDataCutoffDate } from './hooks/useDataCutoffDate';
import { Header } from './components/Header';
import { Scene } from './components/Scene';
import { ProbeList } from './components/ProbeList';
import { TimelineController } from './components/TimelineController';
import { Loading } from './components/Loading';
import { InterstellarTicker } from './components/InterstellarTicker';
import { ControlPanel } from './components/ControlPanel';
import { AuthModal } from './components/AuthModal';
import { MessageBoard } from './components/MessageBoard';
import { auth } from './utils/auth';
import type { CelestialBody } from './types';
import { useToast } from './contexts/ToastContext';

// Timeline configuration - will be fetched from backend later
const TIMELINE_DAYS = 30; // Total days in timeline range

const PREFS_KEY = 'cosmo_preferences';

function App() {
  const navigate = useNavigate();
  const toast = useToast();
  
  // Load preferences
  const [isTimelineMode, setIsTimelineMode] = useState(false); // Usually not persisted
  const [showOrbits, setShowOrbits] = useState(true);
  const [isSoundOn, setIsSoundOn] = useState(false);
  const [showMessageBoard, setShowMessageBoard] = useState(false);

  // Initialize state from localStorage
  useEffect(() => {
    const savedPrefs = localStorage.getItem(PREFS_KEY);
    if (savedPrefs) {
      try {
        const prefs = JSON.parse(savedPrefs);
        if (prefs.showOrbits !== undefined) setShowOrbits(prefs.showOrbits);
        if (prefs.isSoundOn !== undefined) setIsSoundOn(prefs.isSoundOn);
      } catch (e) {
        console.error('Failed to parse preferences:', e);
      }
    }
  }, []);

  // Persist preferences
  useEffect(() => {
    const prefs = {
      showOrbits,
      isSoundOn,
    };
    localStorage.setItem(PREFS_KEY, JSON.stringify(prefs));
  }, [showOrbits, isSoundOn]);

  const [selectedDate, setSelectedDate] = useState<Date | null>(null);
  const { takeScreenshot } = useScreenshot();
  const [resetTrigger, setResetTrigger] = useState(0);
  
  // Auth state
  const [user, setUser] = useState<any>(auth.getUser());
  const [showAuthModal, setShowAuthModal] = useState(false);

  // Get data cutoff date
  const { cutoffDate } = useDataCutoffDate();

  // Use real-time data or historical data based on mode
  const { bodies: realTimeBodies, loading: realTimeLoading, error: realTimeError } = useSpaceData();
  const { bodies: historicalBodies, loading: historicalLoading, error: historicalError } = useHistoricalData(selectedDate);

  const bodies = isTimelineMode ? historicalBodies : realTimeBodies;
  const loading = isTimelineMode ? historicalLoading : realTimeLoading;
  const error = isTimelineMode ? historicalError : realTimeError;

  const [selectedBody, setSelectedBody] = useState<CelestialBody | null>(null);
  const { trajectoryPositions } = useTrajectory(selectedBody);

  // Handle time change from timeline controller
  const handleTimeChange = useCallback((date: Date) => {
    setSelectedDate(date);
  }, []);

  // Toggle timeline mode
  const toggleTimelineMode = useCallback(() => {
    setIsTimelineMode((prev) => !prev);
    if (!isTimelineMode) {
      // Entering timeline mode, use cutoff date instead of current date
      setSelectedDate(cutoffDate || new Date());
    } else {
      setSelectedDate(null);
    }
  }, [isTimelineMode, cutoffDate]);

  // Filter probes and planets from all bodies
  const probes = bodies.filter((b) => b.type === 'probe');
  const planets = bodies.filter((b) =>
    b.type === 'planet' || b.type === 'dwarf_planet' || b.type === 'satellite' || b.type === 'comet'
  );

  const handleBodySelect = (body: CelestialBody | null) => {
    setSelectedBody(body);
  };

  // Screenshot handler with auth check
  const handleScreenshot = useCallback(() => {
    if (!user) {
      toast.warning('请先登录以拍摄宇宙快照', 3000, () => {
        setShowAuthModal(true);
      });
      return;
    }
    // Use username or full_name or fallback
    const nickname = user.full_name || user.username || 'Explorer';
    takeScreenshot(nickname);
  }, [user, takeScreenshot, toast]);

  // Auth handlers
  const handleLoginSuccess = (userData: any) => {
    setUser(userData);
    setShowAuthModal(false);
  };

  const handleLogout = () => {
    auth.logout();
    setUser(null);
  };

  // Only show full screen loading when we have no data
  // This prevents flashing when timeline is playing and fetching new data
  if (loading && bodies.length === 0) {
    return <Loading />;
  }

  if (error) {
    return (
      <div className="w-full h-full flex items-center justify-center bg-black text-white">
        <div className="text-center">
          <h1 className="text-2xl font-bold mb-4">数据加载失败</h1>
          <p className="text-red-400">{error}</p>
          <p className="mt-4 text-sm text-gray-400">
            请确保后端 API 运行在 http://localhost:8000
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="w-full h-full relative">
      {/* Header with simplified branding and User Auth */}
      <Header
        bodyCount={bodies.filter(b => b.is_active !== false).length}
        selectedBodyName={selectedBody?.name}
        cutoffDate={cutoffDate}
        user={user}
        onOpenAuth={() => setShowAuthModal(true)}
        onLogout={handleLogout}
        onNavigateToAdmin={() => navigate('/admin')}
      />

      {/* Right Control Panel */}
      <ControlPanel
        isTimelineMode={isTimelineMode}
        onToggleTimeline={toggleTimelineMode}
        showOrbits={showOrbits}
        onToggleOrbits={() => setShowOrbits(!showOrbits)}
        isSoundOn={isSoundOn}
        onToggleSound={() => setIsSoundOn(!isSoundOn)}
        showMessageBoard={showMessageBoard}
        onToggleMessageBoard={() => {
          if (!user) {
            toast.warning('请先登录以访问留言板', 3000, () => {
              setShowAuthModal(true);
            });
          } else {
            setShowMessageBoard(!showMessageBoard);
          }
        }}
        onScreenshot={handleScreenshot}
      />

      {/* Auth Modal */}
      <AuthModal 
        isOpen={showAuthModal} 
        onClose={() => setShowAuthModal(false)} 
        onLoginSuccess={handleLoginSuccess} 
      />

      {/* Message Board */}
      <MessageBoard 
        open={showMessageBoard} 
        onClose={() => setShowMessageBoard(false)} 
      />

      {/* Probe List Sidebar */}
      <ProbeList
        probes={probes}
        planets={planets}
        onBodySelect={handleBodySelect}
        selectedBody={selectedBody}
        onResetCamera={() => setResetTrigger(prev => prev + 1)}
      />

      {/* 3D Scene */}
      <Scene
        bodies={bodies}
        selectedBody={selectedBody}
        trajectoryPositions={trajectoryPositions}
        showOrbits={showOrbits}
        onBodySelect={handleBodySelect}
        resetTrigger={resetTrigger}
        toast={toast}
      />

      {/* Timeline Controller */}
      {isTimelineMode && cutoffDate && (
        <TimelineController
          onTimeChange={handleTimeChange}
          maxDate={cutoffDate} // Use cutoff date instead of new Date()
          minDate={new Date(cutoffDate.getTime() - TIMELINE_DAYS * 24 * 60 * 60 * 1000)} // End point (past)
        />
      )}

      {/* Interstellar Ticker Sound (Controlled) */}
      <InterstellarTicker isPlaying={isSoundOn} />

      {/* Instructions overlay (Only show when exploring freely) */}
      {!selectedBody && (
        <div className="absolute bottom-4 left-1/2 -translate-x-1/2 z-30 text-white text-xs bg-black/50 backdrop-blur-sm border border-white/10 px-4 py-2 rounded-full flex items-center gap-4 pointer-events-none">
          <div className="flex items-center gap-2">
            <span className="bg-white/20 p-1 rounded text-[10px]">左键</span> 旋转
          </div>
          <div className="flex items-center gap-2">
            <span className="bg-white/20 p-1 rounded text-[10px]">右键</span> 平移
          </div>
          <div className="flex items-center gap-2">
            <span className="bg-white/20 p-1 rounded text-[10px]">滚轮</span> 缩放
          </div>
        </div>
      )}
    </div>
  );
}

export default App;
