part of '../main.dart';

class SavedAnalysis {
  const SavedAnalysis({
    required this.studentName,
    required this.studentGender,
    required this.label,
    required this.description,
    required this.confidence,
    required this.probabilityPd,
    required this.probabilityTpd,
  });

  factory SavedAnalysis.fromJson(Map<String, dynamic> json) {
    return SavedAnalysis(
      studentName: json['student_name']?.toString() ?? '-',
      studentGender: json['student_gender']?.toString() ?? '',
      label: json['predicted_label']?.toString() ?? '-',
      description: json['description']?.toString() ?? '-',
      confidence: PredictionResult._asDouble(json['confidence']),
      probabilityPd: PredictionResult._asDouble(json['probability_pd']),
      probabilityTpd: PredictionResult._asDouble(json['probability_tpd']),
    );
  }

  final String studentName;
  final String studentGender;
  final String label;
  final String description;
  final double confidence;
  final double probabilityPd;
  final double probabilityTpd;

  String get confidencePercent => (confidence * 100).toStringAsFixed(1);
  String get pdPercent => (probabilityPd * 100).toStringAsFixed(1);
  String get tpdPercent => (probabilityTpd * 100).toStringAsFixed(1);
  String get genderLabel =>
      studentGender.isEmpty ? 'Belum diisi' : studentGender;
}

class PredictionResult {
  const PredictionResult({
    required this.id,
    required this.studentName,
    required this.studentGender,
    required this.isValidAudio,
    required this.errorMessage,
    required this.label,
    required this.description,
    required this.confidence,
    required this.probabilityPd,
    required this.probabilityTpd,
    required this.audioQuality,
    required this.explanation,
    required this.rawJson,
  });

  factory PredictionResult.fromJson(Map<String, dynamic> json) {
    final probabilities =
        (json['probabilities'] as Map?)?.cast<String, dynamic>() ?? {};
    final predictedLabel = json['predicted_label']?.toString();
    return PredictionResult(
      id:
          json['prediction_id'] is int
              ? json['prediction_id'] as int
              : int.tryParse(json['prediction_id']?.toString() ?? ''),
      studentName: json['student_name']?.toString() ?? '',
      studentGender: json['student_gender']?.toString() ?? '',
      isValidAudio: json['is_valid_audio'] != false,
      errorMessage: json['error_message']?.toString(),
      label: predictedLabel ?? json['label']?.toString() ?? '-',
      description: json['description']?.toString() ?? '-',
      confidence: _asDouble(json['confidence']),
      probabilityPd: _asDouble(json['probability_pd'] ?? probabilities['PD']),
      probabilityTpd: _asDouble(
        json['probability_tpd'] ?? probabilities['TPD'],
      ),
      audioQuality: AudioQuality.fromJson(
        (json['audio_quality'] as Map?)?.cast<String, dynamic>() ?? {},
      ),
      explanation: json['explanation']?.toString() ?? '',
      rawJson: json,
    );
  }

  Map<String, dynamic> toSaveJson(int userId, String studentGender) {
    return {
      ...rawJson,
      'student_name': studentName,
      'student_gender': studentGender,
      'user_id': userId,
    };
  }

  static double _asDouble(Object? value) {
    if (value is num) {
      return value.toDouble();
    }
    return double.tryParse(value?.toString() ?? '') ?? 0.0;
  }

  final int? id;
  final String studentName;
  final String studentGender;
  final bool isValidAudio;
  final String? errorMessage;
  final String label;
  final String description;
  final double confidence;
  final double probabilityPd;
  final double probabilityTpd;
  final AudioQuality audioQuality;
  final String explanation;
  final Map<String, dynamic> rawJson;

  String get genderLabel =>
      studentGender.isEmpty ? 'Belum diisi' : studentGender;
}

class AudioQuality {
  const AudioQuality({
    required this.isClipped,
    required this.isTooQuiet,
    required this.isTooShort,
  });

  factory AudioQuality.fromJson(Map<String, dynamic> json) {
    return AudioQuality(
      isClipped: json['is_clipped'] == true,
      isTooQuiet: json['is_too_quiet'] == true,
      isTooShort: json['is_too_short'] == true,
    );
  }

  final bool isClipped;
  final bool isTooQuiet;
  final bool isTooShort;
}
