import 'dart:convert';
import '../../../core/network/api_client.dart';
import '../../../core/services/storage_service.dart';
import '../models/word_book_model.dart';
import '../models/word_model.dart';

/// 生词本服务
class WordBookService {
  final ApiClient _apiClient;
  final StorageService _storageService;
  
  static const String _wordBooksKey = 'word_books';
  static const String _wordBookEntriesKey = 'word_book_entries';

  WordBookService({
    required ApiClient apiClient,
    required StorageService storageService,
  }) : _apiClient = apiClient,
       _storageService = storageService;

  /// 获取用户的所有生词本
  Future<List<WordBook>> getUserWordBooks() async {
    try {
      // 尝试从本地存储获取
      final localData = await _storageService.getString(_wordBooksKey);
      if (localData != null) {
        final List<dynamic> jsonList = json.decode(localData);
        return jsonList.map((json) => WordBook.fromJson(json)).toList();
      }

      // 如果本地没有数据，创建默认生词本
      final defaultWordBook = WordBook(
        id: 'default_word_book',
        name: '我的生词本',
        description: '收藏的生词',
        userId: 'current_user',
        createdAt: DateTime.now(),
        updatedAt: DateTime.now(),
      );

      await _saveWordBooksToLocal([defaultWordBook]);
      return [defaultWordBook];
    } catch (e) {
      throw Exception('获取生词本失败: $e');
    }
  }

  /// 创建新的生词本
  Future<WordBook> createWordBook({
    required String name,
    String? description,
    WordBookType type = WordBookType.personal,
  }) async {
    try {
      final wordBook = WordBook(
        id: DateTime.now().millisecondsSinceEpoch.toString(),
        name: name,
        description: description,
        userId: 'current_user',
        type: type,
        createdAt: DateTime.now(),
        updatedAt: DateTime.now(),
      );

      final existingBooks = await getUserWordBooks();
      existingBooks.add(wordBook);
      await _saveWordBooksToLocal(existingBooks);

      return wordBook;
    } catch (e) {
      throw Exception('创建生词本失败: $e');
    }
  }

  /// 删除生词本
  Future<void> deleteWordBook(String wordBookId) async {
    try {
      final existingBooks = await getUserWordBooks();
      existingBooks.removeWhere((book) => book.id == wordBookId);
      await _saveWordBooksToLocal(existingBooks);

      // 同时删除该生词本的所有条目
      final entries = await getWordBookEntries(wordBookId);
      for (final entry in entries) {
        await removeWordFromBook(wordBookId, entry.wordId);
      }
    } catch (e) {
      throw Exception('删除生词本失败: $e');
    }
  }

  /// 更新生词本信息
  Future<WordBook> updateWordBook(WordBook wordBook) async {
    try {
      final existingBooks = await getUserWordBooks();
      final index = existingBooks.indexWhere((book) => book.id == wordBook.id);
      
      if (index == -1) {
        throw Exception('生词本不存在');
      }

      final updatedWordBook = wordBook.copyWith(updatedAt: DateTime.now());
      existingBooks[index] = updatedWordBook;
      await _saveWordBooksToLocal(existingBooks);

      return updatedWordBook;
    } catch (e) {
      throw Exception('更新生词本失败: $e');
    }
  }

  /// 添加单词到生词本
  Future<WordBookEntry> addWordToBook({
    required String wordBookId,
    required Word word,
    String? note,
    List<String> tags = const [],
  }) async {
    try {
      // 检查单词是否已存在
      final existingEntries = await getWordBookEntries(wordBookId);
      final existingEntry = existingEntries.where((entry) => entry.wordId == word.id).firstOrNull;
      
      if (existingEntry != null) {
        throw Exception('单词已存在于生词本中');
      }

      final entry = WordBookEntry(
        id: '${wordBookId}_${word.id}',
        wordBookId: wordBookId,
        wordId: word.id,
        word: word,
        note: note,
        tags: tags,
        addedAt: DateTime.now(),
      );

      existingEntries.add(entry);
      await _saveWordBookEntriesToLocal(existingEntries);

      // 更新生词本的单词数量
      await _updateWordBookCount(wordBookId);

      return entry;
    } catch (e) {
      throw Exception('添加单词到生词本失败: $e');
    }
  }

  /// 从生词本移除单词
  Future<void> removeWordFromBook(String wordBookId, String wordId) async {
    try {
      final existingEntries = await getWordBookEntries(wordBookId);
      existingEntries.removeWhere((entry) => 
        entry.wordBookId == wordBookId && entry.wordId == wordId);
      await _saveWordBookEntriesToLocal(existingEntries);

      // 更新生词本的单词数量
      await _updateWordBookCount(wordBookId);
    } catch (e) {
      throw Exception('从生词本移除单词失败: $e');
    }
  }

  /// 获取生词本的所有条目
  Future<List<WordBookEntry>> getWordBookEntries(String wordBookId) async {
    try {
      final localData = await _storageService.getString(_wordBookEntriesKey);
      if (localData == null) {
        return [];
      }

      final List<dynamic> jsonList = json.decode(localData);
      final allEntries = jsonList.map((json) => WordBookEntry.fromJson(json)).toList();
      
      return allEntries.where((entry) => entry.wordBookId == wordBookId).toList();
    } catch (e) {
      throw Exception('获取生词本条目失败: $e');
    }
  }

  /// 更新生词本条目
  Future<WordBookEntry> updateWordBookEntry(WordBookEntry entry) async {
    try {
      final allEntries = await _getAllWordBookEntries();
      final index = allEntries.indexWhere((e) => e.id == entry.id);
      
      if (index == -1) {
        throw Exception('生词本条目不存在');
      }

      allEntries[index] = entry;
      await _saveWordBookEntriesToLocal(allEntries);

      return entry;
    } catch (e) {
      throw Exception('更新生词本条目失败: $e');
    }
  }

  /// 获取生词本统计信息
  Future<WordBookStats> getWordBookStats(String wordBookId) async {
    try {
      final entries = await getWordBookEntries(wordBookId);
      
      final totalWords = entries.length;
      final masteredWords = entries.where((entry) => 
        entry.reviewCount >= 3 && 
        entry.correctCount / entry.reviewCount >= 0.8
      ).length;
      final reviewingWords = entries.where((entry) => 
        entry.reviewCount > 0 && entry.reviewCount < 3
      ).length;
      final newWords = entries.where((entry) => entry.reviewCount == 0).length;
      
      final masteryRate = totalWords > 0 ? masteredWords / totalWords : 0.0;
      
      final lastStudyAt = entries
        .where((entry) => entry.lastReviewAt != null)
        .map((entry) => entry.lastReviewAt!)
        .fold<DateTime?>(null, (latest, current) => 
          latest == null || current.isAfter(latest) ? current : latest);

      return WordBookStats(
        wordBookId: wordBookId,
        totalWords: totalWords,
        masteredWords: masteredWords,
        reviewingWords: reviewingWords,
        newWords: newWords,
        masteryRate: masteryRate,
        lastStudyAt: lastStudyAt,
        totalReviews: entries.fold(0, (sum, entry) => sum + entry.reviewCount),
      );
    } catch (e) {
      throw Exception('获取生词本统计失败: $e');
    }
  }

  /// 检查单词是否在生词本中
  Future<bool> isWordInBook(String wordBookId, String wordId) async {
    try {
      final entries = await getWordBookEntries(wordBookId);
      return entries.any((entry) => entry.wordId == wordId);
    } catch (e) {
      return false;
    }
  }

  /// 搜索生词本中的单词
  Future<List<WordBookEntry>> searchWordsInBook({
    required String wordBookId,
    required String query,
  }) async {
    try {
      final entries = await getWordBookEntries(wordBookId);
      final lowerQuery = query.toLowerCase();
      
      return entries.where((entry) {
        final word = entry.word.word.toLowerCase();
        final definitions = entry.word.definitions
          .map((def) => def.definition.toLowerCase())
          .join(' ');
        final translations = entry.word.definitions
          .map((def) => def.translation?.toLowerCase() ?? '')
          .join(' ');
        
        return word.contains(lowerQuery) || 
               definitions.contains(lowerQuery) ||
               translations.contains(lowerQuery);
      }).toList();
    } catch (e) {
      throw Exception('搜索生词本失败: $e');
    }
  }

  /// 保存生词本到本地存储
  Future<void> _saveWordBooksToLocal(List<WordBook> wordBooks) async {
    final jsonList = wordBooks.map((book) => book.toJson()).toList();
    await _storageService.setString(_wordBooksKey, json.encode(jsonList));
  }

  /// 保存生词本条目到本地存储
  Future<void> _saveWordBookEntriesToLocal(List<WordBookEntry> entries) async {
    final jsonList = entries.map((entry) => entry.toJson()).toList();
    await _storageService.setString(_wordBookEntriesKey, json.encode(jsonList));
  }

  /// 获取所有生词本条目
  Future<List<WordBookEntry>> _getAllWordBookEntries() async {
    final localData = await _storageService.getString(_wordBookEntriesKey);
    if (localData == null) {
      return [];
    }

    final List<dynamic> jsonList = json.decode(localData);
    return jsonList.map((json) => WordBookEntry.fromJson(json)).toList();
  }

  /// 更新生词本的单词数量
  Future<void> _updateWordBookCount(String wordBookId) async {
    final entries = await getWordBookEntries(wordBookId);
    final wordBooks = await getUserWordBooks();
    
    final index = wordBooks.indexWhere((book) => book.id == wordBookId);
    if (index != -1) {
      final updatedBook = wordBooks[index].copyWith(
        wordCount: entries.length,
        updatedAt: DateTime.now(),
      );
      wordBooks[index] = updatedBook;
      await _saveWordBooksToLocal(wordBooks);
    }
  }
}