class ReadingStats {
  final int totalArticlesRead;
  final int practicesDone;
  final double averageScore;
  final int totalReadingTime; // in minutes
  final double averageReadingSpeed; // words per minute
  final double comprehensionAccuracy; // percentage
  final int vocabularyMastered;
  final int consecutiveDays;
  final Map<String, int> categoryStats; // category -> articles read
  final Map<String, double> difficultyStats; // difficulty -> average score
  final List<DailyReadingRecord> dailyRecords;

  const ReadingStats({
    required this.totalArticlesRead,
    required this.practicesDone,
    required this.averageScore,
    required this.totalReadingTime,
    required this.averageReadingSpeed,
    required this.comprehensionAccuracy,
    required this.vocabularyMastered,
    required this.consecutiveDays,
    required this.categoryStats,
    required this.difficultyStats,
    required this.dailyRecords,
  });

  factory ReadingStats.fromJson(Map<String, dynamic> json) {
    final totalArticlesRead = json['totalArticlesRead'];
    final practicesDone = json['practicesDone'];
    final averageScore = json['averageScore'];
    final totalReadingTime = json['totalReadingTime'];
    final averageReadingSpeed = json['averageReadingSpeed'];
    final comprehensionAccuracy = json['comprehensionAccuracy'];
    final vocabularyMastered = json['vocabularyMastered'];
    final consecutiveDays = json['consecutiveDays'];

    final rawCategoryStats = json['categoryStats'];
    final Map<String, int> categoryStats = {};
    if (rawCategoryStats is Map) {
      rawCategoryStats.forEach((key, value) {
        final k = key is String ? key : key.toString();
        final v = value is num ? value.toInt() : 0;
        categoryStats[k] = v;
      });
    }

    final rawDifficultyStats = json['difficultyStats'];
    final Map<String, double> difficultyStats = {};
    if (rawDifficultyStats is Map) {
      rawDifficultyStats.forEach((key, value) {
        final k = key is String ? key : key.toString();
        final v = value is num ? value.toDouble() : 0.0;
        difficultyStats[k] = v;
      });
    }

    final rawDailyRecords = json['dailyRecords'];
    final List<DailyReadingRecord> dailyRecords = [];
    if (rawDailyRecords is List) {
      for (final record in rawDailyRecords) {
        if (record is Map<String, dynamic>) {
          dailyRecords.add(DailyReadingRecord.fromJson(record));
        }
      }
    }

    return ReadingStats(
      totalArticlesRead: totalArticlesRead is num ? totalArticlesRead.toInt() : 0,
      practicesDone: practicesDone is num ? practicesDone.toInt() : 0,
      averageScore: averageScore is num ? averageScore.toDouble() : 0.0,
      totalReadingTime: totalReadingTime is num ? totalReadingTime.toInt() : 0,
      averageReadingSpeed: averageReadingSpeed is num ? averageReadingSpeed.toDouble() : 0.0,
      comprehensionAccuracy: comprehensionAccuracy is num ? comprehensionAccuracy.toDouble() : 0.0,
      vocabularyMastered: vocabularyMastered is num ? vocabularyMastered.toInt() : 0,
      consecutiveDays: consecutiveDays is num ? consecutiveDays.toInt() : 0,
      categoryStats: categoryStats,
      difficultyStats: difficultyStats,
      dailyRecords: dailyRecords,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'totalArticlesRead': totalArticlesRead,
      'practicesDone': practicesDone,
      'averageScore': averageScore,
      'totalReadingTime': totalReadingTime,
      'averageReadingSpeed': averageReadingSpeed,
      'comprehensionAccuracy': comprehensionAccuracy,
      'vocabularyMastered': vocabularyMastered,
      'consecutiveDays': consecutiveDays,
      'categoryStats': categoryStats,
      'difficultyStats': difficultyStats,
      'dailyRecords': dailyRecords.map((record) => record.toJson()).toList(),
    };
  }

  ReadingStats copyWith({
    int? totalArticlesRead,
    int? practicesDone,
    double? averageScore,
    int? totalReadingTime,
    double? averageReadingSpeed,
    double? comprehensionAccuracy,
    int? vocabularyMastered,
    int? consecutiveDays,
    Map<String, int>? categoryStats,
    Map<String, double>? difficultyStats,
    List<DailyReadingRecord>? dailyRecords,
  }) {
    return ReadingStats(
      totalArticlesRead: totalArticlesRead ?? this.totalArticlesRead,
      practicesDone: practicesDone ?? this.practicesDone,
      averageScore: averageScore ?? this.averageScore,
      totalReadingTime: totalReadingTime ?? this.totalReadingTime,
      averageReadingSpeed: averageReadingSpeed ?? this.averageReadingSpeed,
      comprehensionAccuracy: comprehensionAccuracy ?? this.comprehensionAccuracy,
      vocabularyMastered: vocabularyMastered ?? this.vocabularyMastered,
      consecutiveDays: consecutiveDays ?? this.consecutiveDays,
      categoryStats: categoryStats ?? this.categoryStats,
      difficultyStats: difficultyStats ?? this.difficultyStats,
      dailyRecords: dailyRecords ?? this.dailyRecords,
    );
  }

  String get readingTimeFormatted {
    final hours = totalReadingTime ~/ 60;
    final minutes = totalReadingTime % 60;
    if (hours > 0) {
      return '${hours}小时${minutes}分钟';
    }
    return '${minutes}分钟';
  }

  String get averageScoreFormatted {
    return '${averageScore.toStringAsFixed(1)}分';
  }

  String get comprehensionAccuracyFormatted {
    return '${comprehensionAccuracy.toStringAsFixed(1)}%';
  }

  String get averageReadingSpeedFormatted {
    return '${averageReadingSpeed.toStringAsFixed(0)}词/分钟';
  }
}

class DailyReadingRecord {
  final DateTime date;
  final int articlesRead;
  final int practicesDone;
  final int readingTime; // in minutes
  final double averageScore;
  final int vocabularyLearned;

  const DailyReadingRecord({
    required this.date,
    required this.articlesRead,
    required this.practicesDone,
    required this.readingTime,
    required this.averageScore,
    required this.vocabularyLearned,
  });

  factory DailyReadingRecord.fromJson(Map<String, dynamic> json) {
    final dateRaw = json['date'];
    final articlesRead = json['articlesRead'];
    final practicesDone = json['practicesDone'];
    final readingTime = json['readingTime'];
    final averageScore = json['averageScore'];
    final vocabularyLearned = json['vocabularyLearned'];

    return DailyReadingRecord(
      date: dateRaw is String ? DateTime.parse(dateRaw) : DateTime.fromMillisecondsSinceEpoch(0),
      articlesRead: articlesRead is num ? articlesRead.toInt() : 0,
      practicesDone: practicesDone is num ? practicesDone.toInt() : 0,
      readingTime: readingTime is num ? readingTime.toInt() : 0,
      averageScore: averageScore is num ? averageScore.toDouble() : 0.0,
      vocabularyLearned: vocabularyLearned is num ? vocabularyLearned.toInt() : 0,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'date': date.toIso8601String(),
      'articlesRead': articlesRead,
      'practicesDone': practicesDone,
      'readingTime': readingTime,
      'averageScore': averageScore,
      'vocabularyLearned': vocabularyLearned,
    };
  }

  DailyReadingRecord copyWith({
    DateTime? date,
    int? articlesRead,
    int? practicesDone,
    int? readingTime,
    double? averageScore,
    int? vocabularyLearned,
  }) {
    return DailyReadingRecord(
      date: date ?? this.date,
      articlesRead: articlesRead ?? this.articlesRead,
      practicesDone: practicesDone ?? this.practicesDone,
      readingTime: readingTime ?? this.readingTime,
      averageScore: averageScore ?? this.averageScore,
      vocabularyLearned: vocabularyLearned ?? this.vocabularyLearned,
    );
  }
}

class ReadingProgress {
  final String category;
  final int totalArticles;
  final int completedArticles;
  final double averageScore;
  final String difficulty;

  const ReadingProgress({
    required this.category,
    required this.totalArticles,
    required this.completedArticles,
    required this.averageScore,
    required this.difficulty,
  });

  factory ReadingProgress.fromJson(Map<String, dynamic> json) {
    return ReadingProgress(
      category: json['category'] as String,
      totalArticles: json['totalArticles'] as int,
      completedArticles: json['completedArticles'] as int,
      averageScore: (json['averageScore'] as num).toDouble(),
      difficulty: json['difficulty'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'category': category,
      'totalArticles': totalArticles,
      'completedArticles': completedArticles,
      'averageScore': averageScore,
      'difficulty': difficulty,
    };
  }

  double get progressPercentage {
    if (totalArticles == 0) return 0.0;
    return (completedArticles / totalArticles) * 100;
  }

  String get progressText {
    return '$completedArticles/$totalArticles';
  }

  String get categoryLabel {
    switch (category.toLowerCase()) {
      case 'cet4':
        return '四级阅读';
      case 'cet6':
        return '六级阅读';
      case 'toefl':
        return '托福阅读';
      case 'ielts':
        return '雅思阅读';
      case 'daily':
        return '日常阅读';
      case 'business':
        return '商务阅读';
      case 'academic':
        return '学术阅读';
      case 'news':
        return '新闻阅读';
      default:
        return category;
    }
  }
}