/// 테스트 실행 결과를 담는 클래스
class TestResult {
  final String name;
  final int totalTests;
  final int passedTests;
  final int failedTests;
  final List<String> failedTestNames;
  final Duration executionTime;
  final Map<String, dynamic> metadata;

  TestResult({
    required this.name,
    required this.totalTests,
    required this.passedTests,
    required this.failedTests,
    this.failedTestNames = const [],
    required this.executionTime,
    this.metadata = const {},
  });

  double get passRate => totalTests > 0 ? (passedTests / totalTests) * 100 : 0;
  
  bool get isSuccess => failedTests == 0;
  
  String get summary {
    final emoji = isSuccess ? '✅' : '❌';
    return '$emoji $name: $passedTests/$totalTests 통과 (${passRate.toStringAsFixed(1)}%)';
  }
  
  Map<String, dynamic> toJson() => {
    'name': name,
    'totalTests': totalTests,
    'passedTests': passedTests,
    'failedTests': failedTests,
    'failedTestNames': failedTestNames,
    'executionTimeMs': executionTime.inMilliseconds,
    'passRate': passRate,
    'metadata': metadata,
  };
}

/// 전체 테스트 스위트 결과
class TestSuiteResult {
  final List<TestResult> results;
  final DateTime timestamp;
  
  TestSuiteResult({
    required this.results,
    DateTime? timestamp,
  }) : timestamp = timestamp ?? DateTime.now();
  
  int get totalTests => results.fold(0, (sum, r) => sum + r.totalTests);
  int get passedTests => results.fold(0, (sum, r) => sum + r.passedTests);
  int get failedTests => results.fold(0, (sum, r) => sum + r.failedTests);
  double get overallPassRate => totalTests > 0 ? (passedTests / totalTests) * 100 : 0;
  bool get isSuccess => failedTests == 0;
  
  Duration get totalExecutionTime => Duration(
    milliseconds: results.fold(0, (sum, r) => sum + r.executionTime.inMilliseconds),
  );
  
  String get summary {
    final buffer = StringBuffer();
    buffer.writeln('\n${'=' * 60}');
    buffer.writeln('📊 테스트 실행 결과 요약');
    buffer.writeln('=' * 60);
    buffer.writeln('실행 시간: ${timestamp.toLocal()}');
    buffer.writeln('총 실행 시간: ${totalExecutionTime.inSeconds}초');
    buffer.writeln('');
    
    for (final result in results) {
      buffer.writeln(result.summary);
    }
    
    buffer.writeln('');
    buffer.writeln('-' * 60);
    buffer.writeln('전체 결과: $passedTests/$totalTests 통과 (${overallPassRate.toStringAsFixed(1)}%)');
    
    if (isSuccess) {
      buffer.writeln('🎉 모든 테스트가 성공적으로 통과했습니다!');
    } else {
      buffer.writeln('⚠️ 실패한 테스트가 있습니다.');
      buffer.writeln('\n실패한 테스트 목록:');
      for (final result in results) {
        if (result.failedTestNames.isNotEmpty) {
          buffer.writeln('\n${result.name}:');
          for (final testName in result.failedTestNames) {
            buffer.writeln('  - $testName');
          }
        }
      }
    }
    
    buffer.writeln('=' * 60);
    return buffer.toString();
  }
  
  Map<String, dynamic> toJson() => {
    'timestamp': timestamp.toIso8601String(),
    'totalTests': totalTests,
    'passedTests': passedTests,
    'failedTests': failedTests,
    'overallPassRate': overallPassRate,
    'totalExecutionTimeMs': totalExecutionTime.inMilliseconds,
    'results': results.map((r) => r.toJson()).toList(),
  };
}