import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

/// 错误类型枚举
enum ErrorType {
  network,
  authentication,
  validation,
  server,
  unknown,
}

/// 错误严重程度枚举
enum ErrorSeverity {
  info,
  warning,
  error,
  critical,
}

/// 应用错误模型
class AppError {
  final String id;
  final String message;
  final String? details;
  final ErrorType type;
  final ErrorSeverity severity;
  final DateTime timestamp;
  final String? stackTrace;
  final Map<String, dynamic>? context;

  const AppError({
    required this.id,
    required this.message,
    this.details,
    required this.type,
    required this.severity,
    required this.timestamp,
    this.stackTrace,
    this.context,
  });

  AppError copyWith({
    String? id,
    String? message,
    String? details,
    ErrorType? type,
    ErrorSeverity? severity,
    DateTime? timestamp,
    String? stackTrace,
    Map<String, dynamic>? context,
  }) {
    return AppError(
      id: id ?? this.id,
      message: message ?? this.message,
      details: details ?? this.details,
      type: type ?? this.type,
      severity: severity ?? this.severity,
      timestamp: timestamp ?? this.timestamp,
      stackTrace: stackTrace ?? this.stackTrace,
      context: context ?? this.context,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is AppError &&
        other.id == id &&
        other.message == message &&
        other.type == type &&
        other.severity == severity;
  }

  @override
  int get hashCode {
    return id.hashCode ^
        message.hashCode ^
        type.hashCode ^
        severity.hashCode;
  }

  @override
  String toString() {
    return 'AppError(id: $id, message: $message, type: $type, severity: $severity, timestamp: $timestamp)';
  }

  /// 创建网络错误
  factory AppError.network(String message, {String? details, Map<String, dynamic>? context}) {
    return AppError(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      message: message,
      details: details,
      type: ErrorType.network,
      severity: ErrorSeverity.error,
      timestamp: DateTime.now(),
      context: context,
    );
  }

  /// 创建认证错误
  factory AppError.authentication(String message, {String? details, Map<String, dynamic>? context}) {
    return AppError(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      message: message,
      details: details,
      type: ErrorType.authentication,
      severity: ErrorSeverity.error,
      timestamp: DateTime.now(),
      context: context,
    );
  }

  /// 创建验证错误
  factory AppError.validation(String message, {String? details, Map<String, dynamic>? context}) {
    return AppError(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      message: message,
      details: details,
      type: ErrorType.validation,
      severity: ErrorSeverity.warning,
      timestamp: DateTime.now(),
      context: context,
    );
  }

  /// 创建服务器错误
  factory AppError.server(String message, {String? details, Map<String, dynamic>? context}) {
    return AppError(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      message: message,
      details: details,
      type: ErrorType.server,
      severity: ErrorSeverity.error,
      timestamp: DateTime.now(),
      context: context,
    );
  }

  /// 创建未知错误
  factory AppError.unknown(String message, {String? details, String? stackTrace, Map<String, dynamic>? context}) {
    return AppError(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      message: message,
      details: details,
      type: ErrorType.unknown,
      severity: ErrorSeverity.error,
      timestamp: DateTime.now(),
      stackTrace: stackTrace,
      context: context,
    );
  }
}

/// 错误状态模型
class ErrorState {
  final List<AppError> errors;
  final AppError? currentError;

  const ErrorState({
    required this.errors,
    this.currentError,
  });

  bool get hasErrors => errors.isNotEmpty;

  ErrorState copyWith({
    List<AppError>? errors,
    AppError? currentError,
  }) {
    return ErrorState(
      errors: errors ?? this.errors,
      currentError: currentError,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is ErrorState &&
        other.errors.length == errors.length &&
        other.currentError == currentError;
  }

  @override
  int get hashCode {
    return errors.hashCode ^ currentError.hashCode;
  }
}

/// 错误管理Provider
class ErrorNotifier extends StateNotifier<ErrorState> {
  static const int maxErrorCount = 50; // 最大错误数量
  static const Duration errorRetentionDuration = Duration(hours: 24); // 错误保留时间

  ErrorNotifier() : super(const ErrorState(errors: []));

  /// 添加错误
  void addError(AppError error) {
    final updatedErrors = List<AppError>.from(state.errors);
    updatedErrors.insert(0, error); // 新错误插入到列表开头

    // 限制错误数量
    if (updatedErrors.length > maxErrorCount) {
      updatedErrors.removeRange(maxErrorCount, updatedErrors.length);
    }

    // 清理过期错误
    _cleanExpiredErrors(updatedErrors);

    state = state.copyWith(
      errors: updatedErrors,
      currentError: error,
    );

    // 在调试模式下打印错误
    if (kDebugMode) {
      print('Error added: ${error.toString()}');
      if (error.stackTrace != null) {
        print('Stack trace: ${error.stackTrace}');
      }
    }
  }

  /// 清除当前错误
  void clearCurrentError() {
    state = state.copyWith(currentError: null);
  }

  /// 清除指定错误
  void removeError(String errorId) {
    final updatedErrors = state.errors.where((error) => error.id != errorId).toList();
    
    AppError? newCurrentError = state.currentError;
    if (state.currentError?.id == errorId) {
      newCurrentError = null;
    }

    state = state.copyWith(
      errors: updatedErrors,
      currentError: newCurrentError,
    );
  }

  /// 清除所有错误
  void clearAllErrors() {
    state = const ErrorState(errors: []);
  }

  /// 清除指定类型的错误
  void clearErrorsByType(ErrorType type) {
    final updatedErrors = state.errors.where((error) => error.type != type).toList();
    
    AppError? newCurrentError = state.currentError;
    if (state.currentError?.type == type) {
      newCurrentError = null;
    }

    state = state.copyWith(
      errors: updatedErrors,
      currentError: newCurrentError,
    );
  }

  /// 清除指定严重程度的错误
  void clearErrorsBySeverity(ErrorSeverity severity) {
    final updatedErrors = state.errors.where((error) => error.severity != severity).toList();
    
    AppError? newCurrentError = state.currentError;
    if (state.currentError?.severity == severity) {
      newCurrentError = null;
    }

    state = state.copyWith(
      errors: updatedErrors,
      currentError: newCurrentError,
    );
  }

  /// 获取指定类型的错误
  List<AppError> getErrorsByType(ErrorType type) {
    return state.errors.where((error) => error.type == type).toList();
  }

  /// 获取指定严重程度的错误
  List<AppError> getErrorsBySeverity(ErrorSeverity severity) {
    return state.errors.where((error) => error.severity == severity).toList();
  }

  /// 获取最近的错误
  List<AppError> getRecentErrors({int count = 10}) {
    return state.errors.take(count).toList();
  }

  /// 检查是否有指定类型的错误
  bool hasErrorOfType(ErrorType type) {
    return state.errors.any((error) => error.type == type);
  }

  /// 检查是否有指定严重程度的错误
  bool hasErrorOfSeverity(ErrorSeverity severity) {
    return state.errors.any((error) => error.severity == severity);
  }

  /// 清理过期错误
  void _cleanExpiredErrors(List<AppError> errors) {
    final now = DateTime.now();
    errors.removeWhere((error) => 
        now.difference(error.timestamp) > errorRetentionDuration);
  }

  /// 处理异常并转换为AppError
  void handleException(dynamic exception, {
    String? message,
    ErrorType? type,
    ErrorSeverity? severity,
    Map<String, dynamic>? context,
  }) {
    String errorMessage = message ?? exception.toString();
    ErrorType errorType = type ?? ErrorType.unknown;
    ErrorSeverity errorSeverity = severity ?? ErrorSeverity.error;
    String? stackTrace;

    if (exception is Error) {
      stackTrace = exception.stackTrace?.toString();
    }

    final error = AppError(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      message: errorMessage,
      details: exception.toString(),
      type: errorType,
      severity: errorSeverity,
      timestamp: DateTime.now(),
      stackTrace: stackTrace,
      context: context,
    );

    addError(error);
  }
}

/// 错误状态Provider
final errorProvider = StateNotifierProvider<ErrorNotifier, ErrorState>(
  (ref) => ErrorNotifier(),
);

/// 当前错误Provider
final currentErrorProvider = Provider<AppError?>(
  (ref) => ref.watch(errorProvider).currentError,
);

/// 是否有错误Provider
final hasErrorsProvider = Provider<bool>(
  (ref) => ref.watch(errorProvider).hasErrors,
);

/// 错误数量Provider
final errorCountProvider = Provider<int>(
  (ref) => ref.watch(errorProvider).errors.length,
);

/// 网络错误Provider
final networkErrorsProvider = Provider<List<AppError>>(
  (ref) => ref.watch(errorProvider).errors
      .where((error) => error.type == ErrorType.network)
      .toList(),
);

/// 认证错误Provider
final authErrorsProvider = Provider<List<AppError>>(
  (ref) => ref.watch(errorProvider).errors
      .where((error) => error.type == ErrorType.authentication)
      .toList(),
);

/// 严重错误Provider
final criticalErrorsProvider = Provider<List<AppError>>(
  (ref) => ref.watch(errorProvider).errors
      .where((error) => error.severity == ErrorSeverity.critical)
      .toList(),
);