import 'dart:async';
import 'dart:math' as math;
import 'dart:convert';

import 'package:ainoval/models/editor_settings.dart';
import 'package:ainoval/models/novel_structure.dart' as novel_models;
import 'package:ainoval/services/api_service/repositories/impl/editor_repository_impl.dart';
import 'package:ainoval/utils/logger.dart';
import 'package:ainoval/utils/word_count_analyzer.dart';
import 'package:ainoval/utils/quill_helper.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

part 'editor_event.dart';
part 'editor_state.dart';

// Helper class to hold the two maps
class _ChapterMaps {
  final Map<String, int> chapterGlobalIndices;
  final Map<String, String> chapterToActMap;

  _ChapterMaps(this.chapterGlobalIndices, this.chapterToActMap);
}

// Bloc实现
class EditorBloc extends Bloc<EditorEvent, EditorState> {
  EditorBloc({
    required EditorRepositoryImpl repository,
    required this.novelId,
  })  : repository = repository,
        super(EditorInitial()) {
    on<LoadEditorContentPaginated>(_onLoadContentPaginated);
    on<LoadMoreScenes>(_onLoadMoreScenes);
    on<UpdateContent>(_onUpdateContent);
    on<SaveContent>(_onSaveContent);
    on<UpdateSceneContent>(_onUpdateSceneContent);
    on<UpdateSummary>(_onUpdateSummary);
    on<UpdateEditorSettings>(_onUpdateSettings);
    on<LoadUserEditorSettings>(_onLoadUserEditorSettings); // 🚀 新增：处理加载用户编辑器设置事件
    on<SetActiveChapter>(_onSetActiveChapter);
    on<SetActiveScene>(_onSetActiveScene);
    on<SetFocusChapter>(_onSetFocusChapter); // 添加新的事件处理
    on<AddNewScene>(_onAddNewScene);
    on<DeleteScene>(_onDeleteScene);
    on<DeleteChapter>(_onDeleteChapter);
    on<DeleteAct>(_onDeleteAct);
    on<SaveSceneContent>(_onSaveSceneContent);
    on<ForceSaveSceneContent>(_onForceSaveSceneContent); // 添加强制保存事件处理
    on<AddNewAct>(_onAddNewAct);
    on<AddNewChapter>(_onAddNewChapter);
    on<UpdateVisibleRange>(_onUpdateVisibleRange);
    on<ResetActLoadingFlags>(_onResetActLoadingFlags); // 添加新事件处理
    on<SetActLoadingFlags>(_onSetActLoadingFlags); // 添加新的事件处理器
    on<UpdateChapterTitle>(_onUpdateChapterTitle); // 添加Chapter标题更新事件处理
    on<UpdateActTitle>(_onUpdateActTitle); // 添加Act标题更新事件处理
    on<GenerateSceneFromSummaryRequested>(_onGenerateSceneFromSummaryRequested); // 添加场景生成事件处理
    on<UpdateGeneratedSceneContent>(_onUpdateGeneratedSceneContent); // 添加更新生成内容事件处理
    on<SceneGenerationCompleted>(_onSceneGenerationCompleted); // 添加生成完成事件处理
    on<SceneGenerationFailed>(_onSceneGenerationFailed); // 添加生成失败事件处理
    on<StopSceneGeneration>(_onStopSceneGeneration); // 添加停止生成事件处理
    on<SetPendingSummary>(_onSetPendingSummary); // 添加设置待处理摘要事件处理
    
    // 🚀 新增：Plan视图相关事件处理
    on<SwitchToPlanView>(_onSwitchToPlanView);
    on<SwitchToWriteView>(_onSwitchToWriteView);
    on<LoadPlanContent>(_onLoadPlanContent);
    on<MoveScene>(_onMoveScene);
    on<NavigateToSceneFromPlan>(_onNavigateToSceneFromPlan);
    on<RefreshEditorData>(_onRefreshEditorData);
    
    // 🚀 新增：沉浸模式相关事件处理
    on<SwitchToImmersiveMode>(_onSwitchToImmersiveMode);
    on<SwitchToNormalMode>(_onSwitchToNormalMode);
    on<NavigateToNextChapter>(_onNavigateToNextChapter);
    on<NavigateToPreviousChapter>(_onNavigateToPreviousChapter);
  }
  final EditorRepositoryImpl repository;
  final String novelId;
  Timer? _autoSaveTimer;
  novel_models.Novel? _novel;
  bool _isDirty = false;
  DateTime? _lastSaveTime;
  final EditorSettings _settings = const EditorSettings();
  bool? hasReachedEnd;
  bool? hasReachedStart;

  StreamSubscription<String>? _generationStreamSubscription;

  /// 待保存场景的缓冲队列
  final Map<String, Map<String, dynamic>> _pendingSaveScenes = {};
  /// 上次保存时间映射
  final Map<String, DateTime> _lastSceneSaveTime = {};
  /// 批量保存防抖计时器
  Timer? _batchSaveDebounceTimer;
  /// 批量保存间隔（改为5分钟，优先本地保存，减少后端请求）
  static const Duration _batchSaveInterval = Duration(minutes: 5);
  /// 单场景保存防抖间隔
  static const Duration _sceneSaveDebounceInterval = Duration(milliseconds: 800);

  /// 摘要更新防抖控制
  final Map<String, DateTime> _lastSummaryUpdateRequestTime = {};
  static const Duration _summaryUpdateRequestInterval = Duration(milliseconds: 800);

  /// lastEditedChapterId更新防抖控制
  Timer? _lastEditedChapterUpdateTimer;
  String? _pendingLastEditedChapterId;
  static const Duration _lastEditedChapterUpdateInterval = Duration(seconds: 3);

  // Helper method to calculate chapter maps
  _ChapterMaps _calculateChapterMaps(novel_models.Novel novel) {
    final Map<String, int> chapterGlobalIndices = {};
    final Map<String, String> chapterToActMap = {};
    int globalIndex = 0;

    for (final act in novel.acts) {
      for (final chapter in act.chapters) {
        chapterGlobalIndices[chapter.id] = globalIndex++;
        chapterToActMap[chapter.id] = act.id;
      }
    }
    return _ChapterMaps(chapterGlobalIndices, chapterToActMap);
  }

  Future<void> _onLoadContentPaginated(
      LoadEditorContentPaginated event, Emitter<EditorState> emit) async {
    emit(EditorLoading());

    try {
      // 使用getNovelWithAllScenes替代getNovelWithPaginatedScenes
      novel_models.Novel? novel = await repository.getNovelWithAllScenes(event.novelId);

      if (novel == null) {
        emit(const EditorError(message: '无法加载小说数据'));
        return;
      }
      AppLogger.i('EditorBloc/_onLoadContentPaginated', 'Loaded novel from getNovelWithAllScenes. Novel ID: ${novel.id}, Title: ${novel.title}');
      AppLogger.i('EditorBloc/_onLoadContentPaginated', 'Novel acts count: ${novel.acts.length}');
      for (int i = 0; i < novel.acts.length; i++) {
          final act = novel.acts[i];
          //AppLogger.i('EditorBloc/_onLoadContentPaginated', 'Act ${i} (${act.id}): Title: ${act.title}, Chapters count: ${act.chapters.length}');
          for (int j = 0; j < act.chapters.length; j++) {
              final chapter = act.chapters[j];
              //AppLogger.i('EditorBloc/_onLoadContentPaginated', '  Chapter ${j} (${chapter.id}): Title: ${chapter.title}, Scenes count: ${chapter.scenes.length}');
              for (int k = 0; k < chapter.scenes.length; k++) {
                  final scene = chapter.scenes[k];
                  //AppLogger.d('EditorBloc/_onLoadContentPaginated', '    Scene ${k} (${scene.id}): WordCount: ${scene.wordCount}, HasContent: ${scene.content.isNotEmpty}, Summary: ${scene.summary.content}');
              }
          }
      }

      // 从此处开始，novel 不为 null
      if (novel.acts.isEmpty) { 
        AppLogger.i('EditorBloc/_onLoadContentPaginated', '检测到小说 (${novel.id}) 没有卷，尝试自动创建第一卷。');
        try {
          // novel.id 是安全的，因为 novel 在此不为 null
          final novelWithNewAct = await repository.addNewAct(
            novel.id, 
            "第一卷", 
          );
          if (novelWithNewAct != null) {
            novel = novelWithNewAct; // novel 可能被新对象（同样不为null）赋值
            // novel.id 和 novel.acts 在此也是安全的
            AppLogger.i('EditorBloc/_onLoadContentPaginated', '成功为小说 (${novel.id}) 自动创建第一卷。新的卷数量: ${novel.acts.length}');
          } else {
            AppLogger.w('EditorBloc/_onLoadContentPaginated', '为小说 (${novel.id}) 自动创建第一卷失败，repository.addNewAct 返回 null。');
          }
        } catch (e) {
          AppLogger.e('EditorBloc/_onLoadContentPaginated', '为小说 (${novel?.id}) 自动创建第一卷时发生错误。', e);
        }
      }

      final settings = await repository.getEditorSettings();

      String? activeActId;
      // novel 在此不为 null
      String? activeChapterId = novel?.lastEditedChapterId;
      String? activeSceneId;

      if (activeChapterId != null && activeChapterId.isNotEmpty) {
        for (final act_ in novel!.acts) { 
          for (final chapter in act_.chapters) {
            if (chapter.id == activeChapterId) {
              activeActId = act_.id;
              if (chapter.scenes.isNotEmpty) {
                activeSceneId = chapter.scenes.first.id;
              }
              break;
            }
          }
          if (activeActId != null) break;
        }
      }

      if (activeActId == null && novel!.acts.isNotEmpty) {
        activeActId = novel.acts.first.id;
        if (novel.acts.first.chapters.isNotEmpty) {
          activeChapterId = novel.acts.first.chapters.first.id;
          if (novel.acts.first.chapters.first.scenes.isNotEmpty) {
            activeSceneId = novel.acts.first.chapters.first.scenes.first.id;
          }
        } else {
          activeChapterId = null;
          activeSceneId = null;
        }
      }
      
      // novel 在此不为 null，因此 novel! 是安全的
      final chapterMaps = _calculateChapterMaps(novel!);

      emit(EditorLoaded(
        novel: novel,
        settings: settings,
        activeActId: activeActId,
        activeChapterId: activeChapterId,
        activeSceneId: activeSceneId,
        isDirty: false,
        isSaving: false,
        chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Added
        chapterToActMap: chapterMaps.chapterToActMap, // Added
      ));
    } catch (e) {
      emit(EditorError(message: '加载小说失败: ${e.toString()}'));
    }
  }

  Future<void> _onLoadMoreScenes(
      LoadMoreScenes event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) {
      return;
    }

    // 获取当前加载状态
    final currentState = state as EditorLoaded;
    
    // 如果已经在加载中且skipIfLoading为true，则跳过
    if (currentState.isLoading && event.skipIfLoading) {
      AppLogger.d('Blocs/editor/editor_bloc', '加载请求过于频繁，已被节流');
      return;
    }

    // 增强边界检测逻辑，更严格地检查是否已到达边界
    if (event.direction == 'up') {
      if (currentState.hasReachedStart) {
        AppLogger.i('Blocs/editor/editor_bloc', '已到达内容顶部，跳过向上加载请求');
        // 再次明确设置hasReachedStart标志，以防之前的设置未生效
        emit(currentState.copyWith(
          hasReachedStart: true,
        ));
        return;
      }
    } else if (event.direction == 'down') {
      if (currentState.hasReachedEnd) {
        AppLogger.i('Blocs/editor/editor_bloc', '已到达内容底部，跳过向下加载请求');
        // 再次明确设置hasReachedEnd标志，以防之前的设置未生效
        emit(currentState.copyWith(
          hasReachedEnd: true,
        ));
        return;
      }
    }

    // 设置加载状态
    emit(currentState.copyWith(isLoading: true));

    try {
      AppLogger.i('Blocs/editor/editor_bloc', 
          '开始加载更多场景: 卷ID=${event.actId}, 章节ID=${event.fromChapterId}, 方向=${event.direction}, 章节限制=${event.chaptersLimit}, 防止焦点变化=${event.preventFocusChange}');
      
      // 添加超时处理，避免请求无响应
      final completer = Completer<Map<String, List<novel_models.Scene>>?>();
      
      // 使用Future.any同时处理正常结果和超时
      Future.delayed(const Duration(seconds: 15), () {
        if (!completer.isCompleted) {
          AppLogger.w('Blocs/editor/editor_bloc', '加载请求超时，自动取消');
          completer.complete(null);
        }
      });
      
      // 尝试从本地加载
      if (event.loadFromLocalOnly) {
        AppLogger.i('Blocs/editor/editor_bloc', '尝试仅从本地加载卷 ${event.actId} 章节 ${event.fromChapterId} 的场景');
        // 实现本地加载逻辑
      } else {
        // 从API加载，使用正确的参数格式
        AppLogger.i('Blocs/editor/editor_bloc', '从API加载卷 ${event.actId} 章节 ${event.fromChapterId} 的场景 (方向=${event.direction})');
        
        // 开始API请求但不立即等待
        final futureResult = repository.loadMoreScenes(
          novelId,
          event.actId,
          event.fromChapterId,
          event.direction,
          chaptersLimit: event.chaptersLimit,
        );
        
        // 将API请求结果提交给completer
        futureResult.then((result) {
          if (!completer.isCompleted) {
            completer.complete(result);
          }
        }).catchError((e) {
          if (!completer.isCompleted) {
            AppLogger.e('Blocs/editor/editor_bloc', '加载API调用出错', e);
            completer.complete(null);
          }
        });
      }
      
      // 等待结果或超时
      final result = await completer.future;

      // 检查API返回结果
      if (result != null) {
        if (result.isNotEmpty) {
          // 获取当前状态（可能在API请求期间已经发生变化）
          final updatedState = state as EditorLoaded;

          // 合并新场景到小说结构
          final updatedNovel = _mergeNewScenes(updatedState.novel, result);
          
          // 更新活动章节ID（如果需要）
          String? newActiveChapterId = updatedState.activeChapterId;
          String? newActiveSceneId = updatedState.activeSceneId;
          String? newActiveActId = updatedState.activeActId;

          if (!event.preventFocusChange) {
            // 仅当允许改变焦点时才更新活动章节
            final firstChapterId = result.keys.first;
            final firstChapterScenes = result[firstChapterId];
            
            if (firstChapterScenes != null && firstChapterScenes.isNotEmpty) {
              newActiveChapterId = firstChapterId;
              newActiveSceneId = firstChapterScenes.first.id;
              
              // 查找活动章节所属的Act
              for (final act in updatedNovel.acts) {
                for (final chapter in act.chapters) {
                  if (chapter.id == newActiveChapterId) {
                    newActiveActId = act.id;
                    break;
                  }
                }
                if (newActiveActId != null) break;
              }
            }
          }

          // 设置加载边界标志
          bool hasReachedStart = updatedState.hasReachedStart;
          bool hasReachedEnd = updatedState.hasReachedEnd;
          
          // 根据方向和返回结果判断是否达到边界
          // 如果API返回的结果非常少（比如只有1章），可能也意味着接近边界
          if (event.direction == 'up' && result.length <= 1) {
            hasReachedStart = true;
            AppLogger.i('Blocs/editor/editor_bloc', '向上加载返回数据很少，可能已接近顶部，设置hasReachedStart=true');
          } else if (event.direction == 'down' && result.length <= 1) {
            hasReachedEnd = true;
            AppLogger.i('Blocs/editor/editor_bloc', '向下加载返回数据很少，可能已接近底部，设置hasReachedEnd=true');
          }
          
          // Calculate chapter maps for the updated novel
          final chapterMaps = _calculateChapterMaps(updatedNovel);
          
          // 发送更新后的状态
          emit(EditorLoaded(
            novel: updatedNovel,
            settings: updatedState.settings,
            activeActId: newActiveActId,
            activeChapterId: newActiveChapterId,
            activeSceneId: newActiveSceneId,
            isLoading: false,
            hasReachedStart: hasReachedStart,
            hasReachedEnd: hasReachedEnd,
            focusChapterId: updatedState.focusChapterId,
            chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Added
            chapterToActMap: chapterMaps.chapterToActMap, // Added
          ));
          
          AppLogger.i('Blocs/editor/editor_bloc', '加载更多场景成功，更新了 ${result.length} 个章节');
        } else {
          // API返回空结果，说明该方向没有更多内容了
          // 根据加载方向设置边界标志
          bool hasReachedStart = currentState.hasReachedStart;
          bool hasReachedEnd = currentState.hasReachedEnd;
          
          if (event.direction == 'up') {
            hasReachedStart = true;
            AppLogger.i('Blocs/editor/editor_bloc', '向上没有更多场景可加载，设置hasReachedStart=true');
          } else if (event.direction == 'down') {
            hasReachedEnd = true;
            AppLogger.i('Blocs/editor/editor_bloc', '向下没有更多场景可加载，设置hasReachedEnd=true');
          } else if (event.direction == 'center') {
            // 如果是center方向且返回为空，可能同时到达了顶部和底部
            hasReachedStart = true;
            hasReachedEnd = true;
            AppLogger.i('Blocs/editor/editor_bloc', '中心加载返回为空，设置hasReachedStart=true和hasReachedEnd=true');
          }
          
          // 发送更新状态，包含边界标志
          emit(currentState.copyWith(
            isLoading: false,
            hasReachedStart: hasReachedStart,
            hasReachedEnd: hasReachedEnd,
          ));
          
          AppLogger.i('Blocs/editor/editor_bloc', '没有更多场景可加载，API返回为空');
        }
      } else {
        // API返回null，表示请求失败或超时
        // 这种情况不应标记为已到达边界，因为可能是网络问题
        AppLogger.w('Blocs/editor/editor_bloc', '加载更多场景失败，API返回null');
        emit(currentState.copyWith(
          isLoading: false,
          errorMessage: '加载场景时出现错误，请稍后再试',
        ));
      }
    } catch (e) {
      // 处理异常
      AppLogger.e('Blocs/editor/editor_bloc', '加载更多场景出错', e);
      // 不要在出错时设置边界标志，以免误判
      emit(currentState.copyWith(
        isLoading: false,
        errorMessage: '加载场景时出现错误: ${e.toString()}',
      ));
    }
  }


  Future<void> _onUpdateContent(
      UpdateContent event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      // 更新当前活动场景的内容
      if (currentState.activeActId != null &&
          currentState.activeChapterId != null) {
        final updatedNovel = _updateNovelContent(
          currentState.novel,
          currentState.activeActId!,
          currentState.activeChapterId!,
          event.content,
        );

        emit(currentState.copyWith(
          novel: updatedNovel,
          isDirty: true,
        ));
      }
    }
  }

  Future<void> _onSaveContent(
      SaveContent event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      emit(currentState.copyWith(isSaving: true));

      try {
        // 🚀 优化：首先强制处理所有待保存的场景内容
        if (_pendingSaveScenes.isNotEmpty) {
          AppLogger.i('EditorBloc', '手动保存：先处理${_pendingSaveScenes.length}个待保存场景');
          await _processBatchSaveQueue();
        }

        // 🚀 优化：只保存小说基本信息，不包含场景数据
        await repository.saveNovel(currentState.novel);
        AppLogger.i('EditorBloc', '手动保存：小说基本信息已保存');

        // 🚀 优化：确保当前活动场景也被保存（如果它不在待保存队列中）
        if (currentState.activeActId != null &&
            currentState.activeChapterId != null &&
            currentState.activeSceneId != null) {
          
          final sceneKey = '${currentState.novel.id}_${currentState.activeActId}_${currentState.activeChapterId}_${currentState.activeSceneId}';
          
          // 只有当前场景不在最近保存的列表中时才单独保存
          final lastSaveTime = _lastSceneSaveTime[sceneKey];
          final now = DateTime.now();
          if (lastSaveTime == null || now.difference(lastSaveTime) > Duration(minutes: 1)) {
            try {
              // 获取当前活动场景
              final act = currentState.novel.acts.firstWhere(
                (act) => act.id == currentState.activeActId,
              );
              final chapter = act.chapters.firstWhere(
                (chapter) => chapter.id == currentState.activeChapterId,
              );

              // 获取当前活动场景
              if (chapter.scenes.isNotEmpty) {
                // 查找当前活动场景
                final scene = chapter.scenes.firstWhere(
                  (s) => s.id == currentState.activeSceneId,
                  orElse: () => chapter.scenes.first,
                );

                // 计算字数
                final wordCount = WordCountAnalyzer.countWords(scene.content);

                // 保存场景内容（确保同步到服务器）
                await repository.saveSceneContent(
                  currentState.novel.id,
                  currentState.activeActId!,
                  currentState.activeChapterId!,
                  currentState.activeSceneId!,
                  scene.content,
                  wordCount.toString(),
                  scene.summary,
                  localOnly: false, // 🚀 确保同步到服务器
                );
                
                // 更新最后保存时间
                _lastSceneSaveTime[sceneKey] = now;
                AppLogger.i('EditorBloc', '手动保存：当前活动场景已额外保存');
              }
            } catch (e) {
              AppLogger.e('EditorBloc', '手动保存当前活动场景失败', e);
              // 不抛出异常，因为场景保存失败不应该影响整体保存流程
            }
          } else {
            AppLogger.i('EditorBloc', '手动保存：当前活动场景最近已保存，跳过');
          }
        }

        emit(currentState.copyWith(
          isDirty: false, // 🚀 修复：手动保存后应该清除dirty状态
          isSaving: false,
          lastSaveTime: DateTime.now(),
        ));
      } catch (e) {
        emit(currentState.copyWith(
          isSaving: false,
          errorMessage: e.toString(),
        ));
      }
    }
  }

  // 使用防抖动机制将场景加入批量保存队列
  void _enqueueSceneForBatchSave({
    required String novelId,
    required String actId,
    required String chapterId,
    required String sceneId,
    required String content,
    required String wordCount,
  }) {
    // 首先验证章节和场景是否仍然存在
    if (state is EditorLoaded) {
      final currentState = state as EditorLoaded;
      
      // 查找章节是否存在
      bool chapterExists = false;
      bool sceneExists = false;

      for (final act in currentState.novel.acts) {
        if (act.id == actId) {
          for (final chapter in act.chapters) {
            if (chapter.id == chapterId) {
              chapterExists = true;
              // 检查场景是否存在
              for (final scene in chapter.scenes) {
                if (scene.id == sceneId) {
                  sceneExists = true;
                  break;
                }
              }
              break;
            }
          }
          break;
        }
      }

      if (!chapterExists) {
        AppLogger.w('EditorBloc', '无法保存场景${sceneId}：章节${chapterId}已不存在，跳过保存');
        return;
      }

      if (!sceneExists) {
        AppLogger.w('EditorBloc', '无法保存场景${sceneId}：场景已不存在，跳过保存');
        return;
      }
    }

    // 生成唯一键
    final sceneKey = '${novelId}_${actId}_${chapterId}_$sceneId';
    
    // 检查时间戳节流
    final now = DateTime.now();
    final lastSaveTime = _lastSceneSaveTime[sceneKey];
    if (lastSaveTime != null && now.difference(lastSaveTime) < _sceneSaveDebounceInterval) {
      AppLogger.d('EditorBloc', '场景${sceneId}的保存请求被节流，忽略此次保存');
      
      // 更新待保存数据，但不触发新的保存计时器
      _pendingSaveScenes[sceneKey] = {
        'novelId': novelId,
        'actId': actId,
        'chapterId': chapterId,
        'sceneId': sceneId,
        'id': sceneId, // 添加id字段，与repository.batchSaveSceneContents期望的格式一致
        'content': _ensureValidQuillJson(content),
        'wordCount': int.tryParse(wordCount) ?? 0, // 转换为整数
        'queuedAt': now,
      };
      return;
    }

    // 加入待保存队列
    _pendingSaveScenes[sceneKey] = {
      'novelId': novelId,
      'actId': actId,
      'chapterId': chapterId,
      'sceneId': sceneId,
      'id': sceneId, // 添加id字段，与repository.batchSaveSceneContents期望的格式一致
      'content': _ensureValidQuillJson(content),
      'wordCount': int.tryParse(wordCount) ?? 0, // 转换为整数
      'queuedAt': now,
    };
    
    AppLogger.i('EditorBloc', '将场景${sceneId}加入批量保存队列，当前队列中有${_pendingSaveScenes.length}个场景');
    
    // 取消现有计时器
    _batchSaveDebounceTimer?.cancel();
    
    // 创建新计时器
    _batchSaveDebounceTimer = Timer(_batchSaveInterval, () {
      _processBatchSaveQueue();
    });
  }
  
  // 确保内容是有效的Quill JSON格式
  String _ensureValidQuillJson(String content) {
    // 直接使用QuillHelper工具类处理内容格式
    return QuillHelper.ensureQuillFormat(content);
  }

  /// 防抖更新lastEditedChapterId
  void _updateLastEditedChapterWithDebounce(String chapterId) {
    // 如果是相同的章节ID，不需要更新
    if (_pendingLastEditedChapterId == chapterId) {
      return;
    }

    _pendingLastEditedChapterId = chapterId;
    
    // 取消现有计时器
    _lastEditedChapterUpdateTimer?.cancel();
    
    // 创建新的防抖计时器
    _lastEditedChapterUpdateTimer = Timer(_lastEditedChapterUpdateInterval, () {
      if (_pendingLastEditedChapterId != null) {
        _flushLastEditedChapterUpdate();
      }
    });
    
    AppLogger.d('EditorBloc', '设置lastEditedChapterId防抖更新: $chapterId');
  }

  /// 立即执行lastEditedChapterId更新
  Future<void> _flushLastEditedChapterUpdate() async {
    if (_pendingLastEditedChapterId == null) return;
    
    final chapterId = _pendingLastEditedChapterId!;
    _pendingLastEditedChapterId = null;
    _lastEditedChapterUpdateTimer?.cancel();
    
    try {
      await repository.updateLastEditedChapterId(novelId, chapterId);
      AppLogger.i('EditorBloc', '防抖更新lastEditedChapterId成功: $chapterId');
    } catch (e) {
      AppLogger.e('EditorBloc', '防抖更新lastEditedChapterId失败: $chapterId', e);
    }
  }

  /// 处理批量保存队列
  Future<void> _processBatchSaveQueue() async {
    if (_pendingSaveScenes.isEmpty) return;
    
    AppLogger.i('EditorBloc', '开始处理批量保存队列，共${_pendingSaveScenes.length}个场景');
    
    // 处理前再次验证章节和场景存在性
    if (state is EditorLoaded) {
      final currentState = state as EditorLoaded;
      final novel = currentState.novel;
      
      // 创建需要移除的键列表
      final keysToRemove = <String>[];
      
      // 检查每个待保存场景
      for (final entry in _pendingSaveScenes.entries) {
        final key = entry.key;
        final sceneData = entry.value;
        final String actId = sceneData['actId'] as String;
        final String chapterId = sceneData['chapterId'] as String;
        final String sceneId = sceneData['sceneId'] as String;
        
        // 查找章节和场景是否仍然存在
        bool shouldKeep = false;
        
        for (final act in novel.acts) {
      if (act.id == actId) {
            for (final chapter in act.chapters) {
          if (chapter.id == chapterId) {
                for (final scene in chapter.scenes) {
                  if (scene.id == sceneId) {
                    shouldKeep = true;
                    break;
                  }
                }
                break;
              }
            }
            break;
          }
        }
        
        if (!shouldKeep) {
          keysToRemove.add(key);
          AppLogger.i('EditorBloc', '移除不存在的场景${sceneId}（章节${chapterId}）的保存请求');
        }
      }
      
      // 移除无效条目
      for (final key in keysToRemove) {
        _pendingSaveScenes.remove(key);
      }
      
      // 如果所有条目都被移除，直接返回
      if (_pendingSaveScenes.isEmpty) {
        AppLogger.i('EditorBloc', '批量保存队列为空（所有条目已被移除），跳过保存');
        return;
      }
    }
    
    // 按小说ID分组场景
    final Map<String, List<Map<String, dynamic>>> scenesByNovel = {};
    
    _pendingSaveScenes.forEach((sceneKey, sceneData) {
      final novelId = sceneData['novelId'] as String;
      if (!scenesByNovel.containsKey(novelId)) {
        scenesByNovel[novelId] = [];
      }
      scenesByNovel[novelId]!.add(sceneData);
      
      // 更新最后保存时间
      _lastSceneSaveTime[sceneKey] = DateTime.now();
    });
    
    // 清空待保存队列
    _pendingSaveScenes.clear();
    
    // 按小说批量保存
    for (final entry in scenesByNovel.entries) {
      final novelId = entry.key;
      final scenes = entry.value;
      
      AppLogger.i('EditorBloc', '批量保存小说${novelId}的${scenes.length}个场景');
      
      try {
        // 确保每个场景对象包含所有必要字段
        final List<Map<String, dynamic>> processedScenes = scenes.map((sceneData) {
          // 确保有id字段
          if (sceneData['id'] == null && sceneData['sceneId'] != null) {
            sceneData['id'] = sceneData['sceneId'];
          }
          
          // 移除队列特定的字段
          final processedData = Map<String, dynamic>.from(sceneData);
          processedData.remove('queuedAt'); // 移除仅用于队列的时间戳
          
          // 确保wordCount是整数
          if (processedData['wordCount'] is String) {
            processedData['wordCount'] = int.tryParse(processedData['wordCount']) ?? 0;
          }
          
          return processedData;
        }).toList();
        
        final success = await _batchSaveScenes(processedScenes, novelId);
        if (success) {
          AppLogger.i('EditorBloc', '小说${novelId}的${scenes.length}个场景批量保存成功');
          
          // 🚀 修复：更新保存状态
          _lastSaveTime = DateTime.now();
          _isDirty = false;
          
          // 🚀 新增：批量保存成功后，更新lastEditedChapterId
          // 选择最后排队保存的场景所在的章节作为lastEditedChapterId
          if (scenes.isNotEmpty) {
            // 找到最后排队的场景（按queuedAt时间排序）
            final lastScene = scenes.reduce((a, b) {
              final aTime = a['queuedAt'] as DateTime? ?? DateTime.fromMillisecondsSinceEpoch(0);
              final bTime = b['queuedAt'] as DateTime? ?? DateTime.fromMillisecondsSinceEpoch(0);
              return aTime.isAfter(bTime) ? a : b;
            });
            
            final lastChapterId = lastScene['chapterId'] as String?;
            if (lastChapterId != null) {
              AppLogger.i('EditorBloc', '批量保存后使用防抖更新lastEditedChapterId: $lastChapterId');
              _updateLastEditedChapterWithDebounce(lastChapterId);
            }
          }
          
          // 如果当前状态是EditorLoaded，更新保存状态
          if (state is EditorLoaded) {
            final currentState = state as EditorLoaded;
            
            emit(currentState.copyWith(
              isSaving: false,
              lastSaveTime: DateTime.now(),
              isDirty: false, // 🚀 修复：批量保存成功后清除dirty状态
            ));
          }
        } else {
          AppLogger.e('EditorBloc', '小说${novelId}的场景批量保存失败');
          // 🚀 修复：保存失败时不清除dirty状态
          if (state is EditorLoaded) {
            final currentState = state as EditorLoaded;
            emit(currentState.copyWith(
              isSaving: false,
              errorMessage: '批量保存失败',
            ));
          }
        }
      } catch (e) {
        AppLogger.e('EditorBloc', '批量保存出错: $e');
        // 🚀 修复：保存出错时不清除dirty状态
        if (state is EditorLoaded) {
          final currentState = state as EditorLoaded;
          emit(currentState.copyWith(
            isSaving: false,
            errorMessage: '批量保存出错: $e',
          ));
        }
      }
    }
  }

  // 修改现有的_onUpdateSceneContent方法，使用优化的批量保存
  Future<void> _onUpdateSceneContent(
      UpdateSceneContent event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      final isMinorChange = event.isMinorChange ?? false;
      
      // 验证章节和场景是否仍然存在
      bool chapterExists = false;
      bool sceneExists = false;
      
      for (final act in currentState.novel.acts) {
        if (act.id == event.actId) {
          for (final chapter in act.chapters) {
            if (chapter.id == event.chapterId) {
              chapterExists = true;
              
              for (final scene in chapter.scenes) {
                if (scene.id == event.sceneId) {
                  sceneExists = true;
                  break;
                }
              }
              break;
            }
          }
          break;
        }
      }
      
      if (!chapterExists) {
        AppLogger.e('EditorBloc', '更新场景内容失败：找不到指定的Chapter');
        emit(currentState.copyWith(
            isSaving: false,
          errorMessage: '更新场景内容失败：找不到指定的Chapter',
        ));
        return;
      }
      
      if (!sceneExists) {
        AppLogger.e('EditorBloc', '更新场景内容失败：找不到指定的Scene');
        emit(currentState.copyWith(
          isSaving: false,
          errorMessage: '更新场景内容失败：找不到指定的Scene',
        ));
        return;
      }
      
      // 记录输入的字数
      AppLogger.i('EditorBloc',
          '接收到场景内容更新 - 场景ID: ${event.sceneId}, 字数: ${event.wordCount}, 是否小改动: $isMinorChange');

      // 验证并确保内容是有效的Quill JSON格式
      final String validContent = _ensureValidQuillJson(event.content);

      // 更新指定场景的内容（现在_updateSceneContent会自动更新lastEditedChapterId）
      final updatedNovel = _updateSceneContent(
        currentState.novel,
        event.actId,
        event.chapterId,
          event.sceneId,
        validContent, // 使用验证后的内容
      );

      // 🚀 修复：判断是否需要立即更新UI状态
      final bool shouldUpdateUiState = !isMinorChange;
      
      // 🚀 简化：统一更新小说数据和dirty状态
      emit(currentState.copyWith(
        novel: updatedNovel,
        isDirty: true, // 🚀 有未保存的更改
      ));

      // 使用传递的字数或重新计算
      final wordCount = event.wordCount ??
          WordCountAnalyzer.countWords(event.content).toString();

      // 将场景加入批量保存队列
      _enqueueSceneForBatchSave(
        novelId: event.novelId,
        actId: event.actId,
        chapterId: event.chapterId,
        sceneId: event.sceneId,
        content: validContent, // 使用验证后的内容
        wordCount: wordCount,
      );
    }
  }

  Future<void> _onUpdateSummary(
      UpdateSummary event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      try {
        // 添加防抖控制 - 使用场景ID作为键
        final String cacheKey = event.sceneId;
        final now = DateTime.now();
        final lastRequestTime = _lastSummaryUpdateRequestTime[cacheKey];
        
        if (lastRequestTime != null && 
            now.difference(lastRequestTime) < _summaryUpdateRequestInterval) {
          AppLogger.i('Blocs/editor/editor_bloc', 
              '摘要更新请求频率过高，跳过此次请求: ${event.sceneId}');
          return;
        }
        
        // 记录本次请求时间
        _lastSummaryUpdateRequestTime[cacheKey] = now;
        
        emit(currentState.copyWith(isSaving: true));
        
        AppLogger.i('Blocs/editor/editor_bloc',
            '更新场景摘要: novelId=${event.novelId}, actId=${event.actId}, chapterId=${event.chapterId}, sceneId=${event.sceneId}');
        
        // 查找场景和对应的摘要
        novel_models.Scene? sceneToUpdate;
        for (final act in currentState.novel.acts) {
          if (act.id == event.actId) {
            for (final chapter in act.chapters) {
              if (chapter.id == event.chapterId) {
                for (final scene in chapter.scenes) {
                  if (scene.id == event.sceneId) {
                    sceneToUpdate = scene;
                    break;
                  }
                }
                break;
              }
            }
            break;
          }
        }
        
        if (sceneToUpdate == null) {
          AppLogger.e('Blocs/editor/editor_bloc',
              '找不到要更新摘要的场景: ${event.sceneId}');
          emit(currentState.copyWith(
            isSaving: false,
            errorMessage: '找不到要更新摘要的场景',
          ));
          return;
        }
        
        // 创建新的摘要对象
        final updatedSummary = novel_models.Summary(
          id: sceneToUpdate.summary.id,
          content: event.summary,
        );
        
        // 使用repository保存摘要
        final success = await repository.updateSummary(
          event.novelId,
          event.actId,
          event.chapterId,
          event.sceneId,
          event.summary,
        );
        
        if (!success) {
          throw Exception('更新摘要失败');
        }
        
        // 创建更新后的场景
        final updatedScene = sceneToUpdate.copyWith(
          summary: updatedSummary,
        );
        
        // 更新小说中的场景
        final updatedNovel = _updateNovelScene(
          currentState.novel,
          event.actId,
          event.chapterId,
          updatedScene,
        );
        
        // 保存成功后，更新状态
        emit(currentState.copyWith(
          novel: updatedNovel,
          isDirty: false,
          isSaving: false,
          lastSaveTime: DateTime.now(),
        ));
        
        AppLogger.i('Blocs/editor/editor_bloc',
            '场景摘要更新成功: ${event.sceneId}');
      } catch (e) {
        AppLogger.e('Blocs/editor/editor_bloc', '更新场景摘要失败', e);
        emit(currentState.copyWith(
          isSaving: false,
          errorMessage: '更新场景摘要失败: ${e.toString()}',
        ));
      }
    }
  }

  // 辅助方法：查找章节所属的Act ID
  String? _findActIdForChapter(novel_models.Novel novel, String chapterId) {
    for (final act in novel.acts) {
      for (final chapter in act.chapters) {
        if (chapter.id == chapterId) {
          return act.id;
        }
      }
    }
    return null;
  }

  @override
  Future<void> close() async {
    // 立即执行任何待处理的lastEditedChapterId更新
    await _flushLastEditedChapterUpdate();
    
    // 取消所有计时器
    _autoSaveTimer?.cancel();
    _batchSaveDebounceTimer?.cancel();
    _lastEditedChapterUpdateTimer?.cancel();
    
    // 取消生成流订阅
    _generationStreamSubscription?.cancel();
    
    return super.close();
  }

  // 批量保存多个场景内容的辅助方法
  Future<bool> _batchSaveScenes(List<Map<String, dynamic>> sceneUpdates, String novelId) async {
    if (sceneUpdates.isEmpty) return true;
    
    try {
      // 确保每个场景都有必要的字段
      final processedUpdates = sceneUpdates.map((scene) {
        // 确保每个场景都有novelId
        final updated = Map<String, dynamic>.from(scene);
        updated['novelId'] = novelId;
        
        // 确保每个场景都有chapterId和actId
        if (updated['chapterId'] == null || updated['chapterId'].toString().isEmpty) {
          AppLogger.w('EditorBloc/_batchSaveScenes', '场景缺少chapterId: ${updated['id']}，跳过该场景');
          return null; // 返回null表示这个场景无效
        }
        
        if (updated['actId'] == null || updated['actId'].toString().isEmpty) {
          AppLogger.w('EditorBloc/_batchSaveScenes', '场景缺少actId: ${updated['id']}，跳过该场景');
          return null; // 返回null表示这个场景无效
        }
        
        return updated;
      }).where((scene) => scene != null).cast<Map<String, dynamic>>().toList();
      
      if (processedUpdates.isEmpty) {
        AppLogger.w('EditorBloc/_batchSaveScenes', '处理后没有有效场景可以保存');
        return false;
      }
      
      // 记录一下要发送的数据，便于调试
      AppLogger.i('EditorBloc/_batchSaveScenes', '批量保存${processedUpdates.length}个场景，novelId=${novelId}');
      
      final result = await repository.batchSaveSceneContents(novelId, processedUpdates);
      if (result) {
        AppLogger.i('EditorBloc/_batchSaveScenes', '批量保存场景成功: ${processedUpdates.length}个场景');
      } else {
        AppLogger.e('EditorBloc/_batchSaveScenes', '批量保存场景失败');
      }
      return result;
    } catch (e) {
      AppLogger.e('EditorBloc/_batchSaveScenes', '批量保存场景出错', e);
      return false;
    }
  }



  // 将新加载的场景合并到当前小说结构中
  novel_models.Novel _mergeNewScenes(
    novel_models.Novel novel,
    Map<String, List<novel_models.Scene>> newScenes) {
    
    // 创建当前小说acts的深拷贝，以便修改
    final List<novel_models.Act> updatedActs = novel.acts.map((act) {
      // 为每个Act创建深拷贝，以便修改其中的章节
      final List<novel_models.Chapter> updatedChapters = act.chapters.map((chapter) {
        // 检查是否有该章节的新场景
        if (newScenes.containsKey(chapter.id)) {
          // 合并新场景和现有场景
          List<novel_models.Scene> existingScenes = List.from(chapter.scenes);
          List<novel_models.Scene> scenesToAdd = List.from(newScenes[chapter.id]!);
          
          // 创建场景ID到场景的映射，用于快速查找和合并
          Map<String, novel_models.Scene> sceneMap = {};
          for (var scene in existingScenes) {
            sceneMap[scene.id] = scene;
          }
          
          // 合并场景列表，优先使用新加载的场景
          for (var scene in scenesToAdd) {
            sceneMap[scene.id] = scene;
          }
          
          // 将合并后的场景转换回列表
          // 注意：这种基于Map的合并方式不保证场景的原始顺序。
          // 如果场景顺序很重要，并且API返回的scenesToAdd是有序的，
          // 或者场景对象自身没有可用于排序的字段（如order），
          // 则可能需要更复杂的合并逻辑来保留或重建正确的顺序。
          List<novel_models.Scene> mergedScenes = sceneMap.values.toList();
          
          // 创建更新后的章节
          return chapter.copyWith(scenes: mergedScenes);
        }
        // 如果没有该章节的新场景，则返回原章节
        return chapter;
      }).toList();
      
      // 返回更新后的Act
      return act.copyWith(chapters: updatedChapters);
    }).toList();
    
    // 在返回更新后的小说之前记录一些渲染相关的日志
    AppLogger.i('EditorBloc', '合并了${newScenes.length}个章节的场景，可能需要重新渲染');
    return novel.copyWith(acts: updatedActs);
  }

  // 更新小说内容的辅助方法
  novel_models.Novel _updateNovelContent(
    novel_models.Novel novel,
    String actId,
    String chapterId,
    String content) {
    
    // 创建当前小说acts的深拷贝以便修改
    final List<novel_models.Act> updatedActs = novel.acts.map((act) {
      if (act.id == actId) {
        // 更新指定Act的章节
        final List<novel_models.Chapter> updatedChapters = act.chapters.map((chapter) {
          if (chapter.id == chapterId) {
            // 找到指定章节，更新其第一个场景的内容
            if (chapter.scenes.isNotEmpty) {
              final List<novel_models.Scene> updatedScenes = List.from(chapter.scenes);
              final novel_models.Scene firstScene = updatedScenes.first;
              
              // 更新场景内容
              updatedScenes[0] = firstScene.copyWith(
                content: content,
              );
              
              return chapter.copyWith(scenes: updatedScenes);
            }
          }
          return chapter;
        }).toList();
        
        return act.copyWith(chapters: updatedChapters);
      }
      return act;
    }).toList();
    
    // 返回更新后的小说，同时更新最后编辑章节
    return novel.copyWith(
      acts: updatedActs,
      lastEditedChapterId: chapterId,
    );
  }

  // 更新小说场景的辅助方法
  novel_models.Novel _updateNovelScene(
    novel_models.Novel novel,
    String actId,
    String chapterId,
    novel_models.Scene updatedScene) {
    
    // 创建当前小说acts的深拷贝以便修改
    final List<novel_models.Act> updatedActs = novel.acts.map((act) {
      if (act.id == actId) {
        // 更新指定Act的章节
        final List<novel_models.Chapter> updatedChapters = act.chapters.map((chapter) {
          if (chapter.id == chapterId) {
            // 找到指定章节，更新其场景
            final List<novel_models.Scene> updatedScenes = chapter.scenes.map((scene) {
              if (scene.id == updatedScene.id) {
                // 返回更新后的场景
                return updatedScene;
              }
              return scene;
            }).toList();
            
            return chapter.copyWith(scenes: updatedScenes);
          }
          return chapter;
        }).toList();
        
        return act.copyWith(chapters: updatedChapters);
      }
      return act;
    }).toList();
    
    // 返回更新后的小说，同时更新最后编辑章节
    return novel.copyWith(
      acts: updatedActs,
      lastEditedChapterId: chapterId,
    );
  }

  // 更新场景内容的辅助方法
  novel_models.Novel _updateSceneContent(
    novel_models.Novel novel,
    String actId,
    String chapterId,
    String sceneId,
    String content) {
    
    // 创建当前小说acts的深拷贝以便修改
    final List<novel_models.Act> updatedActs = novel.acts.map((act) {
      if (act.id == actId) {
        // 更新指定Act的章节
        final List<novel_models.Chapter> updatedChapters = act.chapters.map((chapter) {
          if (chapter.id == chapterId) {
            // 找到指定章节，更新其场景
            final List<novel_models.Scene> updatedScenes = chapter.scenes.map((scene) {
              if (scene.id == sceneId) {
                // 更新场景内容
                return scene.copyWith(
                  content: content,
                );
              }
              return scene;
            }).toList();
            
            return chapter.copyWith(scenes: updatedScenes);
          }
          return chapter;
        }).toList();
        
        return act.copyWith(chapters: updatedChapters);
      }
      return act;
    }).toList();
    
    // 返回更新后的小说，同时更新最后编辑章节
    return novel.copyWith(
      acts: updatedActs,
      lastEditedChapterId: chapterId,
    );
  }

  // 设置活动章节
  Future<void> _onSetActiveChapter(
      SetActiveChapter event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      // 🚀 优化：检查状态是否真的需要改变
      bool needsUpdate = false;
      String? newActiveActId = currentState.activeActId;
      String? newActiveChapterId = currentState.activeChapterId;
      String? newActiveSceneId = currentState.activeSceneId;
      
      // 检查Act是否需要更新
      if (currentState.activeActId != event.actId) {
        needsUpdate = true;
        newActiveActId = event.actId;
      }
      
      // 检查Chapter是否需要更新
      if (currentState.activeChapterId != event.chapterId) {
        needsUpdate = true;
        newActiveChapterId = event.chapterId;
        
        // 🚀 新增：章节切换时，立即执行任何待处理的lastEditedChapterId更新
        await _flushLastEditedChapterUpdate();
        
        // 只有在章节发生变化时才查找第一个场景
        String? firstSceneId;
        for (final act in currentState.novel.acts) {
          if (act.id == event.actId) {
            for (final chapter in act.chapters) {
              if (chapter.id == event.chapterId && chapter.scenes.isNotEmpty) {
                firstSceneId = chapter.scenes.first.id;
                break;
              }
            }
            break;
          }
        }
        newActiveSceneId = firstSceneId;
      }
      
      // 🚀 只有在真的需要更新时才emit新状态
      if (needsUpdate) {
        // 记录日志
        AppLogger.i('EditorBloc', '设置活动章节: ${event.actId}/${event.chapterId}, 活动场景: $newActiveSceneId');
        
        emit(currentState.copyWith(
          activeActId: newActiveActId,
          activeChapterId: newActiveChapterId,
          activeSceneId: newActiveSceneId,
          lastUpdateSilent: event.silent, // 🚀 标记是否为静默更新
        ));
      } else {
        // 状态没有变化，记录日志但不emit
        AppLogger.v('EditorBloc', '跳过设置活动章节：状态未发生变化 ${event.actId}/${event.chapterId}');
      }
    }
  }

  // 设置活动场景
  Future<void> _onSetActiveScene(
      SetActiveScene event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      // 🚀 优化：检查状态是否真的需要改变
      bool needsUpdate = false;
      
      // 检查任何一个ID是否发生变化
      if (currentState.activeActId != event.actId ||
          currentState.activeChapterId != event.chapterId ||
          currentState.activeSceneId != event.sceneId) {
        needsUpdate = true;
      }
      
      // 🚀 只有在真的需要更新时才emit新状态
      if (needsUpdate) {
        AppLogger.i('EditorBloc', '设置活动场景: ${event.actId}/${event.chapterId}/${event.sceneId}');
        
        emit(currentState.copyWith(
          activeActId: event.actId,
          activeChapterId: event.chapterId,
          activeSceneId: event.sceneId,
          lastUpdateSilent: event.silent, // 🚀 标记是否为静默更新
        ));
      } else {
        // 状态没有变化，记录日志但不emit
        AppLogger.v('EditorBloc', '跳过设置活动场景：状态未发生变化 ${event.actId}/${event.chapterId}/${event.sceneId}');
      }
    }
  }

  // 🚀 新增：加载用户编辑器设置
  Future<void> _onLoadUserEditorSettings(
      LoadUserEditorSettings event, Emitter<EditorState> emit) async {
    try {
      AppLogger.i('EditorBloc', '开始加载用户编辑器设置: userId=${event.userId}');
      
      // 🚀 修正：EditorRepositoryImpl没有getUserEditorSettings方法
      // 需要使用NovelRepositoryImpl或从其他地方获取
      // 暂时使用默认设置，并添加TODO注释
      AppLogger.w('EditorBloc', 'TODO: 需要实现从NovelRepository获取用户编辑器设置的逻辑');
      
      // 使用默认设置
      const defaultSettings = EditorSettings();
      final settingsMap = defaultSettings.toMap();
      
      AppLogger.i('EditorBloc', '使用默认编辑器设置，字体大小: ${defaultSettings.fontSize}');
      
      // 更新当前状态的设置
      final currentState = state;
      if (currentState is EditorLoaded) {
        emit(currentState.copyWith(settings: settingsMap));
      } else {
        AppLogger.d('EditorBloc', '编辑器尚未加载完成，将在加载完成后应用设置');
      }
      
    } catch (e) {
      AppLogger.e('EditorBloc', '加载用户编辑器设置失败: ${e}');
      // 加载失败时使用默认设置
      const defaultSettings = EditorSettings();
      final defaultSettingsMap = defaultSettings.toMap();
      
      final currentState = state;
      if (currentState is EditorLoaded) {
        emit(currentState.copyWith(settings: defaultSettingsMap));
      }
    }
  }

  // 更新编辑器设置
  Future<void> _onUpdateSettings(
      UpdateEditorSettings event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      emit(currentState.copyWith(
        settings: event.settings,
      ));
      
      // 保存设置到本地存储
      try {
        await repository.saveEditorSettings(event.settings);
      } catch (e) {
        AppLogger.e('Blocs/editor/editor_bloc', '保存编辑器设置失败', e);
      }
    }
  }

  // 删除Scene
  Future<void> _onDeleteScene(
      DeleteScene event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      try {
        emit(currentState.copyWith(isSaving: true));
        
        AppLogger.i('Blocs/editor/editor_bloc',
            '删除场景: novelId=${event.novelId}, actId=${event.actId}, chapterId=${event.chapterId}, sceneId=${event.sceneId}');
        
        // 查找要删除的场景
        novel_models.Scene? sceneToDelete;
        novel_models.Chapter? parentChapter;
        novel_models.Act? parentAct;
        
        for (final act in currentState.novel.acts) {
          if (act.id == event.actId) {
            parentAct = act;
            for (final chapter in act.chapters) {
              if (chapter.id == event.chapterId) {
                parentChapter = chapter;
                for (final scene in chapter.scenes) {
                  if (scene.id == event.sceneId) {
                    sceneToDelete = scene;
                    break;
                  }
                }
                break;
              }
            }
            break;
          }
        }
        
        if (sceneToDelete == null || parentChapter == null || parentAct == null) {
          AppLogger.e('Blocs/editor/editor_bloc',
              '找不到要删除的场景: ${event.sceneId}');
          emit(currentState.copyWith(
            isSaving: false,
            errorMessage: '找不到要删除的场景',
          ));
          return;
        }
        
        // 创建不包含要删除场景的新场景列表
        final updatedScenes = parentChapter.scenes
            .where((scene) => scene.id != event.sceneId)
            .toList();
        
        // 如果该章节没有更多场景，可以考虑提示用户
        final bool isLastSceneInChapter = updatedScenes.isEmpty;
        
        // 更新章节
        final updatedChapter = parentChapter.copyWith(
          scenes: updatedScenes,
        );
        
        // 更新所在Act的章节列表
        final updatedChapters = parentAct.chapters.map((chapter) {
          if (chapter.id == event.chapterId) {
            return updatedChapter;
          }
          return chapter;
        }).toList();
        
        // 更新Act
        final updatedAct = parentAct.copyWith(
          chapters: updatedChapters,
        );
        
        // 更新小说的Acts列表
        final updatedActs = currentState.novel.acts.map((act) {
          if (act.id == event.actId) {
            return updatedAct;
          }
          return act;
        }).toList();
        
        // 创建更新后的小说模型
        final updatedNovel = currentState.novel.copyWith(
          acts: updatedActs,
          updatedAt: DateTime.now(),
        );
        
        // 清除该场景的所有保存请求
        _cleanupPendingSaveForScene(event.sceneId);
        
        // 如果删除的是当前活动场景，确定下一个活动场景
        String? newActiveSceneId = currentState.activeSceneId;
        if (currentState.activeSceneId == event.sceneId) {
          if (updatedScenes.isNotEmpty) {
            // 如果章节还有其他场景，选择第一个
            newActiveSceneId = updatedScenes.first.id;
          } else {
            // 章节没有场景了，将活动场景设为null
            newActiveSceneId = null;
          }
        }
        
        // Calculate chapter maps for the updated novel
        final chapterMaps = _calculateChapterMaps(updatedNovel);

        // 在UI上标记为正在处理
        emit(currentState.copyWith(
          novel: updatedNovel,
          activeSceneId: newActiveSceneId,
          isDirty: true,
          isSaving: true,
          chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Added
          chapterToActMap: chapterMaps.chapterToActMap, // Added
        ));
        
        // 调用API删除场景
        final success = await repository.deleteScene(
          event.novelId,
          event.actId,
          event.chapterId,
          event.sceneId,
        );
        
        if (!success) {
          throw Exception('删除场景失败');
        }
        
        // 保存成功后，更新状态
        emit(currentState.copyWith(
          novel: updatedNovel,
          activeSceneId: newActiveSceneId,
          isDirty: false,
          isSaving: false,
          lastSaveTime: DateTime.now(),
          chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Ensure maps are consistent
          chapterToActMap: chapterMaps.chapterToActMap,       // Ensure maps are consistent
        ));
        
        // 持久化：确保删除后的小说结构写回本地缓存
        await repository.saveNovel(updatedNovel);
        
        AppLogger.i('Blocs/editor/editor_bloc',
            '场景删除成功: ${event.sceneId}');
        
        // 如果删除的是最后一个场景，提示用户考虑添加新场景
        if (isLastSceneInChapter) {
          AppLogger.i('Blocs/editor/editor_bloc',
              '章节 ${event.chapterId} 现在没有场景了');
          // 这里可以添加一些逻辑来提示用户添加场景
        }
      } catch (e) {
        AppLogger.e('Blocs/editor/editor_bloc', '删除场景失败', e);
        emit(currentState.copyWith(
          isSaving: false,
          errorMessage: '删除场景失败: ${e.toString()}',
        ));
      }
    }
  }

  // 在场景删除后清理该场景的保存请求
  void _cleanupPendingSaveForScene(String sceneId) {
    final keysToRemove = <String>[];
    
    _pendingSaveScenes.forEach((key, data) {
      if (data['sceneId'] == sceneId) {
        keysToRemove.add(key);
      }
    });
    
    for (final key in keysToRemove) {
      _pendingSaveScenes.remove(key);
      AppLogger.i('EditorBloc', '已从保存队列中移除场景: ${sceneId}');
    }
  }

  Future<void> _onAddNewAct(
      AddNewAct event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      try {
        // 开始保存状态
        emit(currentState.copyWith(isSaving: true));
        
        AppLogger.i('EditorBloc/_onAddNewAct', '开始添加新Act: title=${event.title}');
        
        // 调用API创建新Act
        final updatedNovel = await repository.addNewAct(
          novelId,
          event.title,
        );
        
        if (updatedNovel == null) {
          AppLogger.e('EditorBloc/_onAddNewAct', '添加新Act失败，API返回null');
          emit(currentState.copyWith(
            isSaving: false,
            errorMessage: '添加新Act失败：无法获取更新后的小说数据',
          ));
          return;
        }
        
        // 检查是否成功添加了新Act
        if (updatedNovel.acts.length > currentState.novel.acts.length) {
          AppLogger.i('EditorBloc/_onAddNewAct', 
              '成功添加新Act：之前${currentState.novel.acts.length}个，现在${updatedNovel.acts.length}个');
          
          // 设置新添加的Act为活动Act
          final newAct = updatedNovel.acts.last;
          
          // Calculate chapter maps for the updated novel
          final chapterMaps = _calculateChapterMaps(updatedNovel);

          // 发出更新状态
          emit(currentState.copyWith(
            novel: updatedNovel,
            isSaving: false,
            isDirty: false,
            activeActId: newAct.id,
            // 如果新Act有章节，设置第一个章节为活动章节
            activeChapterId: newAct.chapters.isNotEmpty ? newAct.chapters.first.id : null,
            // 清除活动场景
            activeSceneId: null,
            chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Added
            chapterToActMap: chapterMaps.chapterToActMap, // Added
          ));
          
          AppLogger.i('EditorBloc/_onAddNewAct', '已更新UI状态，设置新Act为活动Act: ${newAct.id}');
        } else {
          AppLogger.w('EditorBloc/_onAddNewAct', 
              '添加Act可能失败：之前${currentState.novel.acts.length}个，现在${updatedNovel.acts.length}个');
          
          // Calculate chapter maps even if the addition might have issues, to reflect current state
          final chapterMaps = _calculateChapterMaps(updatedNovel);

          // 仍然更新状态以刷新UI
          emit(currentState.copyWith(
            novel: updatedNovel,
            isSaving: false,
            errorMessage: 'Act可能未成功添加，请检查网络连接',
            chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Added
            chapterToActMap: chapterMaps.chapterToActMap, // Added
          ));
        }
      } catch (e) {
        AppLogger.e('EditorBloc/_onAddNewAct', '添加新Act过程中发生异常', e);
        emit(currentState.copyWith(
          isSaving: false,
          errorMessage: '添加新Act失败: ${e.toString()}',
        ));
      }
    }
  }

  /// 添加新章节
  Future<void> _onAddNewChapter(
      AddNewChapter event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      try {
        // 开始保存状态
        emit(currentState.copyWith(isSaving: true));
        
        AppLogger.i('EditorBloc/_onAddNewChapter', 
            '开始添加新Chapter: novelId=${event.novelId}, actId=${event.actId}, title=${event.title}');
        
        // 调用API创建新Chapter
        final updatedNovel = await repository.addNewChapter(
          event.novelId,
          event.actId,
          event.title,
        );
        
        if (updatedNovel == null) {
          AppLogger.e('EditorBloc/_onAddNewChapter', '添加新Chapter失败，API返回null');
          emit(currentState.copyWith(
            isSaving: false,
            errorMessage: '添加新Chapter失败：无法获取更新后的小说数据',
          ));
          return;
        }
        
        // 获取更新后Act中的新章节
        novel_models.Act? updatedAct;
        novel_models.Chapter? newChapter;
        
        for (final act in updatedNovel.acts) {
          if (act.id == event.actId) {
            updatedAct = act;
            if (act.chapters.isNotEmpty) {
              // 通常新章节会被添加到末尾
              newChapter = act.chapters.last;
            }
            break;
          }
        }
        
        if (updatedAct == null || newChapter == null) {
          AppLogger.w('EditorBloc/_onAddNewChapter', 
              '无法确定新添加的章节，使用更新后的小说数据');
          
          // Calculate chapter maps for the updated novel
          final chapterMaps = _calculateChapterMaps(updatedNovel);
          // 仍然更新状态
          emit(currentState.copyWith(
            novel: updatedNovel,
            isSaving: false,
            isDirty: false,
            chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Added
            chapterToActMap: chapterMaps.chapterToActMap, // Added
          ));
          return;
        }
        
        AppLogger.i('EditorBloc/_onAddNewChapter', 
            '成功添加新章节: actId=${updatedAct.id}, chapterId=${newChapter.id}');
        
        // Calculate chapter maps for the updated novel
        final chapterMaps = _calculateChapterMaps(updatedNovel);

        // 发出更新状态，并设置新章节为活动章节
        emit(currentState.copyWith(
          novel: updatedNovel,
          isSaving: false,
          isDirty: false,
          activeActId: updatedAct.id,
          activeChapterId: newChapter.id,
          focusChapterId: newChapter.id, // <--- 确保设置焦点到新章节
          // 清除活动场景，因为新章节还没有场景
          activeSceneId: null,
          chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Added
          chapterToActMap: chapterMaps.chapterToActMap, // Added
        ));
        
        AppLogger.i('EditorBloc/_onAddNewChapter', 
            '已更新UI状态，设置新章节为活动章节: ${newChapter.id}');
      } catch (e) {
        AppLogger.e('EditorBloc/_onAddNewChapter', '添加新章节过程中发生异常', e);
        emit(currentState.copyWith(
          isSaving: false,
          errorMessage: '添加新章节失败: ${e.toString()}',
        ));
      }
    }
  }

  // 修改SaveSceneContent处理器也使用相同的JSON验证
  Future<void> _onSaveSceneContent(
      SaveSceneContent event, Emitter<EditorState> emit) async {
    AppLogger.i('EditorBloc',
        '接收到场景内容更新 - 场景ID: ${event.sceneId}, 字数: ${event.wordCount}');
    final currentState = state;
    if (currentState is EditorLoaded) {

      try {
        // 🚀 修复：立即更新状态为正在保存
        emit(currentState.copyWith(isSaving: true));

        // 找到要更新的章节和场景
        final chapter = currentState.novel.acts
            .firstWhere(
                (act) => act.id == event.actId,
                orElse: () => throw Exception('找不到指定的Act'))
            .chapters
            .firstWhere(
                (chapter) => chapter.id == event.chapterId,
                orElse: () => throw Exception('找不到指定的Chapter'));

        // 获取场景摘要（保持不变）
        final sceneSummary =
            chapter.scenes.firstWhere((s) => s.id == event.sceneId).summary;

        // 确保内容是有效的Quill JSON格式
        final String validContent = _ensureValidQuillJson(event.content);

        // 仅保存场景内容（细粒度更新）- 根据参数决定是否同步到服务器
        final updatedScene = await repository.saveSceneContent(
          event.novelId,
          event.actId,
          event.chapterId,
          event.sceneId,
          validContent, // 使用验证后的内容
          event.wordCount,
          sceneSummary,
          localOnly: event.localOnly, // 新增参数：是否仅保存到本地
        );

        // 更新小说里的场景信息
        final finalNovel = _updateNovelScene(
          currentState.novel,
          event.actId,
          event.chapterId,
          updatedScene,
        );

        // 更新最后编辑的章节ID
        var novelWithLastEdited = finalNovel;
        if (finalNovel.lastEditedChapterId != event.chapterId) {
          novelWithLastEdited = finalNovel.copyWith(
            lastEditedChapterId: event.chapterId,
          );
        }

        AppLogger.i('EditorBloc',
            '场景保存成功，更新状态 - 场景ID: ${event.sceneId}, 最终字数: ${updatedScene.wordCount}');

        // 仅当需要同步到服务器时才更新lastEditedChapterId
        if (!event.localOnly && 
            novelWithLastEdited.lastEditedChapterId != currentState.novel.lastEditedChapterId) {
          AppLogger.i('EditorBloc', '使用防抖机制更新最后编辑章节ID: ${novelWithLastEdited.lastEditedChapterId}');
          // 使用防抖机制更新，避免频繁请求
          _updateLastEditedChapterWithDebounce(novelWithLastEdited.lastEditedChapterId!);
        }

        // 🚀 修复：轻量的isDirty状态管理
        // 本地保存成功后立即清除isDirty，提供即时反馈
        // 如果是同步到服务器，则更新lastSaveTime
        emit(currentState.copyWith(
          novel: novelWithLastEdited,
          isDirty: false, // 已保存
          isSaving: false,
          lastSaveTime: DateTime.now(), // 无论是否同步到服务器都更新时间戳，便于UI显示
        ));
      } catch (e) {
        AppLogger.e('Blocs/editor/editor_bloc', '保存场景内容失败', e);
        emit(currentState.copyWith(
          isSaving: false,
          errorMessage: '保存场景内容失败: ${e.toString()}',
        ));
      }
    }
  }

  // 添加新Scene
  Future<void> _onAddNewScene(
      AddNewScene event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      emit(currentState.copyWith(isSaving: true));

      try {
        AppLogger.i('EditorBloc', '添加新场景 - actId: ${event.actId}, chapterId: ${event.chapterId}');
        
        // 1. 创建新场景
        final newScene = novel_models.Scene.createDefault("scene_${DateTime.now().millisecondsSinceEpoch}");
        
        // 2. 添加场景到API
        final addedScene = await repository.addScene(
          novelId,
          event.actId,
          event.chapterId,
          newScene,
        );
        
        if (addedScene == null) {
          throw Exception('添加场景失败，API返回为空');
        }
        
        // 3. 在本地模型中找到对应章节并添加场景
        final updatedNovel = _addSceneToNovel(
          currentState.novel,
          event.actId,
          event.chapterId,
          addedScene,
        );
        
        // 4. 更新状态
        emit(currentState.copyWith(
          novel: updatedNovel,
          isSaving: false,
          isDirty: false,
          // 立即将新场景设置为活动场景
          activeActId: event.actId,
          activeChapterId: event.chapterId,
          activeSceneId: addedScene.id,
        ));
        
        // 持久化：避免后续基于旧缓存的结构操作覆盖新增场景
        await repository.saveNovel(updatedNovel);
        
        AppLogger.i('EditorBloc', '场景添加成功，ID: ${addedScene.id}');
      } catch (e) {
        AppLogger.e('EditorBloc', '添加场景失败: ${e.toString()}');
        emit(currentState.copyWith(
          isSaving: false,
          errorMessage: '添加场景失败: ${e.toString()}',
        ));
      }
    }
  }
  
  // 辅助方法：将场景添加到小说模型中
  novel_models.Novel _addSceneToNovel(
    novel_models.Novel novel,
    String actId,
    String chapterId,
    novel_models.Scene newScene,
  ) {
    // 创建当前小说acts的深拷贝以便修改
    final List<novel_models.Act> updatedActs = novel.acts.map((act) {
      if (act.id == actId) {
        // 更新指定Act的章节
        final List<novel_models.Chapter> updatedChapters = act.chapters.map((chapter) {
          if (chapter.id == chapterId) {
            // 找到指定章节，添加场景
            final List<novel_models.Scene> updatedScenes = List.from(chapter.scenes)
              ..add(newScene);
            
            return chapter.copyWith(scenes: updatedScenes);
          }
          return chapter;
        }).toList();
        
        return act.copyWith(chapters: updatedChapters);
      }
      return act;
    }).toList();
    
    // 返回更新后的小说，同时更新最后编辑章节
    return novel.copyWith(
      acts: updatedActs,
      lastEditedChapterId: chapterId,
    );
  }

  // 删除Chapter
  Future<void> _onDeleteChapter(
      DeleteChapter event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      // 保存原始小说数据，以便在失败时恢复
      final originalNovel = currentState.novel;

      // 查找章节在哪个Act中以及对应的索引
      int actIndex = -1;
      int chapterIndex = -1;
      novel_models.Act? act;

      for (int i = 0; i < originalNovel.acts.length; i++) {
        final currentAct = originalNovel.acts[i];
        if (currentAct.id == event.actId) {
          actIndex = i;
          act = currentAct;
          for (int j = 0; j < currentAct.chapters.length; j++) {
            if (currentAct.chapters[j].id == event.chapterId) {
              chapterIndex = j;
              break;
            }
          }
          break;
        }
      }

      if (actIndex == -1 || chapterIndex == -1 || act == null) {
        AppLogger.e('Blocs/editor/editor_bloc',
            '找不到要删除的章节: ${event.chapterId}');
        // 保持当前状态，但显示错误信息
        emit(currentState.copyWith(errorMessage: '找不到要删除的章节'));
        return;
      }

      // 确定删除后的下一个活动Chapter ID
      String? nextActiveChapterId;
      novel_models.Chapter? nextActiveChapter;
      if (act.chapters.length > 1) {
        // 如果删除后Act还有其他章节
        if (chapterIndex > 0) {
          // 优先选前一个章节
          nextActiveChapter = act.chapters[chapterIndex - 1];
        } else {
          // 否则选后一个章节
          nextActiveChapter = act.chapters[1];
        }
        nextActiveChapterId = nextActiveChapter.id;
      } else if (originalNovel.acts.length > 1) {
        // 如果当前Act没有其他章节了，但还有其他Act
        // 尝试选择前一个Act的最后一个章节或后一个Act的第一个章节
        int nextActIndex;
        if (actIndex > 0) {
          nextActIndex = actIndex - 1;
          final nextAct = originalNovel.acts[nextActIndex];
          if (nextAct.chapters.isNotEmpty) {
            nextActiveChapter = nextAct.chapters.last;
            nextActiveChapterId = nextActiveChapter.id;
          }
        } else if (actIndex < originalNovel.acts.length - 1) {
          nextActIndex = actIndex + 1;
          final nextAct = originalNovel.acts[nextActIndex];
          if (nextAct.chapters.isNotEmpty) {
            nextActiveChapter = nextAct.chapters.first;
            nextActiveChapterId = nextActiveChapter.id;
          }
        }
      }

      // 更新本地小说模型 (不可变方式)
      final updatedChapters = List<novel_models.Chapter>.from(act.chapters)
        ..removeAt(chapterIndex);
      final updatedAct = act.copyWith(chapters: updatedChapters);
      final updatedActs = List<novel_models.Act>.from(originalNovel.acts)
        ..[actIndex] = updatedAct;
      final updatedNovel = originalNovel.copyWith(
        acts: updatedActs,
        updatedAt: DateTime.now(),
      );

      // Calculate chapter maps for the updated novel state
      final chapterMaps = _calculateChapterMaps(updatedNovel);

      // 更新UI状态为 "正在保存"，并设置新的活动章节
      emit(currentState.copyWith(
        novel: updatedNovel, // 显示删除后的状态
        isDirty: true, // 标记为脏
        isSaving: true, // 标记正在保存
        // 更新活动章节ID
        activeChapterId: currentState.activeChapterId == event.chapterId
            ? nextActiveChapterId
            : currentState.activeChapterId,
        // 如果活动章节变了，也要更新活动Act
        activeActId: (currentState.activeChapterId == event.chapterId && nextActiveChapter != null)
            ? (nextActiveChapter != null ? _findActIdForChapter(originalNovel, nextActiveChapterId!) : currentState.activeActId)
            : currentState.activeActId,
        // 如果删除的是当前活动章节，把活动场景设为null
        activeSceneId: currentState.activeChapterId == event.chapterId
            ? null
            : currentState.activeSceneId,
        chapterGlobalIndices: chapterMaps.chapterGlobalIndices, // Added
        chapterToActMap: chapterMaps.chapterToActMap, // Added
      ));

      try {
        // 清理该章节的所有场景保存请求
        _cleanupPendingSavesForChapter(event.chapterId);
        
        // 使用细粒度方法删除章节
        final success = await repository.deleteChapterFine(
          event.novelId, 
          event.actId, 
          event.chapterId
        );
        
        if (!success) {
          throw Exception('删除章节失败');
        }

        // 保存成功后，更新状态为已保存
        emit((state as EditorLoaded).copyWith(
          isDirty: false,
          isSaving: false,
          lastSaveTime: DateTime.now(),
          // chapterGlobalIndices and chapterToActMap are already part of the state from the previous emit
        ));
        
        // 持久化：确保章节删除后的小说结构写回本地缓存
        await repository.saveNovel(updatedNovel);
        AppLogger.i('Blocs/editor/editor_bloc',
            '章节删除成功: ${event.chapterId}');
      } catch (e) {
        AppLogger.e('Blocs/editor/editor_bloc', '删除章节失败', e);
        // 删除失败，恢复原始数据
        // Recalculate maps for the original novel if rolling back
        final originalChapterMaps = _calculateChapterMaps(originalNovel);
        emit((state as EditorLoaded).copyWith(
          novel: originalNovel,
          isSaving: false,
          errorMessage: '删除章节失败: ${e.toString()}',
          activeActId: currentState.activeActId,
          activeChapterId: currentState.activeChapterId,
          activeSceneId: currentState.activeSceneId,
          chapterGlobalIndices: originalChapterMaps.chapterGlobalIndices, // Added for rollback
          chapterToActMap: originalChapterMaps.chapterToActMap, // Added for rollback
        ));
      }
    }
  }

  // 删除Act（卷）
  Future<void> _onDeleteAct(
      DeleteAct event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      final originalNovel = currentState.novel;
      try {
        // 1) 本地先行更新：移除该Act
        final updatedActs = List<novel_models.Act>.from(originalNovel.acts)
          ..removeWhere((a) => a.id == event.actId);
        final updatedNovel = originalNovel.copyWith(
          acts: updatedActs,
          updatedAt: DateTime.now(),
        );

        // 计算章节映射
        final chapterMaps = _calculateChapterMaps(updatedNovel);

        // 2) 先更新UI，标记为保存中
        emit(currentState.copyWith(
          novel: updatedNovel,
          isDirty: true,
          isSaving: true,
          // 如果当前活动Act被删，重置活动指针
          activeActId: currentState.activeActId == event.actId ? (updatedActs.isNotEmpty ? updatedActs.first.id : null) : currentState.activeActId,
          activeChapterId: currentState.activeActId == event.actId ? (updatedActs.isNotEmpty && updatedActs.first.chapters.isNotEmpty ? updatedActs.first.chapters.first.id : null) : currentState.activeChapterId,
          activeSceneId: currentState.activeActId == event.actId ? null : currentState.activeSceneId,
          chapterGlobalIndices: chapterMaps.chapterGlobalIndices,
          chapterToActMap: chapterMaps.chapterToActMap,
        ));

        // 3) 调用细粒度删除API
        final success = await repository.deleteActFine(event.novelId, event.actId);
        if (!success) {
          throw Exception('删除卷失败');
        }

        // 4) 持久化并完成状态
        await repository.saveNovel(updatedNovel);
        emit((state as EditorLoaded).copyWith(
          isDirty: false,
          isSaving: false,
          lastSaveTime: DateTime.now(),
        ));
      } catch (e) {
        AppLogger.e('EditorBloc/_onDeleteAct', '删除卷失败', e);
        // 回滚
        final originalMaps = _calculateChapterMaps(originalNovel);
        emit((state as EditorLoaded).copyWith(
          novel: originalNovel,
          isSaving: false,
          errorMessage: '删除卷失败: ${e.toString()}',
          chapterGlobalIndices: originalMaps.chapterGlobalIndices,
          chapterToActMap: originalMaps.chapterToActMap,
        ));
      }
    }
  }

  // 在章节删除后清理该章节的所有场景保存请求
  void _cleanupPendingSavesForChapter(String chapterId) {
    final keysToRemove = <String>[];
    
    _pendingSaveScenes.forEach((key, data) {
      if (data['chapterId'] == chapterId) {
        keysToRemove.add(key);
      }
    });
    
    for (final key in keysToRemove) {
      _pendingSaveScenes.remove(key);
      AppLogger.i('EditorBloc', '已从保存队列中移除章节${chapterId}的场景: ${key}');
    }
    
    if (keysToRemove.isNotEmpty) {
      AppLogger.i('EditorBloc', '已清理${keysToRemove.length}个属于已删除章节${chapterId}的场景保存请求');
    }
  }

  // 实现更新可见范围的处理
  Future<void> _onUpdateVisibleRange(
      UpdateVisibleRange event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      emit(currentState.copyWith(
        visibleRange: [event.startIndex, event.endIndex],
      ));
    }
  }

  // 设置焦点章节 - 仅更新焦点，不影响活动场景
  Future<void> _onSetFocusChapter(
      SetFocusChapter event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      AppLogger.i('EditorBloc', '设置焦点章节: ${event.chapterId} (仅更新焦点，不影响活动场景)');
      
      emit(currentState.copyWith(
        focusChapterId: event.chapterId,
        // 不更新activeActId、activeChapterId和activeSceneId
      ));
    }
  }

  // 处理重置Act加载状态标志的事件
  void _onResetActLoadingFlags(ResetActLoadingFlags event, Emitter<EditorState> emit) {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 重置边界标志
    emit(currentState.copyWith(
      hasReachedEnd: false,
      hasReachedStart: false,
    ));
    
    AppLogger.i('Blocs/editor/editor_bloc', '已重置Act加载标志: hasReachedEnd=false, hasReachedStart=false');
  }
  
  void _onSetActLoadingFlags(SetActLoadingFlags event, Emitter<EditorState> emit) {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 只更新提供了值的标志
    bool hasReachedEnd = currentState.hasReachedEnd;
    bool hasReachedStart = currentState.hasReachedStart;
    
    if (event.hasReachedEnd != null) {
      hasReachedEnd = event.hasReachedEnd!;
    }
    
    if (event.hasReachedStart != null) {
      hasReachedStart = event.hasReachedStart!;
    }
    
    // 更新状态
    emit(currentState.copyWith(
      hasReachedEnd: hasReachedEnd,
      hasReachedStart: hasReachedStart,
    ));
    
    AppLogger.i('Blocs/editor/editor_bloc', 
        '已设置Act加载标志: hasReachedEnd=${hasReachedEnd}, hasReachedStart=${hasReachedStart}');
  }

  // 更新章节标题的事件处理方法
  Future<void> _onUpdateChapterTitle(
      UpdateChapterTitle event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      try {
        // 更新标题逻辑
        final acts = currentState.novel.acts.map((act) {
          if (act.id == event.actId) {
            final chapters = act.chapters.map((chapter) {
              if (chapter.id == event.chapterId) {
                return chapter.copyWith(title: event.title);
              }
              return chapter;
            }).toList();
            return act.copyWith(chapters: chapters);
          }
          return act;
        }).toList();

        final updatedNovel = currentState.novel.copyWith(acts: acts);

        emit(currentState.copyWith(
          novel: updatedNovel,
          isDirty: true,
          lastUpdateSilent: true,
        ));
        
        // 本地持久化，避免随后基于旧缓存的结构操作覆盖标题变更
        await repository.saveNovel(updatedNovel);
        
        // 保存到服务器
        final success = await repository.updateChapterTitle(
          novelId,
          event.actId,
          event.chapterId,
          event.title,
        );
        
        if (!success) {
          AppLogger.e('Blocs/editor/editor_bloc', '更新Chapter标题失败');
        }
        
        emit(currentState.copyWith(isDirty: false));
      } catch (e) {
        AppLogger.e('Blocs/editor/editor_bloc', '更新Chapter标题失败', e);
        emit(currentState.copyWith(
          errorMessage: '更新Chapter标题失败: ${e.toString()}',
        ));
      }
    }
  }

  // 更新卷标题的事件处理方法
  Future<void> _onUpdateActTitle(
      UpdateActTitle event, Emitter<EditorState> emit) async {
    final currentState = state;
    if (currentState is EditorLoaded) {
      try {
        // 更新标题逻辑
        final acts = currentState.novel.acts.map((act) {
          if (act.id == event.actId) {
            return act.copyWith(title: event.title);
          }
          return act;
        }).toList();

        final updatedNovel = currentState.novel.copyWith(acts: acts);

        emit(currentState.copyWith(
          novel: updatedNovel,
          isDirty: true,
          lastUpdateSilent: true,
        ));
        
        // 本地持久化，避免随后基于旧缓存的结构操作覆盖标题变更
        await repository.saveNovel(updatedNovel);
        
        // 保存到服务器
        final success = await repository.updateActTitle(
          novelId,
          event.actId,
          event.title,
        );
        
        if (!success) {
          AppLogger.e('Blocs/editor/editor_bloc', '更新Act标题失败');
        }
        
        emit(currentState.copyWith(isDirty: false));
      } catch (e) {
        AppLogger.e('Blocs/editor/editor_bloc', '更新Act标题失败', e);
        emit(currentState.copyWith(
          errorMessage: '更新Act标题失败: ${e.toString()}',
        ));
      }
    }
  }

  // 处理GenerateSceneFromSummaryRequested事件
  Future<void> _onGenerateSceneFromSummaryRequested(
      GenerateSceneFromSummaryRequested event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 取消之前的生成订阅（如果有）
    if (_generationStreamSubscription != null) {
      await _generationStreamSubscription!.cancel();
      _generationStreamSubscription = null;
    }
    
    // 更新状态为正在生成
    emit(currentState.copyWith(
      aiSceneGenerationStatus: AIGenerationStatus.generating,
      generatedSceneContent: '',
      aiGenerationError: null,
    ));
    
    try {
      AppLogger.i('EditorBloc/_onGenerateSceneFromSummaryRequested', 
        '开始从摘要生成场景，摘要长度：${event.summary.length}, 流式生成：${event.useStreamingMode}');
      
      if (event.useStreamingMode) {
        // 流式生成模式
        final stream = await repository.generateSceneFromSummaryStream(
          event.novelId,
          event.summary,
          chapterId: event.chapterId,
          additionalInstructions: event.styleInstructions,
        );
        
        String accumulatedContent = '';
        
        _generationStreamSubscription = stream.listen(
          (chunk) {
            // 累加接收到的内容
            accumulatedContent += chunk;
            // 发送更新生成内容事件
            add(UpdateGeneratedSceneContent(accumulatedContent));
          },
          onDone: () {
            // 生成完成
            add(SceneGenerationCompleted(accumulatedContent));
            _generationStreamSubscription = null;
          },
          onError: (error) {
            // 生成出错
            AppLogger.e('EditorBloc/_onGenerateSceneFromSummaryRequested', '流式生成场景失败', error);
            add(SceneGenerationFailed(error.toString()));
            _generationStreamSubscription = null;
          },
        );
      } else {
        // 非流式生成模式
        final result = await repository.generateSceneFromSummary(
          event.novelId,
          event.summary,
          chapterId: event.chapterId,
          additionalInstructions: event.styleInstructions,
        );
        
        // 生成完成
        add(SceneGenerationCompleted(result));
      }
    } catch (e) {
      // 捕获并处理所有异常
      AppLogger.e('EditorBloc/_onGenerateSceneFromSummaryRequested', '生成场景失败', e);
      add(SceneGenerationFailed(e.toString()));
    }
  }

  // 处理更新生成内容事件
  void _onUpdateGeneratedSceneContent(
      UpdateGeneratedSceneContent event, Emitter<EditorState> emit) {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 更新生成的内容
    emit(currentState.copyWith(
      generatedSceneContent: event.content,
    ));
  }

  // 处理生成完成事件
  void _onSceneGenerationCompleted(
      SceneGenerationCompleted event, Emitter<EditorState> emit) {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 更新状态为生成完成
    emit(currentState.copyWith(
      aiSceneGenerationStatus: AIGenerationStatus.completed,
      generatedSceneContent: event.content,
    ));
    
    AppLogger.i('EditorBloc/_onSceneGenerationCompleted', '场景生成完成，生成内容长度：${event.content.length}');
  }

  // 处理生成失败事件
  void _onSceneGenerationFailed(
      SceneGenerationFailed event, Emitter<EditorState> emit) {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 更新状态为生成失败
    emit(currentState.copyWith(
      aiSceneGenerationStatus: AIGenerationStatus.failed,
      aiGenerationError: event.error,
    ));
    
    AppLogger.e('EditorBloc/_onSceneGenerationFailed', '场景生成失败，错误：${event.error}');
  }

  // 处理停止生成事件
  Future<void> _onStopSceneGeneration(
      StopSceneGeneration event, Emitter<EditorState> emit) async {
    // 取消订阅
    if (_generationStreamSubscription != null) {
      await _generationStreamSubscription!.cancel();
      _generationStreamSubscription = null;
    }
    
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 更新状态为初始状态
    emit(currentState.copyWith(
      aiSceneGenerationStatus: AIGenerationStatus.initial,
    ));
    
    AppLogger.i('EditorBloc/_onStopSceneGeneration', '场景生成已取消');
  }

  // 处理设置待处理摘要事件
  void _onSetPendingSummary(
      SetPendingSummary event, Emitter<EditorState> emit) {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 设置待处理的摘要
    emit(currentState.copyWith(
      pendingSummary: event.summary,
    ));
    
    AppLogger.d('EditorBloc/_onSetPendingSummary', '已设置待处理摘要，长度：${event.summary.length}');
  }

  // 强制保存场景内容处理器 - 用于SceneEditor dispose时立即保存
  Future<void> _onForceSaveSceneContent(
      ForceSaveSceneContent event, Emitter<EditorState> emit) async {
    AppLogger.i('EditorBloc/_onForceSaveSceneContent',
        '强制保存场景内容 - 场景ID: ${event.sceneId}, 字数: ${event.wordCount ?? "自动计算"}');
    
    final currentState = state;
    if (currentState is EditorLoaded) {
      try {
        // 验证场景是否存在
        bool sceneExists = false;
        novel_models.Scene? existingScene;
        
        for (final act in currentState.novel.acts) {
          if (act.id == event.actId) {
            for (final chapter in act.chapters) {
              if (chapter.id == event.chapterId) {
                for (final scene in chapter.scenes) {
                  if (scene.id == event.sceneId) {
                    sceneExists = true;
                    existingScene = scene;
                    break;
                  }
                }
                break;
              }
            }
            break;
          }
        }
        
        if (!sceneExists || existingScene == null) {
          AppLogger.w('EditorBloc/_onForceSaveSceneContent', 
              '强制保存失败：场景不存在或已被删除 ${event.sceneId}');
          return;
        }
        
        // 计算字数（如果未提供）
        final int calculatedWordCount = event.wordCount != null 
            ? int.tryParse(event.wordCount!) ?? WordCountAnalyzer.countWords(event.content)
            : WordCountAnalyzer.countWords(event.content);
            
        // 使用提供的摘要或保持原有摘要
        final sceneSummary = event.summary != null 
            ? novel_models.Summary(
                id: '${event.sceneId}_summary',
                content: event.summary!,
              )
            : existingScene.summary;
        
        // 确保内容是有效的Quill JSON格式
        final String validContent = _ensureValidQuillJson(event.content);
        
        // 直接更新小说模型中的场景内容
        final updatedNovel = _updateSceneContentAndSummary(
          currentState.novel,
          event.actId,
          event.chapterId,
          event.sceneId,
          validContent,
          calculatedWordCount,
          sceneSummary,
        );
        
        // 立即发出更新状态，包含新的场景内容
        emit(currentState.copyWith(
          novel: updatedNovel,
          isDirty: true, // 标记为脏，因为有未保存的更改
          lastUpdateSilent: true, // 设置为静默更新，避免触发大量UI刷新
        ));
        
        // 异步保存到本地存储（不等待完成）
        _saveSceneToLocalStorageAsync(
          event.novelId,
          event.actId,
          event.chapterId,
          event.sceneId,
          validContent,
          calculatedWordCount.toString(),
          sceneSummary,
        );
        
        AppLogger.i('EditorBloc/_onForceSaveSceneContent',
            '强制保存完成 - 场景ID: ${event.sceneId}, 字数: $calculatedWordCount');
            
      } catch (e) {
        AppLogger.e('EditorBloc/_onForceSaveSceneContent', '强制保存场景内容失败', e);
        // 对于强制保存，我们不更新错误状态，避免影响UI
      }
    }
  }
  
  // 异步保存场景到本地存储
  void _saveSceneToLocalStorageAsync(
    String novelId,
    String actId,
    String chapterId,
    String sceneId,
    String content,
    String wordCount,
    novel_models.Summary summary,
  ) {
    // 使用异步方法，不阻塞主线程
    Future.microtask(() async {
      try {
        await repository.saveSceneContent(
          novelId,
          actId,
          chapterId,
          sceneId,
          content,
          wordCount,
          summary,
          localOnly: true, // 仅保存到本地
        );
        
        AppLogger.d('EditorBloc/_saveSceneToLocalStorageAsync',
            '异步本地保存完成 - 场景ID: $sceneId');
      } catch (e) {
        AppLogger.e('EditorBloc/_saveSceneToLocalStorageAsync', 
            '异步本地保存失败 - 场景ID: $sceneId', e);
      }
    });
  }
  
  // 更新场景内容和摘要的辅助方法
  novel_models.Novel _updateSceneContentAndSummary(
    novel_models.Novel novel,
    String actId,
    String chapterId,
    String sceneId,
    String content,
    int wordCount,
    novel_models.Summary summary,
  ) {
    // 创建当前小说acts的深拷贝以便修改
    final List<novel_models.Act> updatedActs = novel.acts.map((act) {
      if (act.id == actId) {
        // 更新指定Act的章节
        final List<novel_models.Chapter> updatedChapters = act.chapters.map((chapter) {
          if (chapter.id == chapterId) {
            // 找到指定章节，更新其场景
            final List<novel_models.Scene> updatedScenes = chapter.scenes.map((scene) {
              if (scene.id == sceneId) {
                // 更新场景内容、字数和摘要
                return scene.copyWith(
                  content: content,
                  wordCount: wordCount,
                  summary: summary,
                  lastEdited: DateTime.now(),
                );
              }
              return scene;
            }).toList();
            
            return chapter.copyWith(scenes: updatedScenes);
          }
          return chapter;
        }).toList();
        
        return act.copyWith(chapters: updatedChapters);
      }
      return act;
    }).toList();
    
    // 返回更新后的小说，同时更新最后编辑章节
    return novel.copyWith(
      acts: updatedActs,
      lastEditedChapterId: chapterId,
      updatedAt: DateTime.now(),
    );
  }
  
  // 🚀 新增：Plan视图事件处理方法
  
  /// 切换到Plan视图模式
  Future<void> _onSwitchToPlanView(
      SwitchToPlanView event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    AppLogger.i('EditorBloc/_onSwitchToPlanView', '切换到Plan视图模式（直接使用已有数据）');
    
    // 直接设置Plan视图模式，使用已有的小说数据
    // 无需重新加载数据，因为EditorBloc已经包含了完整的小说结构
    emit(currentState.copyWith(
      isPlanViewMode: true,
      planModificationSource: null, // 清除之前的修改标记
      lastPlanModifiedTime: DateTime.now(),
    ));
    
    AppLogger.i('EditorBloc/_onSwitchToPlanView', 'Plan视图模式切换完成');
  }
  
  /// 切换到Write视图模式
  Future<void> _onSwitchToWriteView(
      SwitchToWriteView event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    AppLogger.i('EditorBloc/_onSwitchToWriteView', '切换到Write视图模式');
    
    // 检查是否需要刷新编辑器数据
    bool shouldRefreshData = currentState.planViewDirty || 
                            currentState.planModificationSource != null;
    
    // 切换到Write视图模式
    emit(currentState.copyWith(
      isPlanViewMode: false,
      planViewDirty: false, // 清除Plan修改标记
    ));
    
    // 如果Plan视图有修改，触发数据刷新
    if (shouldRefreshData) {
      AppLogger.i('EditorBloc/_onSwitchToWriteView', 'Plan视图有修改，触发无感刷新');
      add(const RefreshEditorData(preserveActiveScene: true, source: 'plan_to_write'));
    }
  }
  
  /// 加载Plan内容（使用已有数据，无需API调用）
  Future<void> _onLoadPlanContent(
      LoadPlanContent event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    AppLogger.i('EditorBloc/_onLoadPlanContent', '加载Plan内容（使用已有数据）');
    
    // 直接使用当前已有的小说数据，无需重新从服务器获取
    // EditorBloc已经包含了完整的小说结构和场景数据
    emit(currentState.copyWith(
      lastPlanModifiedTime: DateTime.now(),
    ));
    
    AppLogger.i('EditorBloc/_onLoadPlanContent', 'Plan内容加载完成（使用缓存数据）');
  }
  
  /// 移动场景
  Future<void> _onMoveScene(
      MoveScene event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    try {
      AppLogger.i('EditorBloc/_onMoveScene', 
          '移动场景: ${event.sourceActId}/${event.sourceChapterId}/${event.sourceSceneId} -> ${event.targetActId}/${event.targetChapterId}[${event.targetIndex}]');
      
      // 调用repository移动场景
      final updatedNovel = await repository.moveScene(
        event.novelId,
        event.sourceActId,
        event.sourceChapterId,
        event.sourceSceneId,
        event.targetActId,
        event.targetChapterId,
        event.targetIndex,
      );
      
      if (updatedNovel == null) {
        emit(currentState.copyWith(
          errorMessage: '移动场景失败',
        ));
        return;
      }
      
      // 重新计算章节映射
      final chapterMaps = _calculateChapterMaps(updatedNovel);
      
      // 更新状态，标记Plan视图已修改
      emit(currentState.copyWith(
        novel: updatedNovel,
        chapterGlobalIndices: chapterMaps.chapterGlobalIndices,
        chapterToActMap: chapterMaps.chapterToActMap,
        planViewDirty: true,
        lastPlanModifiedTime: DateTime.now(),
        planModificationSource: 'scene_move',
      ));
      
      // 持久化：确保移动后的结构与本地缓存一致
      await repository.saveNovel(updatedNovel);
      
      AppLogger.i('EditorBloc/_onMoveScene', '场景移动完成');
    } catch (e) {
      AppLogger.e('EditorBloc/_onMoveScene', '移动场景失败', e);
      emit(currentState.copyWith(
        errorMessage: '移动场景失败: ${e.toString()}',
      ));
    }
  }
  
  /// 从Plan视图跳转到指定场景
  Future<void> _onNavigateToSceneFromPlan(
      NavigateToSceneFromPlan event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    AppLogger.i('EditorBloc/_onNavigateToSceneFromPlan', 
        '从Plan视图跳转到场景: ${event.actId}/${event.chapterId}/${event.sceneId}');
    
    // 1. 设置活动场景
    emit(currentState.copyWith(
      activeActId: event.actId,
      activeChapterId: event.chapterId,
      activeSceneId: event.sceneId,
      focusChapterId: event.chapterId,
    ));
    
    // 2. 加载目标场景的内容（如果还没有加载）
    add(LoadMoreScenes(
      fromChapterId: event.chapterId,
      actId: event.actId,
      direction: 'center',
      chaptersLimit: 5,
      targetChapterId: event.chapterId,
      targetSceneId: event.sceneId,
    ));
    
    // 3. 延迟切换到Write视图，确保场景加载完成
    Future.delayed(const Duration(milliseconds: 300), () {
      add(const SwitchToWriteView());
    });
  }
  
  /// 刷新编辑器数据（无感刷新）
  Future<void> _onRefreshEditorData(
      RefreshEditorData event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    AppLogger.i('EditorBloc/_onRefreshEditorData', 
        '执行无感刷新，来源: ${event.source}, 保持活动场景: ${event.preserveActiveScene}');
    
    try {
      // 重新加载小说数据
      final novel = await repository.getNovelWithAllScenes(novelId);
      
      if (novel == null) {
        AppLogger.w('EditorBloc/_onRefreshEditorData', '刷新数据失败，无法加载小说');
        return;
      }
      
      // 重新计算章节映射
      final chapterMaps = _calculateChapterMaps(novel);
      
      // 保持当前活动场景（如果请求保持的话）
      String? activeActId = currentState.activeActId;
      String? activeChapterId = currentState.activeChapterId;
      String? activeSceneId = currentState.activeSceneId;
      
      if (!event.preserveActiveScene) {
        // 如果不保持活动场景，设置为第一个可用场景
        if (novel.acts.isNotEmpty && novel.acts.first.chapters.isNotEmpty && 
            novel.acts.first.chapters.first.scenes.isNotEmpty) {
          activeActId = novel.acts.first.id;
          activeChapterId = novel.acts.first.chapters.first.id;
          activeSceneId = novel.acts.first.chapters.first.scenes.first.id;
        }
      }
      
      // 更新状态，清除Plan修改标记
      emit(currentState.copyWith(
        novel: novel,
        chapterGlobalIndices: chapterMaps.chapterGlobalIndices,
        chapterToActMap: chapterMaps.chapterToActMap,
        activeActId: activeActId,
        activeChapterId: activeChapterId,
        activeSceneId: activeSceneId,
        planViewDirty: false,
        planModificationSource: null,
        lastPlanModifiedTime: DateTime.now(),
      ));
      
      AppLogger.i('EditorBloc/_onRefreshEditorData', '无感刷新完成');
    } catch (e) {
      AppLogger.e('EditorBloc/_onRefreshEditorData', '无感刷新失败', e);
      emit(currentState.copyWith(
        errorMessage: '刷新数据失败: ${e.toString()}',
      ));
    }
  }
  
  /// 🚀 新增：切换到沉浸模式
  Future<void> _onSwitchToImmersiveMode(
      SwitchToImmersiveMode event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 确定目标章节ID
    String? targetChapterId = event.chapterId ?? currentState.activeChapterId;
    
    if (targetChapterId == null) {
      AppLogger.w('EditorBloc/_onSwitchToImmersiveMode', '无法确定目标章节ID');
      return;
    }
    
    AppLogger.i('EditorBloc/_onSwitchToImmersiveMode', '切换到沉浸模式，章节: $targetChapterId');
    
    // 更新状态（不修改lastEditedChapterId，只有编辑内容时才更新）
    emit(currentState.copyWith(
      isImmersiveMode: true,
      immersiveChapterId: targetChapterId,
      activeChapterId: targetChapterId,
      // 设置该章节的第一个场景为活动场景
    ));
    
    // 如果指定的章节还没有加载，则加载它
    await _ensureChapterLoaded(targetChapterId, emit);
    
    AppLogger.i('EditorBloc/_onSwitchToImmersiveMode', '沉浸模式切换完成');
  }
  
    /// 🚀 新增：切换到普通模式
  Future<void> _onSwitchToNormalMode(
SwitchToNormalMode event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    AppLogger.i('EditorBloc/_onSwitchToNormalMode', '切换到普通模式');
    
    // 🚀 修复：保存当前沉浸章节ID，用于后续滚动定位
    final currentImmersiveChapterId = currentState.immersiveChapterId;
    
    // 更新状态，保持当前的活动章节
    emit(currentState.copyWith(
      isImmersiveMode: false,
      immersiveChapterId: null,
      // 🚀 新增：设置焦点章节为当前沉浸章节，用于滚动定位
      focusChapterId: currentImmersiveChapterId ?? currentState.activeChapterId,
    ));
    
    AppLogger.i('EditorBloc/_onSwitchToNormalMode', '普通模式切换完成，当前章节: $currentImmersiveChapterId');
  }
  
  /// 🚀 新增：章节导航到下一章（普通/沉浸模式通用）
  Future<void> _onNavigateToNextChapter(
      NavigateToNextChapter event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    final String? baseChapterId = currentState.isImmersiveMode
        ? currentState.immersiveChapterId
        : currentState.activeChapterId;
    if (baseChapterId == null) {
      AppLogger.w('EditorBloc/_onNavigateToNextChapter', '无法确定当前章节');
      return;
    }
    
    final nextChapterId = _findNextChapter(baseChapterId);
    if (nextChapterId == null) {
      AppLogger.i('EditorBloc/_onNavigateToNextChapter', '已经是最后一章');
      return;
    }
    
    AppLogger.i('EditorBloc/_onNavigateToNextChapter', '导航到下一章: $nextChapterId');
    
    if (currentState.isImmersiveMode) {
      // 沉浸模式下维持沉浸模式
      add(SwitchToImmersiveMode(chapterId: nextChapterId));
    } else {
      // 普通模式下仅更新活动章节/场景
      String? targetActId = currentState.chapterToActMap[nextChapterId] ?? _findActIdForChapter(currentState.novel, nextChapterId);
      String? firstSceneId;
      if (targetActId != null) {
        for (final act in currentState.novel.acts) {
          if (act.id == targetActId) {
            for (final chapter in act.chapters) {
              if (chapter.id == nextChapterId) {
                if (chapter.scenes.isNotEmpty) {
                  firstSceneId = chapter.scenes.first.id;
                }
                break;
              }
            }
            break;
          }
        }
      }
      emit(currentState.copyWith(
        activeActId: targetActId,
        activeChapterId: nextChapterId,
        activeSceneId: firstSceneId,
        focusChapterId: nextChapterId,
      ));
      await _ensureChapterLoaded(nextChapterId, emit);
    }
  }
  
  /// 🚀 新增：章节导航到上一章（普通/沉浸模式通用）
  Future<void> _onNavigateToPreviousChapter(
      NavigateToPreviousChapter event, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    final String? baseChapterId = currentState.isImmersiveMode
        ? currentState.immersiveChapterId
        : currentState.activeChapterId;
    if (baseChapterId == null) {
      AppLogger.w('EditorBloc/_onNavigateToPreviousChapter', '无法确定当前章节');
      return;
    }
    
    final previousChapterId = _findPreviousChapter(baseChapterId);
    if (previousChapterId == null) {
      AppLogger.i('EditorBloc/_onNavigateToPreviousChapter', '已经是第一章');
      return;
    }
    
    AppLogger.i('EditorBloc/_onNavigateToPreviousChapter', '导航到上一章: $previousChapterId');
    
    if (currentState.isImmersiveMode) {
      // 沉浸模式下维持沉浸模式
      add(SwitchToImmersiveMode(chapterId: previousChapterId));
    } else {
      // 普通模式下仅更新活动章节/场景
      String? targetActId = currentState.chapterToActMap[previousChapterId] ?? _findActIdForChapter(currentState.novel, previousChapterId);
      String? firstSceneId;
      if (targetActId != null) {
        for (final act in currentState.novel.acts) {
          if (act.id == targetActId) {
            for (final chapter in act.chapters) {
              if (chapter.id == previousChapterId) {
                if (chapter.scenes.isNotEmpty) {
                  firstSceneId = chapter.scenes.first.id;
                }
                break;
              }
            }
            break;
          }
        }
      }
      emit(currentState.copyWith(
        activeActId: targetActId,
        activeChapterId: previousChapterId,
        activeSceneId: firstSceneId,
        focusChapterId: previousChapterId,
      ));
      await _ensureChapterLoaded(previousChapterId, emit);
    }
  }
  
  /// 🚀 新增：确保指定章节已加载
  Future<void> _ensureChapterLoaded(String chapterId, Emitter<EditorState> emit) async {
    if (state is! EditorLoaded) return;
    
    final currentState = state as EditorLoaded;
    
    // 查找章节所属的卷
    String? actId;
    for (final act in currentState.novel.acts) {
      for (final chapter in act.chapters) {
        if (chapter.id == chapterId) {
          actId = act.id;
          break;
        }
      }
      if (actId != null) break;
    }
    
    if (actId == null) {
      AppLogger.w('EditorBloc/_ensureChapterLoaded', '找不到章节 $chapterId 所属的卷');
      return;
    }
    
    // 检查章节是否已有场景内容
    bool hasScenes = false;
    for (final act in currentState.novel.acts) {
      if (act.id == actId) {
        for (final chapter in act.chapters) {
          if (chapter.id == chapterId && chapter.scenes.isNotEmpty) {
            hasScenes = true;
            break;
          }
        }
        break;
      }
    }
    
    // 如果章节还没有场景，则加载
    if (!hasScenes) {
      AppLogger.i('EditorBloc/_ensureChapterLoaded', '加载章节场景: $chapterId');
      add(LoadMoreScenes(
        fromChapterId: chapterId,
        actId: actId,
        direction: 'center',
        chaptersLimit: 1,
        preventFocusChange: false,
      ));
    }
  }
  
  /// 🚀 新增：查找下一章节
  String? _findNextChapter(String currentChapterId) {
    if (state is! EditorLoaded) return null;
    
    final currentState = state as EditorLoaded;
    bool foundCurrent = false;
    
    for (final act in currentState.novel.acts) {
      for (final chapter in act.chapters) {
        if (foundCurrent) {
          return chapter.id; // 找到下一章
        }
        if (chapter.id == currentChapterId) {
          foundCurrent = true;
        }
      }
    }
    
    return null; // 没有下一章
  }
  
  /// 🚀 新增：查找上一章节
  String? _findPreviousChapter(String currentChapterId) {
    if (state is! EditorLoaded) return null;
    
    final currentState = state as EditorLoaded;
    String? previousChapterId;
    
    for (final act in currentState.novel.acts) {
      for (final chapter in act.chapters) {
        if (chapter.id == currentChapterId) {
          return previousChapterId; // 返回上一章
        }
        previousChapterId = chapter.id;
      }
    }
    
    return null; // 没有上一章
  }
}
