import '../models/listening_exercise_model.dart';
import '../../../core/network/api_client.dart';
import '../../../core/services/enhanced_api_service.dart';
import '../../../core/models/api_response.dart';
import '../../../core/network/api_endpoints.dart';
import 'dart:convert';

/// 听力训练服务
class ListeningService {
  final EnhancedApiService _enhancedApiService = EnhancedApiService();
  
  // 缓存时长配置
  static const Duration _shortCacheDuration = Duration(minutes: 5);
  static const Duration _longCacheDuration = Duration(hours: 1);

  /// 获取听力材料列表
  Future<List<ListeningExercise>> getListeningExercises({
    ListeningExerciseType? type,
    ListeningDifficulty? difficulty,
    int page = 1,
    int limit = 20,
    bool forceRefresh = false,
  }) async {
    try {
      final response = await _enhancedApiService.get<List<ListeningExercise>>(
        ApiEndpoints.listeningMaterials,
        queryParameters: {
          'page': page,
          'page_size': limit,
          if (type != null) 'type': type.name,
          if (difficulty != null) 'level': _levelFromDifficulty(difficulty),
        },
        useCache: !forceRefresh,
        cacheDuration: _shortCacheDuration,
        fromJson: (data) {
          final List<dynamic> list = (data['data']?['materials'] ?? []) as List<dynamic>;
          return list.map((json) => _materialToExercise(json)).toList();
        },
      );
      
      if (response.success && response.data != null) {
        return response.data!;
      } else {
        throw Exception(response.message);
      }
    } catch (e) {
      throw Exception('获取听力练习失败: $e');
    }
  }

  /// 获取单个听力材料详情
  Future<ListeningExercise> getListeningExercise(String exerciseId) async {
    try {
      final response = await _enhancedApiService.get<ListeningExercise>(
        '${ApiEndpoints.listeningMaterials}/$exerciseId',
        cacheDuration: _longCacheDuration,
        fromJson: (data) => _materialToExercise(data['data']),
      );
      
      if (response.success && response.data != null) {
        return response.data!;
      } else {
        throw Exception(response.message);
      }
    } catch (e) {
      throw Exception('获取听力练习详情失败: $e');
    }
  }

  /// 提交听力练习答案
  Future<ListeningExerciseResult> submitListeningExercise({
    required String exerciseId,
    required String userId,
    required List<String> userAnswers,
    required int timeSpent,
    required int playCount,
  }) async {
    try {
      final response = await _enhancedApiService.post<ListeningExerciseResult>(
        ApiEndpoints.listeningRecords,
        data: {
          'material_id': exerciseId,
          'user_answers': userAnswers,
          'time_spent': timeSpent,
          'play_count': playCount,
        },
        fromJson: (data) => _recordToResult(data['record']),
      );
      
      if (response.success && response.data != null) {
        return response.data!;
      } else {
        throw Exception(response.message);
      }
    } catch (e) {
      throw Exception('提交听力练习失败: $e');
    }
  }

  /// 获取用户听力练习历史
  Future<List<ListeningExerciseResult>> getUserListeningHistory({
    required String userId,
    int page = 1,
    int limit = 20,
  }) async {
    try {
      final response = await _enhancedApiService.get<List<ListeningExerciseResult>>( 
        ApiEndpoints.listeningRecords,
        queryParameters: {
          'page': page,
          'page_size': limit,
        },
        cacheDuration: _shortCacheDuration,
        fromJson: (data) {
          final List<dynamic> list = (data['data']?['records'] ?? []) as List<dynamic>;
          return list.map((json) => _recordToResult(json)).toList();
        },
      );
      
      if (response.success && response.data != null) {
        return response.data!;
      } else {
        throw Exception(response.message);
      }
    } catch (e) {
      throw Exception('获取听力练习历史失败: $e');
    }
  }

  /// 获取用户听力学习统计
  Future<ListeningStatistics> getUserListeningStatistics() async {
    try {
      final response = await _enhancedApiService.get<ListeningStatistics>(
        ApiEndpoints.listeningStats,
        useCache: true,
        cacheDuration: _shortCacheDuration,
        fromJson: (data) => _statsToModel(data['data']),
      );
      
      if (response.success && response.data != null) {
        return response.data!;
      } else {
        throw Exception(response.message);
      }
    } catch (e) {
      throw Exception('获取听力学习统计失败: $e');
    }
  }

  Future<ListeningStatistics> getUserListeningStatisticsNoCache() async {
    try {
      final response = await _enhancedApiService.get<ListeningStatistics>(
        ApiEndpoints.listeningStats,
        useCache: false,
        fromJson: (data) => _statsToModel(data['data']),
      );
      if (response.success && response.data != null) {
        return response.data!;
      } else {
        throw Exception(response.message);
      }
    } catch (e) {
      throw Exception('获取听力学习统计失败: $e');
    }
  }

  /// 搜索听力材料
  Future<List<ListeningExercise>> searchListeningExercises({
    required String query,
    ListeningExerciseType? type,
    ListeningDifficulty? difficulty,
    int page = 1,
    int limit = 20,
  }) async {
    try {
      final response = await _enhancedApiService.get<List<ListeningExercise>>(
        '${ApiEndpoints.listeningMaterials}/search',
        queryParameters: {
          'q': query,
          'page': page,
          'page_size': limit,
          if (type != null) 'type': type.name,
          if (difficulty != null) 'difficulty': difficulty.name,
        },
        cacheDuration: _shortCacheDuration,
        fromJson: (data) {
          final List<dynamic> list = (data['data']?['materials'] ?? []) as List<dynamic>;
          return list.map((json) => _materialToExercise(json)).toList();
        },
      );
      
      if (response.success && response.data != null) {
        return response.data!;
      } else {
        throw Exception(response.message);
      }
    } catch (e) {
      throw Exception('搜索听力练习失败: $e');
    }
  }

  /// 获取推荐的听力练习
  /// 后端暂未提供推荐接口，返回空列表
  Future<List<ListeningExercise>> getRecommendedListeningExercises({
    int limit = 10,
  }) async {
    return [];
  }

  ListeningExercise _materialToExercise(Map<String, dynamic> m) {
    final desc = (m['description'] ?? '') as String?;
    final transcript = (m['transcript'] ?? '') as String?;
    final tagsStr = (m['tags'] ?? '') as String?;
    final tags = <String>[];
    if (tagsStr != null && tagsStr.isNotEmpty) {
      try {
        final parsed = json.decode(tagsStr);
        if (parsed is List) {
          tags.addAll(parsed.map((e) => e.toString()));
        }
      } catch (_) {}
    }
    final levelStr = (m['level'] ?? 'beginner') as String;
    final categoryStr = (m['category'] ?? 'conversation') as String;
    final createdAtStr = (m['created_at'] ?? DateTime.now().toIso8601String()).toString();
    final updatedAtStr = (m['updated_at'] ?? DateTime.now().toIso8601String()).toString();
    return ListeningExercise(
      id: m['id'].toString(),
      title: m['title'] ?? '',
      description: desc ?? '',
      type: _typeFromCategory(categoryStr),
      difficulty: _difficultyFromLevel(levelStr),
      audioUrl: m['audio_url'] ?? '',
      duration: (m['duration'] ?? 0) as int,
      transcript: transcript ?? '',
      questions: const [],
      tags: tags,
      thumbnailUrl: '',
      totalPoints: 0,
      passingScore: 0.6,
      creatorId: '',
      creatorName: '',
      isPublic: true,
      playCount: 0,
      rating: 0,
      reviewCount: 0,
      createdAt: DateTime.tryParse(createdAtStr) ?? DateTime.now(),
      updatedAt: DateTime.tryParse(updatedAtStr) ?? DateTime.now(),
    );
  }

  ListeningExerciseResult _recordToResult(Map<String, dynamic> r) {
    final completedAtStr = (r['completed_at'] ?? DateTime.now().toIso8601String()).toString();
    final score = (r['score'] ?? 0.0);
    final accuracy = (r['accuracy'] ?? 0.0);
    final totalQ = 100;
    final correct = (accuracy is num ? (accuracy * totalQ).round() : 0);
    return ListeningExerciseResult(
      id: r['id'].toString(),
      exerciseId: r['material_id'].toString(),
      userId: r['user_id'].toString(),
      userAnswers: const [],
      correctAnswers: List<bool>.filled(totalQ, false),
      totalQuestions: totalQ,
      correctCount: correct,
      score: (score is num ? score.toDouble() : 0.0),
      timeSpent: (r['time_spent'] ?? 0) as int,
      playCount: (r['play_count'] ?? 1) as int,
      isPassed: (score is num ? score >= 60 : false),
      completedAt: DateTime.tryParse(completedAtStr) ?? DateTime.now(),
    );
  }

  ListeningStatistics _statsToModel(Map<String, dynamic> s) {
    final avgAcc = (s['average_accuracy'] ?? 0.0);
    final totalRecords = (s['total_records'] ?? 0) as int;
    final completedRecords = (s['completed_records'] ?? 0) as int;
    final totalTimeMinutes = (s['total_time_spent'] ?? 0) as int;
    final difficultyStatsMap = <ListeningDifficulty, int>{};
    final typeStatsMap = <ListeningExerciseType, int>{};
    final levelStats = s['level_stats'] as Map<String, dynamic>?;
    levelStats?.forEach((k, v) {
      difficultyStatsMap[_difficultyFromLevel(k)] = (v as num).toInt();
    });
    return ListeningStatistics(
      userId: '',
      totalExercises: totalRecords,
      completedExercises: completedRecords,
      totalQuestions: 100,
      correctAnswers: (avgAcc is num ? (avgAcc * 100).round() : 0),
      averageScore: (s['average_score'] is num ? (s['average_score'] as num).toDouble() : 0.0),
      totalTimeSpent: totalTimeMinutes * 60,
      totalPlayCount: 0,
      streakDays: (s['continuous_days'] ?? 0) as int,
      difficultyStats: difficultyStatsMap,
      typeStats: typeStatsMap,
      lastUpdated: DateTime.now(),
    );
  }

  ListeningDifficulty _difficultyFromLevel(String level) {
    switch (level) {
      case 'beginner':
        return ListeningDifficulty.beginner;
      case 'intermediate':
        return ListeningDifficulty.intermediate;
      case 'advanced':
        return ListeningDifficulty.advanced;
      case 'elementary':
        return ListeningDifficulty.elementary;
      case 'expert':
        return ListeningDifficulty.expert;
      default:
        return ListeningDifficulty.beginner;
    }
  }

  ListeningExerciseType _typeFromCategory(String category) {
    switch (category) {
      case 'lecture':
        return ListeningExerciseType.lecture;
      case 'news':
        return ListeningExerciseType.news;
      case 'story':
        return ListeningExerciseType.story;
      case 'interview':
        return ListeningExerciseType.interview;
      case 'dialogue':
        return ListeningExerciseType.dialogue;
      case 'conversation':
      default:
        return ListeningExerciseType.conversation;
    }
  }
}
  String _levelFromDifficulty(ListeningDifficulty d) {
    switch (d) {
      case ListeningDifficulty.beginner:
        return 'beginner';
      case ListeningDifficulty.elementary:
        return 'beginner';
      case ListeningDifficulty.intermediate:
        return 'intermediate';
      case ListeningDifficulty.advanced:
        return 'advanced';
      case ListeningDifficulty.expert:
        return 'advanced';
    }
  }