import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/auth_provider.dart';
import 'providers/evaluation_provider.dart';
import 'providers/theme_provider.dart';
import 'services/notification_service.dart';
import 'screens/login_screen.dart';
import 'screens/home_screen.dart';
import 'widgets/loading_indicator.dart';
import 'utils/error_handler.dart';
import 'utils/app_logger.dart';

void main() async {
  // Run app with global error handling
  await ErrorHandler.runAppWithErrorHandling(() async {
    WidgetsFlutterBinding.ensureInitialized();

    // Initialize logger
    final logger = AppLogger();
    logger.initialize();
    logger.info('Application starting...');

    // Initialize notification service
    final notificationService = NotificationService();
    await notificationService.initialize();

    runApp(MyApp(notificationService: notificationService));
  });
}

class MyApp extends StatelessWidget {
  final NotificationService notificationService;

  const MyApp({super.key, required this.notificationService});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ThemeProvider()),
        ChangeNotifierProvider(create: (_) => AuthProvider()),
        ChangeNotifierProxyProvider<AuthProvider, EvaluationProvider>(
          create: (context) {
            // Create initial provider without connection
            // Connection will be set later when user logs in
            return EvaluationProvider(
              service: null,
              notificationService: notificationService,
            );
          },
          update: (context, authProvider, previous) {
            // Keep the same provider instance and just update connection
            if (previous != null) {
              previous.setConnection(authProvider.connection);
              return previous;
            }
            return EvaluationProvider(
              service: null,
              notificationService: notificationService,
            );
          },
        ),
      ],
      child: Consumer<ThemeProvider>(
        builder: (context, themeProvider, child) {
          // Use MiSans font on Windows platform
          final fontFamily = Platform.isWindows ? 'MiSans' : null;

          return MaterialApp(
            title: '自动评教系统',
            debugShowCheckedModeBanner: false,
            theme: themeProvider.lightTheme.copyWith(
              textTheme: themeProvider.lightTheme.textTheme.apply(
                fontFamily: fontFamily,
              ),
            ),
            darkTheme: themeProvider.darkTheme.copyWith(
              textTheme: themeProvider.darkTheme.textTheme.apply(
                fontFamily: fontFamily,
              ),
            ),
            themeMode: themeProvider.themeMode,
            home: const AppInitializer(),
          );
        },
      ),
    );
  }
}

/// App initializer widget
///
/// Handles initial app setup and session restoration
class AppInitializer extends StatefulWidget {
  const AppInitializer({super.key});

  @override
  State<AppInitializer> createState() => _AppInitializerState();
}

class _AppInitializerState extends State<AppInitializer> {
  bool _isInitializing = true;
  bool _hasSession = false;

  @override
  void initState() {
    super.initState();
    // Defer initialization until after the first frame
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _initialize();
    });
  }

  Future<void> _initialize() async {
    final authProvider = Provider.of<AuthProvider>(context, listen: false);

    // Try to restore session
    final restored = await authProvider.restoreSession();

    if (mounted) {
      setState(() {
        _isInitializing = false;
        _hasSession = restored;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    if (_isInitializing) {
      return const Scaffold(body: LoadingIndicator(message: '正在初始化...'));
    }

    return _hasSession ? const HomeScreen() : const LoginScreen();
  }
}
