
import React, { useState, useEffect, useRef } from 'react';
import { Sidebar } from './components/Sidebar';
import { Header } from './components/Header';
import { Login } from './pages/Login';
import { User, UserRole } from './types';
import { api } from './services/api';
import { AlertTriangle, Loader2 } from 'lucide-react';
import { LiveAssistant } from './components/LiveAssistant';

// --- Page Loading Component ---
const PageLoading = () => (
  <div className="flex h-full w-full items-center justify-center min-h-[400px]">
    <div className="flex flex-col items-center space-y-3">
       <Loader2 className="h-8 w-8 animate-spin text-blue-600" />
       <p className="text-sm text-gray-400">正在加载资源...</p>
    </div>
  </div>
);

// --- Manual Async Component Helper (Replaces React.lazy) ---
// This avoids Suspense getting stuck by managing loading state explicitly.
const lazyLoad = (importFn: () => Promise<any>, name: string) => {
  return (props: any) => {
    const [Component, setComponent] = useState<React.ComponentType<any> | null>(null);
    const [error, setError] = useState<Error | null>(null);
    const mountedRef = useRef(true);

    useEffect(() => {
        mountedRef.current = true;
        
        importFn()
            .then(module => {
                if (!mountedRef.current) return;
                // Support both named export (priority) and default export
                const Comp = module[name] || module.default;
                if (Comp) {
                    // Use callback to set function component to state
                    setComponent(() => Comp);
                } else {
                    throw new Error(`Export "${name}" not found in module.`);
                }
            })
            .catch(err => {
                if (!mountedRef.current) return;
                console.error(`Error loading page ${name}:`, err);
                setError(err);
                // Retry logic for chunks could go here, but usually reload is best
                if (err.message && (err.message.includes('fetch') || err.message.includes('chunk'))) {
                     console.warn('Chunk load error, suggesting reload.');
                }
            });

        return () => { mountedRef.current = false; };
    }, []);

    if (error) {
        return (
            <div className="flex flex-col items-center justify-center h-full text-red-500 gap-4">
                <p>页面加载失败: {error.message}</p>
                <button onClick={() => window.location.reload()} className="px-4 py-2 bg-blue-600 text-white rounded">刷新页面</button>
            </div>
        );
    }

    if (!Component) return <PageLoading />;

    return <Component {...props} />;
  };
};

// Lazy load pages using the manual helper
const Dashboard = lazyLoad(() => import('./pages/Dashboard'), 'Dashboard');
const StudentList = lazyLoad(() => import('./pages/StudentList'), 'StudentList');
const CourseList = lazyLoad(() => import('./pages/CourseList'), 'CourseList');
const ScoreList = lazyLoad(() => import('./pages/ScoreList'), 'ScoreList');
const ClassList = lazyLoad(() => import('./pages/ClassList'), 'ClassList');
const Settings = lazyLoad(() => import('./pages/Settings'), 'Settings');
const Reports = lazyLoad(() => import('./pages/Reports'), 'Reports');
const SubjectList = lazyLoad(() => import('./pages/SubjectList'), 'SubjectList');
const UserList = lazyLoad(() => import('./pages/UserList'), 'UserList');
const SchoolList = lazyLoad(() => import('./pages/SchoolList'), 'SchoolList');
const Games = lazyLoad(() => import('./pages/Games'), 'Games');
const AttendancePage = lazyLoad(() => import('./pages/Attendance'), 'AttendancePage');
const Profile = lazyLoad(() => import('./pages/Profile'), 'Profile');
const WishesAndFeedback = lazyLoad(() => import('./pages/WishesAndFeedback'), 'WishesAndFeedback');
const AIAssistant = lazyLoad(() => import('./pages/AIAssistant'), 'AIAssistant');
const MyClass = lazyLoad(() => import('./pages/MyClass'), 'MyClass');

class ErrorBoundary extends React.Component<{children: React.ReactNode}, {hasError: boolean, error: Error | null}> {
  constructor(props: any) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error: Error) {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error("Uncaught error:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return (
        <div className="min-h-screen flex items-center justify-center bg-gray-50 p-4">
          <div className="bg-white p-8 rounded-xl shadow-lg max-w-lg w-full text-center">
            <div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-red-100 mb-4">
              <AlertTriangle className="h-8 w-8 text-red-600" />
            </div>
            <h2 className="text-2xl font-bold text-gray-900 mb-2">页面运行遇到问题</h2>
            <p className="text-gray-500 mb-6">请尝试刷新页面。</p>
            <button onClick={() => window.location.reload()} className="w-full px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium">刷新页面</button>
          </div>
        </div>
      );
    }
    return this.props.children;
  }
}

const AppContent: React.FC = () => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  const [currentView, setCurrentView] = useState('dashboard');
  const [loading, setLoading] = useState(true);
  const [sidebarOpen, setSidebarOpen] = useState(false);

  // --- Auto-Update Logic ---
  useEffect(() => {
    // 1. Force reload page when Service Worker updates (controller change)
    // This happens automatically due to 'registerType: autoUpdate' in vite config,
    // but the window needs to reload to use the new SW.
    const handleControllerChange = () => {
        console.log("🔄 App updated, reloading...");
        window.location.reload();
    };

    // 2. Check for updates on visibility change (e.g. user comes back to tab)
    const checkForUpdates = () => {
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.ready.then(registration => {
                registration.update();
            }).catch(() => {});
        }
    };

    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.addEventListener('controllerchange', handleControllerChange);
        document.addEventListener('visibilitychange', () => {
            if (document.visibilityState === 'visible') {
                checkForUpdates();
            }
        });
        // Initial check
        checkForUpdates();
    }

    return () => {
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.removeEventListener('controllerchange', handleControllerChange);
        }
    };
  }, []);

  useEffect(() => {
    const initApp = async () => {
        api.init();
        let storedUser = api.auth.getCurrentUser();
        
        if (storedUser) {
            try {
                const refreshedUser = await api.auth.refreshSession();
                if (refreshedUser) storedUser = refreshedUser;
            } catch (e) {
                console.warn('Session refresh failed');
            }
            setCurrentUser(storedUser);
            setIsAuthenticated(true);
        }
        setLoading(false);
    };
    initApp();
  }, []);

  const handleLogin = (user: User) => {
    setCurrentUser(user);
    setIsAuthenticated(true);
    setCurrentView('dashboard');
  };

  const handleLogout = () => {
    api.auth.logout();
    setIsAuthenticated(false);
    setCurrentUser(null);
  };

  const renderContent = () => {
    switch (currentView) {
      case 'dashboard': return <Dashboard onNavigate={(view: string) => setCurrentView(view)} />;
      case 'students': return <StudentList />;
      case 'classes': return <ClassList />;
      case 'courses': return <CourseList />;
      case 'grades': return <ScoreList />;
      case 'settings': return <Settings />;
      case 'reports': return <Reports />;
      case 'subjects': return <SubjectList />;
      case 'users': return <UserList />;
      case 'schools': return <SchoolList />; 
      case 'games': return <Games />; 
      case 'attendance': return <AttendancePage />;
      case 'wishes': return <WishesAndFeedback />;
      case 'ai-assistant': return <AIAssistant />;
      case 'profile': return <Profile />;
      case 'my-class': return <MyClass />;
      default: return <Dashboard onNavigate={(view: string) => setCurrentView(view)} />;
    }
  };

  const viewTitles: Record<string, string> = {
    dashboard: '工作台',
    students: '学生档案管理',
    classes: '班级管理',
    courses: '课程安排',
    grades: '成绩管理',
    settings: '系统设置',
    reports: '统计报表',
    subjects: '学科设置',
    users: '用户权限管理',
    schools: '学校维度管理',
    games: '互动教学中心',
    attendance: '考勤管理',
    wishes: '心愿与反馈',
    'ai-assistant': 'AI 智能助教',
    profile: '个人中心',
    'my-class': '我的班级 (班主任)'
  };

  if (loading) return <div className="min-h-screen flex items-center justify-center bg-gray-50 text-blue-600">加载中...</div>;

  if (!isAuthenticated) return <Login onLogin={handleLogin} />;

  const showLiveAssistant = currentUser && (currentUser.role === UserRole.ADMIN || currentUser.aiAccess);

  // Layout Logic:
  // For 'ai-assistant' and 'games', we want full height without internal padding from Main, 
  // so the component can manage its own scroll/flex layout (sticky headers/footers).
  // For other pages, we use the standard scrolling Main container.
  const isAppLikePage = currentView === 'ai-assistant' || currentView === 'games';
  
  const mainClasses = isAppLikePage
    ? "flex-1 overflow-hidden relative bg-slate-50 w-full" 
    : "flex-1 overflow-x-hidden overflow-y-auto bg-gray-50 p-4 md:p-6 w-full relative";

  return (
    // Fixed inset-0 prevents body scroll, everything happens inside
    <div className="fixed inset-0 flex bg-gray-50 overflow-hidden">
      <Sidebar
        currentView={currentView}
        onChangeView={(view) => { setCurrentView(view); setSidebarOpen(false); }}
        userRole={(currentUser?.role as UserRole) || UserRole.USER}
        onLogout={handleLogout}
        isOpen={sidebarOpen}
        onClose={() => setSidebarOpen(false)}
      />
      
      <div className="flex-1 flex flex-col w-full relative h-full min-w-0">
        <Header user={currentUser!} title={viewTitles[currentView] || '智慧校园'} onMenuClick={() => setSidebarOpen(true)}/>
        
        <main className={mainClasses}>
          {isAppLikePage ? (
             renderContent()
          ) : (
             <div className="max-w-7xl mx-auto w-full min-h-full">
               {renderContent()}
             </div>
          )}
        </main>
        
        {showLiveAssistant && <LiveAssistant />}
      </div>
    </div>
  );
};

const App: React.FC = () => {
  return (
    <ErrorBoundary>
      <AppContent />
    </ErrorBoundary>
  );
};

export default App;
