/// 對話場景模型
class DialogueScene {
  final String id;
  final String name;
  final String description;
  final String backgroundImageUrl;
  final String characterId;
  final String difficultyLevel;
  final List<String> tags;
  final Map<String, dynamic> metadata;

  DialogueScene({
    required this.id,
    required this.name,
    required this.description,
    required this.backgroundImageUrl,
    required this.characterId,
    required this.difficultyLevel,
    this.tags = const [],
    this.metadata = const {},
  });

  factory DialogueScene.fromJson(Map<String, dynamic> json) {
    return DialogueScene(
      id: json['id'] as String,
      name: json['name'] as String,
      description: json['description'] as String,
      backgroundImageUrl: json['backgroundImageUrl'] as String,
      characterId: json['characterId'] as String,
      difficultyLevel: json['difficultyLevel'] as String,
      tags: List<String>.from(json['tags'] ?? []),
      metadata: json['metadata'] as Map<String, dynamic>? ?? {},
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'description': description,
      'backgroundImageUrl': backgroundImageUrl,
      'characterId': characterId,
      'difficultyLevel': difficultyLevel,
      'tags': tags,
      'metadata': metadata,
    };
  }
}

/// 對話角色模型
class DialogueCharacter {
  final String id;
  final String name;
  final String description;
  final String avatarUrl;
  final String personality;
  final String role;
  final String background;
  final List<String> specialities;
  final Map<String, String> localizedNames;

  DialogueCharacter({
    required this.id,
    required this.name,
    required this.description,
    required this.avatarUrl,
    required this.personality,
    required this.role,
    required this.background,
    this.specialities = const [],
    this.localizedNames = const {},
  });

  factory DialogueCharacter.fromJson(Map<String, dynamic> json) {
    return DialogueCharacter(
      id: json['id'] as String,
      name: json['name'] as String,
      description: json['description'] as String,
      avatarUrl: json['avatarUrl'] as String,
      personality: json['personality'] as String,
      role: json['role'] as String,
      background: json['background'] as String,
      specialities: List<String>.from(json['specialities'] ?? []),
      localizedNames: Map<String, String>.from(json['localizedNames'] ?? {}),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'description': description,
      'avatarUrl': avatarUrl,
      'personality': personality,
      'role': role,
      'background': background,
      'specialities': specialities,
      'localizedNames': localizedNames,
    };
  }
}

/// 對話消息模型
class DialogueMessage {
  final String id;
  final String content;
  final bool isUser;
  final DateTime timestamp;
  final DialogueMessageType type;
  final Map<String, dynamic>? metadata;
  final String? audioUrl;
  final double? confidence;

  DialogueMessage({
    required this.id,
    required this.content,
    required this.isUser,
    required this.timestamp,
    this.type = DialogueMessageType.text,
    this.metadata,
    this.audioUrl,
    this.confidence,
  });

  factory DialogueMessage.fromJson(Map<String, dynamic> json) {
    return DialogueMessage(
      id: json['id'] as String,
      content: json['content'] as String,
      isUser: json['isUser'] as bool,
      timestamp: DateTime.parse(json['timestamp'] as String),
      type: DialogueMessageType.values.firstWhere(
        (e) => e.toString() == 'DialogueMessageType.${json['type']}',
        orElse: () => DialogueMessageType.text,
      ),
      metadata: json['metadata'] as Map<String, dynamic>?,
      audioUrl: json['audioUrl'] as String?,
      confidence: json['confidence'] as double?,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'content': content,
      'isUser': isUser,
      'timestamp': timestamp.toIso8601String(),
      'type': type.toString().split('.').last,
      'metadata': metadata,
      'audioUrl': audioUrl,
      'confidence': confidence,
    };
  }
}

/// 對話消息類型
enum DialogueMessageType {
  text,
  audio,
  system,
  hint,
}

/// 對話任務模型
class DialogueTask {
  final String id;
  final String title;
  final String description;
  final DialogueTaskType type;
  final Map<String, dynamic> requirements;
  final double progress;
  final bool isCompleted;
  final int maxAttempts;
  final int currentAttempts;
  final String? completionMessage;

  DialogueTask({
    required this.id,
    required this.title,
    required this.description,
    required this.type,
    required this.requirements,
    this.progress = 0.0,
    this.isCompleted = false,
    this.maxAttempts = 3,
    this.currentAttempts = 0,
    this.completionMessage,
  });

  factory DialogueTask.fromJson(Map<String, dynamic> json) {
    return DialogueTask(
      id: json['id'] as String,
      title: json['title'] as String,
      description: json['description'] as String,
      type: DialogueTaskType.values.firstWhere(
        (e) => e.toString() == 'DialogueTaskType.${json['type']}',
        orElse: () => DialogueTaskType.conversation,
      ),
      requirements: json['requirements'] as Map<String, dynamic>,
      progress: json['progress'] as double? ?? 0.0,
      isCompleted: json['isCompleted'] as bool? ?? false,
      maxAttempts: json['maxAttempts'] as int? ?? 3,
      currentAttempts: json['currentAttempts'] as int? ?? 0,
      completionMessage: json['completionMessage'] as String?,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'description': description,
      'type': type.toString().split('.').last,
      'requirements': requirements,
      'progress': progress,
      'isCompleted': isCompleted,
      'maxAttempts': maxAttempts,
      'currentAttempts': currentAttempts,
      'completionMessage': completionMessage,
    };
  }

  DialogueTask copyWith({
    String? id,
    String? title,
    String? description,
    DialogueTaskType? type,
    Map<String, dynamic>? requirements,
    double? progress,
    bool? isCompleted,
    int? maxAttempts,
    int? currentAttempts,
    String? completionMessage,
  }) {
    return DialogueTask(
      id: id ?? this.id,
      title: title ?? this.title,
      description: description ?? this.description,
      type: type ?? this.type,
      requirements: requirements ?? this.requirements,
      progress: progress ?? this.progress,
      isCompleted: isCompleted ?? this.isCompleted,
      maxAttempts: maxAttempts ?? this.maxAttempts,
      currentAttempts: currentAttempts ?? this.currentAttempts,
      completionMessage: completionMessage ?? this.completionMessage,
    );
  }
}

/// 對話任務類型
enum DialogueTaskType {
  conversation,    // 完成對話
  vocabulary,      // 使用指定詞彙
  grammar,         // 語法練習
  pronunciation,   // 發音練習
  comprehension,   // 理解測試
}

/// 對話分析結果模型
class DialogueAnalysis {
  final String id;
  final String userReply;
  final DateTime timestamp;
  
  // 三維度評分
  final double grammarScore;
  final double semanticsScore;
  final double fluencyScore;
  
  // 詳細分析
  final List<GrammarIssue> grammarIssues;
  final List<String> usedVocabulary;
  final List<String> missedVocabulary;
  final List<String> suggestions;
  
  // 任務相關
  final double? taskProgress;
  final bool isDialogueComplete;
  
  // 其他
  final Map<String, dynamic> metadata;

  DialogueAnalysis({
    required this.id,
    required this.userReply,
    required this.timestamp,
    required this.grammarScore,
    required this.semanticsScore,
    required this.fluencyScore,
    this.grammarIssues = const [],
    this.usedVocabulary = const [],
    this.missedVocabulary = const [],
    this.suggestions = const [],
    this.taskProgress,
    this.isDialogueComplete = false,
    this.metadata = const {},
  });

  factory DialogueAnalysis.fromJson(Map<String, dynamic> json) {
    return DialogueAnalysis(
      id: json['id'] as String,
      userReply: json['userReply'] as String,
      timestamp: DateTime.parse(json['timestamp'] as String),
      grammarScore: json['grammarScore'] as double,
      semanticsScore: json['semanticsScore'] as double,
      fluencyScore: json['fluencyScore'] as double,
      grammarIssues: (json['grammarIssues'] as List?)
          ?.map((e) => GrammarIssue.fromJson(e as Map<String, dynamic>))
          .toList() ?? [],
      usedVocabulary: List<String>.from(json['usedVocabulary'] ?? []),
      missedVocabulary: List<String>.from(json['missedVocabulary'] ?? []),
      suggestions: List<String>.from(json['suggestions'] ?? []),
      taskProgress: json['taskProgress'] as double?,
      isDialogueComplete: json['isDialogueComplete'] as bool? ?? false,
      metadata: json['metadata'] as Map<String, dynamic>? ?? {},
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'userReply': userReply,
      'timestamp': timestamp.toIso8601String(),
      'grammarScore': grammarScore,
      'semanticsScore': semanticsScore,
      'fluencyScore': fluencyScore,
      'grammarIssues': grammarIssues.map((e) => e.toJson()).toList(),
      'usedVocabulary': usedVocabulary,
      'missedVocabulary': missedVocabulary,
      'suggestions': suggestions,
      'taskProgress': taskProgress,
      'isDialogueComplete': isDialogueComplete,
      'metadata': metadata,
    };
  }
}

/// 語法問題模型
class GrammarIssue {
  final String type;
  final String description;
  final String originalText;
  final String suggestedText;
  final int position;
  final int length;
  final GrammarIssueSeverity severity;

  GrammarIssue({
    required this.type,
    required this.description,
    required this.originalText,
    required this.suggestedText,
    required this.position,
    required this.length,
    required this.severity,
  });

  factory GrammarIssue.fromJson(Map<String, dynamic> json) {
    return GrammarIssue(
      type: json['type'] as String,
      description: json['description'] as String,
      originalText: json['originalText'] as String,
      suggestedText: json['suggestedText'] as String,
      position: json['position'] as int,
      length: json['length'] as int,
      severity: GrammarIssueSeverity.values.firstWhere(
        (e) => e.toString() == 'GrammarIssueSeverity.${json['severity']}',
        orElse: () => GrammarIssueSeverity.minor,
      ),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'type': type,
      'description': description,
      'originalText': originalText,
      'suggestedText': suggestedText,
      'position': position,
      'length': length,
      'severity': severity.toString().split('.').last,
    };
  }
}

/// 語法問題嚴重程度
enum GrammarIssueSeverity {
  minor,
  moderate,
  major,
  critical,
}

/// 對話最終得分模型
class DialogueScore {
  final double grammarScore;
  final double semanticsScore;
  final double fluencyScore;
  final double taskBonus;
  final double vocabularyBonus;
  final double timeBonus;
  final double totalScore;
  final int starRating;
  final DateTime timestamp;
  final Map<String, dynamic> breakdown;

  DialogueScore({
    required this.grammarScore,
    required this.semanticsScore,
    required this.fluencyScore,
    required this.taskBonus,
    required this.vocabularyBonus,
    required this.timeBonus,
    required this.totalScore,
    required this.starRating,
    DateTime? timestamp,
    this.breakdown = const {},
  }) : timestamp = timestamp ?? DateTime.now();

  factory DialogueScore.fromJson(Map<String, dynamic> json) {
    return DialogueScore(
      grammarScore: json['grammarScore'] as double,
      semanticsScore: json['semanticsScore'] as double,
      fluencyScore: json['fluencyScore'] as double,
      taskBonus: json['taskBonus'] as double,
      vocabularyBonus: json['vocabularyBonus'] as double,
      timeBonus: json['timeBonus'] as double,
      totalScore: json['totalScore'] as double,
      starRating: json['starRating'] as int,
      timestamp: DateTime.parse(json['timestamp'] as String),
      breakdown: json['breakdown'] as Map<String, dynamic>? ?? {},
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'grammarScore': grammarScore,
      'semanticsScore': semanticsScore,
      'fluencyScore': fluencyScore,
      'taskBonus': taskBonus,
      'vocabularyBonus': vocabularyBonus,
      'timeBonus': timeBonus,
      'totalScore': totalScore,
      'starRating': starRating,
      'timestamp': timestamp.toIso8601String(),
      'breakdown': breakdown,
    };
  }

  String get grade {
    if (totalScore >= 90) return 'A+';
    if (totalScore >= 80) return 'A';
    if (totalScore >= 70) return 'B';
    if (totalScore >= 60) return 'C';
    if (totalScore >= 50) return 'D';
    return 'F';
  }

  String get comment {
    switch (starRating) {
      case 3:
        return '優秀！你的表現非常出色！';
      case 2:
        return '很好！繼續努力就能更進一步！';
      case 1:
        return '不錯！還有改進的空間。';
      default:
        return '需要更多練習，加油！';
    }
  }
}

/// 詞彙項目模型
class VocabularyItem {
  final String id;
  final String word;
  final String definition;
  final String pronunciation;
  final List<String> examples;
  final String category;
  final int difficulty;
  final bool isRequired;
  final bool isUsed;

  VocabularyItem({
    required this.id,
    required this.word,
    required this.definition,
    required this.pronunciation,
    this.examples = const [],
    this.category = '',
    this.difficulty = 1,
    this.isRequired = false,
    this.isUsed = false,
  });

  factory VocabularyItem.fromJson(Map<String, dynamic> json) {
    return VocabularyItem(
      id: json['id'] as String,
      word: json['word'] as String,
      definition: json['definition'] as String,
      pronunciation: json['pronunciation'] as String,
      examples: List<String>.from(json['examples'] ?? []),
      category: json['category'] as String? ?? '',
      difficulty: json['difficulty'] as int? ?? 1,
      isRequired: json['isRequired'] as bool? ?? false,
      isUsed: json['isUsed'] as bool? ?? false,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'word': word,
      'definition': definition,
      'pronunciation': pronunciation,
      'examples': examples,
      'category': category,
      'difficulty': difficulty,
      'isRequired': isRequired,
      'isUsed': isUsed,
    };
  }

  VocabularyItem copyWith({
    String? id,
    String? word,
    String? definition,
    String? pronunciation,
    List<String>? examples,
    String? category,
    int? difficulty,
    bool? isRequired,
    bool? isUsed,
  }) {
    return VocabularyItem(
      id: id ?? this.id,
      word: word ?? this.word,
      definition: definition ?? this.definition,
      pronunciation: pronunciation ?? this.pronunciation,
      examples: examples ?? this.examples,
      category: category ?? this.category,
      difficulty: difficulty ?? this.difficulty,
      isRequired: isRequired ?? this.isRequired,
      isUsed: isUsed ?? this.isUsed,
    );
  }
}