import 'package:flutter/foundation.dart';
import '../models/user_credentials.dart';
import '../services/aufe_connection.dart';

/// Authentication state enum
enum AuthState { initial, loading, authenticated, unauthenticated, error }

/// Provider for managing authentication state and user sessions
///
/// Handles login, logout, session checking, and credential management
/// Uses ChangeNotifier to notify listeners of state changes
///
/// Usage example:
/// ```dart
/// final authProvider = Provider.of<AuthProvider>(context);
///
/// // Login
/// await authProvider.login(
///   userId: '学号',
///   ecPassword: 'EC密码',
///   password: 'UAAP密码',
/// );
///
/// // Check session
/// final isValid = await authProvider.checkSession();
///
/// // Logout
/// await authProvider.logout();
/// ```
class AuthProvider extends ChangeNotifier {
  AUFEConnection? _connection;
  AuthState _state = AuthState.initial;
  String? _errorMessage;
  UserCredentials? _credentials;

  /// Get current authentication state
  AuthState get state => _state;

  /// Get current error message (if any)
  String? get errorMessage => _errorMessage;

  /// Get current connection instance
  AUFEConnection? get connection => _connection;

  /// Get current user credentials
  UserCredentials? get credentials => _credentials;

  /// Check if user is authenticated
  bool get isAuthenticated => _state == AuthState.authenticated;

  /// Login with user credentials
  ///
  /// Creates AUFEConnection and performs both EC and UAAP login
  /// Saves credentials securely on successful login
  ///
  /// [userId] - Student ID
  /// [ecPassword] - EC system password
  /// [password] - UAAP system password
  ///
  /// Returns true if login succeeds, false otherwise
  Future<bool> login({
    required String userId,
    required String ecPassword,
    required String password,
  }) async {
    try {
      print('🔐 Starting login process...');
      print('🔐 User ID: $userId');

      _setState(AuthState.loading);
      _errorMessage = null;

      // Create credentials
      final credentials = UserCredentials(
        userId: userId,
        ecPassword: ecPassword,
        password: password,
      );

      // Create connection
      print('🔐 Creating AUFEConnection...');
      final connection = AUFEConnection(
        userId: userId,
        ecPassword: ecPassword,
        password: password,
      );

      // Initialize HTTP client
      print('🔐 Starting HTTP client...');
      connection.startClient();

      // Perform EC login
      print('🔐 Performing EC login...');
      final ecLoginStatus = await connection.ecLogin();
      print('🔐 EC login result: ${ecLoginStatus.success}');

      if (!ecLoginStatus.success) {
        _errorMessage = _getEcLoginErrorMessage(ecLoginStatus);
        print('❌ EC login failed: $_errorMessage');
        _setState(AuthState.error);
        await connection.close();
        return false;
      }

      // Perform UAAP login
      print('🔐 Performing UAAP login...');
      final uaapLoginStatus = await connection.uaapLogin();
      print('🔐 UAAP login result: ${uaapLoginStatus.success}');

      if (!uaapLoginStatus.success) {
        _errorMessage = _getUaapLoginErrorMessage(uaapLoginStatus);
        print('❌ UAAP login failed: $_errorMessage');
        _setState(AuthState.error);
        await connection.close();
        return false;
      }

      // Save credentials securely
      print('🔐 Saving credentials...');
      await credentials.saveSecurely();

      // Update state
      _connection = connection;
      _credentials = credentials;
      _setState(AuthState.authenticated);

      print('✅ Login successful!');
      return true;
    } catch (e, stackTrace) {
      _errorMessage = '登录过程出错: $e';
      print('❌ Login error: $e');
      print('❌ Stack trace: $stackTrace');
      _setState(AuthState.error);
      return false;
    }
  }

  /// Logout and clear all session data
  ///
  /// Closes connection, clears credentials from secure storage,
  /// and resets authentication state
  Future<void> logout() async {
    try {
      // Close connection
      if (_connection != null) {
        await _connection!.close();
        _connection = null;
      }

      // Clear credentials from secure storage
      await UserCredentials.clearSecurely();

      // Reset state
      _credentials = null;
      _errorMessage = null;
      _setState(AuthState.unauthenticated);
    } catch (e) {
      debugPrint('Error during logout: $e');
      // Still reset state even if cleanup fails
      _connection = null;
      _credentials = null;
      _setState(AuthState.unauthenticated);
    }
  }

  /// Check if current session is still valid
  ///
  /// Performs health check on the connection
  /// If session is invalid, updates state to unauthenticated
  ///
  /// Returns true if session is valid, false otherwise
  Future<bool> checkSession() async {
    if (_connection == null || _state != AuthState.authenticated) {
      _setState(AuthState.unauthenticated);
      return false;
    }

    try {
      final isHealthy = await _connection!.healthCheck();

      if (!isHealthy) {
        _errorMessage = '会话已过期，请重新登录';
        _setState(AuthState.unauthenticated);
        return false;
      }

      return true;
    } catch (e) {
      _errorMessage = '检查会话状态失败: $e';
      _setState(AuthState.error);
      return false;
    }
  }

  /// Attempt to restore session from saved credentials
  ///
  /// Loads credentials from secure storage and attempts to login
  /// Useful for auto-login on app startup
  ///
  /// Returns true if session restored successfully, false otherwise
  Future<bool> restoreSession() async {
    try {
      _setState(AuthState.loading);

      // Load saved credentials
      final credentials = await UserCredentials.loadSecurely();
      if (credentials == null) {
        _setState(AuthState.unauthenticated);
        return false;
      }

      // Attempt login with saved credentials
      return await login(
        userId: credentials.userId,
        ecPassword: credentials.ecPassword,
        password: credentials.password,
      );
    } catch (e) {
      _errorMessage = '恢复会话失败: $e';
      _setState(AuthState.unauthenticated);
      return false;
    }
  }

  /// Update authentication state and notify listeners
  void _setState(AuthState newState) {
    _state = newState;
    notifyListeners();
  }

  /// Get user-friendly error message for EC login status
  String _getEcLoginErrorMessage(dynamic status) {
    if (status.failInvalidCredentials) {
      return 'EC系统用户名或密码错误';
    } else if (status.failNotFoundTwfid) {
      return '无法获取TwfID，请稍后重试';
    } else if (status.failNotFoundRsaKey) {
      return '无法获取RSA密钥，请稍后重试';
    } else if (status.failNotFoundRsaExp) {
      return '无法获取RSA指数，请稍后重试';
    } else if (status.failNotFoundCsrfCode) {
      return '无法获取CSRF代码，请稍后重试';
    } else if (status.failMaybeAttacked) {
      return '登录频繁，请稍后重试';
    } else if (status.failNetworkError) {
      return 'EC系统网络连接失败';
    } else {
      return 'EC系统登录失败';
    }
  }

  /// Get user-friendly error message for UAAP login status
  String _getUaapLoginErrorMessage(dynamic status) {
    if (status.failInvalidCredentials) {
      return 'UAAP系统用户名或密码错误';
    } else if (status.failNotFoundLt) {
      return '无法获取lt参数，请稍后重试';
    } else if (status.failNotFoundExecution) {
      return '无法获取execution参数，请稍后重试';
    } else if (status.failNetworkError) {
      return 'UAAP系统网络连接失败';
    } else {
      return 'UAAP系统登录失败';
    }
  }

  @override
  void dispose() {
    // Close connection when provider is disposed
    _connection?.close();
    super.dispose();
  }
}
