import 'dart:async';

import 'package:ainoval/config/app_config.dart';
import 'package:ainoval/services/api_service/base/api_client.dart';
import 'package:ainoval/services/api_service/base/api_exception.dart';

import 'package:ainoval/services/local_storage_service.dart';
import 'package:ainoval/utils/logger.dart';
import 'package:connectivity_plus/connectivity_plus.dart';

/// 数据同步服务
///
/// 负责在本地数据和远程API之间同步数据，支持离线模式和冲突解决
class SyncService {
  SyncService({
    required this.apiService,
    required this.localStorageService,
  });

  final ApiClient apiService;
  final LocalStorageService localStorageService;

  // 同步状态流
  final _syncStateController = StreamController<SyncState>.broadcast();
  Stream<SyncState> get syncStateStream => _syncStateController.stream;

  // 当前同步状态
  SyncState _currentState = SyncState.idle();
  SyncState get currentState => _currentState;

  // 网络连接监听器
  StreamSubscription? _connectivitySubscription;

  // 自动同步定时器
  Timer? _autoSyncTimer;
  
  // 服务是否已关闭
  bool _isDisposed = false;
  bool get isDisposed => _isDisposed;

  /// 初始化同步服务
  Future<void> init() async {
    AppLogger.i('SyncService', '初始化同步服务');

    // 监听网络连接状态
    _connectivitySubscription =
        Connectivity().onConnectivityChanged.listen((result) {
      final isOnline = result != ConnectivityResult.none;
      AppLogger.d('SyncService', '网络连接状态变化: ${isOnline ? "在线" : "离线"}');
      _handleConnectivityChange(isOnline);
    });

    // 检查当前网络状态
    final connectivityResult = await Connectivity().checkConnectivity();
    final isOnline = connectivityResult != ConnectivityResult.none;
    AppLogger.d('SyncService', '当前网络状态: ${isOnline ? "在线" : "离线"}');
    _updateSyncState(isOnline: isOnline);

    // 设置自动同步定时器
    _setupAutoSync();
  }

  /// 设置自动同步
  void _setupAutoSync() {
    AppLogger.i('SyncService', '设置自动同步定时器，每5分钟同步一次');
    _autoSyncTimer?.cancel();
    _autoSyncTimer = Timer.periodic(const Duration(minutes: 5), (_) async {
      if (_currentState.isOnline) {
        // 检查当前小说ID是否设置
        final currentNovelId = await localStorageService.getCurrentNovelId();
        if (currentNovelId == null) {
          AppLogger.w('SyncService', '自动同步触发，但无当前小说ID，跳过');
          return;
        }
        
        AppLogger.d('SyncService', '自动同步触发，当前小说ID: $currentNovelId');
        syncAll();
      }
    });
  }

  /// 处理网络连接变化
  void _handleConnectivityChange(bool isOnline) {
    // Store the previous online state before updating
    final wasOffline = !_currentState.isOnline;
    _updateSyncState(isOnline: isOnline);

    // Trigger sync only when coming back online
    if (isOnline && wasOffline) {
      // 检查当前小说ID是否设置后再同步
      localStorageService.getCurrentNovelId().then((currentNovelId) {
        if (currentNovelId != null) {
          AppLogger.i('SyncService', '网络恢复，开始同步数据，当前小说ID: $currentNovelId');
          syncAll(); // syncAll will now also handle pending messages
        } else {
          AppLogger.w('SyncService', '网络恢复，但无当前小说ID，不执行自动同步');
        }
      });
    }
  }

  /// 更新同步状态
  void _updateSyncState({
    bool? isOnline,
    bool? isSyncing,
    String? error,
    double? progress,
  }) {
    // 如果服务已关闭，则不更新状态
    if (_isDisposed) {
      AppLogger.w('SyncService', '服务已关闭，忽略状态更新');
      return;
    }
    
    _currentState = SyncState(
      isOnline: isOnline ?? _currentState.isOnline,
      isSyncing: isSyncing ?? _currentState.isSyncing,
      error: error,
      progress: progress ?? _currentState.progress,
    );

    _syncStateController.add(_currentState);
    AppLogger.v('SyncService', '同步状态更新: $_currentState');
  }

  /// 同步所有数据
  Future<bool> syncAll() async {
    // 如果服务已关闭，直接返回
    if (_isDisposed) {
      AppLogger.w('SyncService', '服务已关闭，无法执行同步');
      return false;
    }
    
    if (_currentState.isSyncing) {
      AppLogger.w('SyncService', '同步已在进行中，跳过本次同步');
      return false;
    }

    if (!_currentState.isOnline) {
      AppLogger.w('SyncService', '无网络连接，无法同步');
      _updateSyncState(error: '无网络连接，无法同步');
      return false;
    }

    try {
      AppLogger.i('SyncService', '开始全量数据同步');
      _updateSyncState(
          isSyncing: true, progress: 0.0, error: null); // Clear previous error

      // --- Sync Pending Messages First ---
      AppLogger.d('SyncService', '开始同步待发送消息');
      await _syncPendingMessages();
      _updateSyncState(progress: 0.1); // Adjust progress steps

      // --- Sync other data types ---
      AppLogger.d('SyncService', '开始同步小说数据');
      await _syncNovels();
      _updateSyncState(progress: 0.3);

      AppLogger.d('SyncService', '开始同步场景内容');
      await _syncScenes();
      _updateSyncState(progress: 0.5);

      AppLogger.d('SyncService', '开始同步编辑器内容');
      await _syncEditorContents();
      _updateSyncState(progress: 0.7);

      // Sync Chat Session METADATA (title, etc.)
      AppLogger.d('SyncService', '开始同步聊天会话元数据');
      await _syncChatSessions(); // This now only syncs metadata
      _updateSyncState(progress: 0.9); // Example progress

      // --- Final step, maybe sync user profile or other settings ---
      _updateSyncState(progress: 1.0); // Example finish

      AppLogger.i('SyncService', '全量数据同步完成');
      _updateSyncState(isSyncing: false, error: null); // Clear error on success
      return true;
    } catch (e, stackTrace) {
      AppLogger.e('SyncService', '同步失败', e, stackTrace);
      // Preserve isOnline state, set error
      _updateSyncState(isSyncing: false, error: '同步失败: $e');
      return false;
    }
  }

  /// 同步小说数据
  Future<void> _syncNovels() async {
    try {
      // 获取当前正在编辑的小说ID
      final currentNovelId = await localStorageService.getCurrentNovelId();
      if (currentNovelId == null) {
        AppLogger.w('SyncService', '无当前小说ID，跳过小说同步');
        return;
      }

      final syncList = await localStorageService.getSyncList('novel');
      AppLogger.d('SyncService', '需要同步的小说数量: ${syncList.length}');

      // 筛选出当前小说
      final novelIdsToSync = syncList.where((novelId) => novelId == currentNovelId).toList();
      AppLogger.d('SyncService', '当前小说需要同步: ${novelIdsToSync.length} (当前小说ID: $currentNovelId)');
      
      if (novelIdsToSync.isEmpty) {
        AppLogger.i('SyncService', '当前小说不需要同步，跳过');
        return;
      }

      for (final novelId in novelIdsToSync) {
        final localNovel = await localStorageService.getNovel(novelId);
        if (localNovel == null) {
          AppLogger.w('SyncService', '本地小说不存在: $novelId');
          continue;
        }

        AppLogger.i('SyncService', '同步小说: ${localNovel.title}($novelId)');
        
        // 构建后端所需的小说数据结构
        final backendNovelJson = {
          'id': localNovel.id,
          'title': localNovel.title,
          'coverImage': localNovel.coverUrl,
          // 确保包含作者信息
          'author': localNovel.author?.toJson() ??
              {
                'id': AppConfig.userId ?? '',
                'username': AppConfig.username ?? 'user'
              },
          'lastEditedChapterId': localNovel.lastEditedChapterId,
          'createdAt': localNovel.createdAt.toIso8601String(),
          'updatedAt': DateTime.now().toIso8601String(),
          'structure': {
            'acts': localNovel.acts
                .map((act) => {
                      'id': act.id,
                      'title': act.title,
                      'order': act.order,
                      'chapters': act.chapters
                          .map((chapter) => {
                                'id': chapter.id,
                                'title': chapter.title,
                                'order': chapter.order,
                                // 注意：章节中只需包含ID，场景内容通过scenesByChapter单独提供
                                'sceneIds': chapter.scenes.map((scene) => scene.id).toList(),
                              })
                          .toList(),
                    })
                .toList(),
          },
        };
        
        // 组织场景数据，按章节分组
        Map<String, List<Map<String, dynamic>>> scenesByChapter = {};
        for (final act in localNovel.acts) {
          for (final chapter in act.chapters) {
            if (chapter.scenes.isNotEmpty) {
              scenesByChapter[chapter.id] = chapter.scenes
                  .map((scene) => {
                        'id': scene.id,
                        'novelId': localNovel.id,
                        'chapterId': chapter.id,
                        'content': scene.content,
                        'summary': scene.summary.content,
                        'updatedAt': scene.lastEdited.toIso8601String(),
                        'version': scene.version,
                        'title': '',
                        'sequence': 0,
                        'sceneType': 'NORMAL',
                      })
                  .toList();
            }
          }
        }
        
        // 组装完整的请求数据
        final novelWithScenesJson = {
          'novel': backendNovelJson,
          'scenesByChapter': scenesByChapter,
        };

        // 调用updateNovelWithScenes接口
        await apiService.updateNovelWithScenes(novelWithScenesJson);

        await localStorageService.clearSyncFlagByType('novel', novelId);
        AppLogger.d('SyncService', '小说同步完成: $novelId');
      }
    } catch (e, stackTrace) {
      AppLogger.e('SyncService', '同步小说数据失败', e, stackTrace);
      throw SyncException('同步小说数据失败: $e');
    }
  }

  /// 同步场景内容
  Future<void> _syncScenes() async {
    try {
      // 获取当前正在编辑的小说ID
      final currentNovelId = await localStorageService.getCurrentNovelId();
      if (currentNovelId == null) {
        AppLogger.w('SyncService', '无当前小说ID，跳过场景同步');
        return;
      }

      final syncList = await localStorageService.getSyncList('scene');
      AppLogger.d('SyncService', '需要同步的场景数量: ${syncList.length}');

      // 筛选出当前小说的场景
      final scenesToSync = syncList.where((sceneKey) {
        final parts = sceneKey.split('_');
        return parts.length == 4 && parts[0] == currentNovelId;
      }).toList();

      AppLogger.d('SyncService', '当前小说的场景需要同步: ${scenesToSync.length} (当前小说ID: $currentNovelId)');
      
      if (scenesToSync.isEmpty) {
        AppLogger.i('SyncService', '当前小说没有场景需要同步，跳过');
        return;
      }

      for (final sceneKey in scenesToSync) {
        final parts = sceneKey.split('_');
        if (parts.length != 4) {
          AppLogger.w('SyncService', '无效的场景键格式: $sceneKey');
          continue;
        }

        final novelId = parts[0];
        final actId = parts[1];
        final chapterId = parts[2];
        final sceneId = parts[3];

        final localScene = await localStorageService.getSceneContent(
            novelId, actId, chapterId, sceneId);
        if (localScene == null) {
          AppLogger.w('SyncService', '本地场景不存在: $sceneKey');
          continue;
        }

        AppLogger.i('SyncService', '同步场景: $sceneKey');
        final sceneData = localScene.toJson();
        await apiService.updateScene(sceneData);

        await localStorageService.clearSyncFlagByType('scene', sceneKey);
        AppLogger.d('SyncService', '场景同步完成: $sceneKey');
      }
    } catch (e, stackTrace) {
      AppLogger.e('SyncService', '同步场景内容失败', e, stackTrace);
      throw SyncException('同步场景内容失败: $e');
    }
  }

  /// 同步编辑器内容
  Future<void> _syncEditorContents() async {
    try {
      // 获取当前正在编辑的小说ID
      final currentNovelId = await localStorageService.getCurrentNovelId();
      if (currentNovelId == null) {
        AppLogger.w('SyncService', '无当前小说ID，跳过编辑器内容同步');
        return;
      }

      final syncList = await localStorageService.getSyncList('editor');
      AppLogger.d('SyncService', '需要同步的编辑器内容数量: ${syncList.length}');

      // 筛选出当前小说的编辑器内容
      final contentsToSync = syncList.where((contentKey) {
        final parts = contentKey.split('_');
        return parts.length >= 2 && parts[0] == currentNovelId;
      }).toList();

      AppLogger.d('SyncService', '当前小说的编辑器内容需要同步: ${contentsToSync.length} (当前小说ID: $currentNovelId)');
      
      if (contentsToSync.isEmpty) {
        AppLogger.i('SyncService', '当前小说没有编辑器内容需要同步，跳过');
        return;
      }

      for (final contentKey in contentsToSync) {
        final parts = contentKey.split('_');
        if (parts.length < 2) {
          AppLogger.w('SyncService', '无效的编辑器内容键格式: $contentKey');
          continue;
        }

        final novelId = parts[0];
        final chapterId = parts[1];

        final localContent =
            await localStorageService.getEditorContent(novelId, chapterId, '');
        if (localContent == null) {
          AppLogger.w('SyncService', '本地编辑器内容不存在: $contentKey');
          continue;
        }

        AppLogger.i('SyncService', '同步编辑器内容: $contentKey');
        await apiService.saveEditorContent(
            novelId, chapterId, localContent.toJson());

        await localStorageService.clearSyncFlagByType('editor', contentKey);
        AppLogger.d('SyncService', '编辑器内容同步完成: $contentKey');
      }
    } catch (e, stackTrace) {
      AppLogger.e('SyncService', '同步编辑器内容失败', e, stackTrace);
      throw SyncException('同步编辑器内容失败: $e');
    }
  }

  /// 同步聊天会话元数据 (No longer sends full message history)
  Future<void> _syncChatSessions() async {
    // This method now only syncs session metadata like title, updatedAt
    try {
      // 获取当前正在编辑的小说ID
      final currentNovelId = await localStorageService.getCurrentNovelId();
      if (currentNovelId == null) {
        AppLogger.w('SyncService', '无当前小说ID，跳过聊天会话同步');
        return;
      }

      final sessions = await localStorageService.getSessionsToSync();
      AppLogger.d('SyncService', '需要同步的聊天会话元数据数量: ${sessions.length}');

      // 筛选出当前小说的聊天会话
      // 注意：这里假设 ChatSession 模型有 novelId 属性，如果没有，需要调整过滤逻辑
      final sessionsToSync = sessions.where((session) => 
          session.metadata != null && 
          session.metadata!['novelId'] == currentNovelId).toList();
      
      AppLogger.d('SyncService', '当前小说的聊天会话需要同步: ${sessionsToSync.length} (当前小说ID: $currentNovelId)');
      
      if (sessionsToSync.isEmpty) {
        AppLogger.i('SyncService', '当前小说没有聊天会话需要同步，跳过');
        return;
      }

      // No need for userId here if updateSession API only updates metadata
      // If updateSession *requires* userId, get it once:
      // final String currentUserId = await _getCurrentUserId();

      for (final session in sessionsToSync) {
        AppLogger.i('SyncService', '同步聊天会话元数据: ${session.id}');

        // Construct updates payload - only include fields managed locally
        // that need syncing (like title if user can rename offline)
        final Map<String, dynamic> updates = {
          'title': session.title,
          // Include lastUpdatedAt from local session to inform server?
          // 'updatedAt': session.lastUpdatedAt.toIso8601String(),
          // Or maybe server handles updatedAt automatically on update?
        };

        // Only call update if there are actual updates to send
        if (updates.isNotEmpty) {
          // If updateSession requires userId, pass it: userId: currentUserId,
          await apiService.updateAiChatSession(
            userId: await _getCurrentUserId(), // Get userId if needed by API
            sessionId: session.id,
            updates: updates,
          );
        } // Else: Session might be marked for sync without local changes, skip API call?

        // REMOVED: Loop sending messages using getMessagesForSession

        await localStorageService.clearSyncFlagByType(
            'chat_session', session.id);
        AppLogger.d('SyncService', '聊天会话元数据同步完成: ${session.id}');
      }
    } catch (e, stackTrace) {
      // Don't throw - allow other sync tasks to proceed if possible
      AppLogger.e('SyncService', '同步聊天会话元数据失败', e, stackTrace);
      // Optionally update state with a non-fatal error?
      // _updateSyncState(error: '部分同步失败: 聊天会话元数据'); // Be careful not to overwrite fatal errors
    }
  }

  /// --- New Method: Sync Pending Chat Messages ---
  Future<void> _syncPendingMessages() async {
    try {
      // 如果服务已关闭，直接返回
      if (_isDisposed) {
        AppLogger.w('SyncService', '服务已关闭，无法同步待发送消息');
        return;
      }
      
      // 获取当前正在编辑的小说ID
      final currentNovelId = await localStorageService.getCurrentNovelId();
      if (currentNovelId == null) {
        AppLogger.w('SyncService', '无当前小说ID，跳过待发送消息同步');
        return;
      }

      final pendingMessages = await localStorageService.getPendingMessages();
      if (pendingMessages.isEmpty) {
        AppLogger.d('SyncService', '没有待发送的消息。');
        return;
      }

      // 筛选出当前小说的待发送消息
      final messagesToSync = pendingMessages.where((message) {
        // 检查消息元数据中是否包含小说ID
        final metadata = message['metadata'] as Map<String, dynamic>?;
        return metadata != null && metadata['novelId'] == currentNovelId;
      }).toList();

      if (messagesToSync.isEmpty) {
        AppLogger.i('SyncService', '当前小说没有待发送消息需要同步，跳过');
        return;
      }

      AppLogger.i('SyncService', '开始处理 ${messagesToSync.length} 条当前小说的待发送消息。 (当前小说ID: $currentNovelId)');
      final String currentUserId =
          await _getCurrentUserId(); // Get User ID once

      for (final messageData in messagesToSync) {
        final localId = messageData['localId'] as String?;
        final sessionId = messageData['sessionId'] as String?;
        final content = messageData['content'] as String?;
        final metadata = messageData['metadata'] as Map<String, dynamic>?;
        // Important: Use the userId stored with the message if available,
        // otherwise use currentUserId. This handles cases where sync might
        // happen after user logout/login, though ideally pending messages
        // should be cleared on logout.
        final userIdToSend = messageData['userId'] as String? ?? currentUserId;

        if (localId == null || sessionId == null || content == null) {
          AppLogger.e('SyncService', '待发送消息数据不完整，跳过: $messageData');
          // Optionally remove corrupted data
          // if (localId != null) await localStorageService.removePendingMessage(localId);
          continue;
        }

        try {
          AppLogger.d(
              'SyncService', '尝试发送消息: localId=$localId, sessionId=$sessionId');
          // Call the actual API to send the message
          await apiService.sendAiChatMessage(
            userId: userIdToSend,
            sessionId: sessionId,
            content: content,
            metadata: metadata,
          );

          // If sendMessage succeeds, remove from local pending queue
          await localStorageService.removePendingMessage(localId);
          AppLogger.i('SyncService', '成功发送并移除待发送消息: localId=$localId');

          // OPTIONAL: Add the successfully sent message to the local history cache
          // This requires constructing a proper ChatMessage object from the response
          // or assuming success and creating one locally. This is complex.
          // It might be simpler to rely on fetching history later.
        } on ApiException catch (apiError, stack) {
          // Catch specific API errors
          AppLogger.e(
              'SyncService',
              '发送待处理消息失败 (API Error $localId): ${apiError.message}',
              apiError,
              stack);
          // Decide if error is temporary or permanent.
          // For now, leave in queue and retry later.
          // If 4xx error, maybe remove from queue?
          if (apiError.statusCode >= 400 &&
              apiError.statusCode < 500 &&
              apiError.statusCode != 401 &&
              apiError.statusCode != 429) {
            AppLogger.w('SyncService',
                '接收到客户端错误 (${apiError.statusCode})，可能移除待发送消息 $localId');
            // Consider removing permanently failed message
            // await localStorageService.removePendingMessage(localId);
          }
        } catch (e, stackTrace) {
          // Catch other errors
          AppLogger.e(
              'SyncService', '发送待处理消息时发生未知错误 ($localId)', e, stackTrace);
          // Leave in queue for retry
        }
      }
      AppLogger.i('SyncService', '处理待发送消息完成。');
    } catch (e, stackTrace) {
      // Error fetching or processing the queue itself
      AppLogger.e('SyncService', '处理待发送消息队列时出错', e, stackTrace);
      // Don't throw, allow other sync tasks. Update state?
      // _updateSyncState(error: '部分同步失败: 待发送消息');
    }
  }

  /// 同步单个小说
  Future<bool> syncNovel(String novelId) async {
    // 如果服务已关闭，直接返回
    if (_isDisposed) {
      AppLogger.w('SyncService', '服务已关闭，无法同步小说');
      return false;
    }
    
    if (!_currentState.isOnline) {
      _updateSyncState(error: '无网络连接，无法同步');
      return false;
    }

    try {
      // 获取本地小说
      final localNovel = await localStorageService.getNovel(novelId);
      if (localNovel == null) return false;

      // 构建后端所需的小说数据结构
      final backendNovelJson = {
        'id': localNovel.id,
        'title': localNovel.title,
        'coverImage': localNovel.coverUrl,
        // 确保包含作者信息
        'author': localNovel.author?.toJson() ??
            {
              'id': AppConfig.userId ?? '',
              'username': AppConfig.username ?? 'user'
            },
        'lastEditedChapterId': localNovel.lastEditedChapterId,
        'createdAt': localNovel.createdAt.toIso8601String(),
        'updatedAt': DateTime.now().toIso8601String(),
        'structure': {
          'acts': localNovel.acts
              .map((act) => {
                    'id': act.id,
                    'title': act.title,
                    'order': act.order,
                    'chapters': act.chapters
                        .map((chapter) => {
                              'id': chapter.id,
                              'title': chapter.title,
                              'order': chapter.order,
                              // 注意：章节中只需包含ID，场景内容通过scenesByChapter单独提供
                              'sceneIds': chapter.scenes.map((scene) => scene.id).toList(),
                            })
                        .toList(),
                  })
              .toList(),
        },
      };
      
      // 组织场景数据，按章节分组
      Map<String, List<Map<String, dynamic>>> scenesByChapter = {};
      for (final act in localNovel.acts) {
        for (final chapter in act.chapters) {
          if (chapter.scenes.isNotEmpty) {
            scenesByChapter[chapter.id] = chapter.scenes
                .map((scene) => {
                      'id': scene.id,
                      'novelId': localNovel.id,
                      'chapterId': chapter.id,
                      'content': scene.content,
                      'summary': scene.summary.content,
                      'updatedAt': scene.lastEdited.toIso8601String(),
                      'version': scene.version,
                      'title': '',
                      'sequence': 0,
                      'sceneType': 'NORMAL',
                    })
                .toList();
          }
        }
      }
      
      // 组装完整的请求数据
      final novelWithScenesJson = {
        'novel': backendNovelJson,
        'scenesByChapter': scenesByChapter,
      };

      // 调用updateNovelWithScenes接口
      await apiService.updateNovelWithScenes(novelWithScenesJson);

      // 标记为已同步
      await localStorageService.clearSyncFlagByType('novel', novelId);

      return true;
    } catch (e) {
      AppLogger.e('Services/sync_service', '同步小说失败', e);
      _updateSyncState(error: '同步小说失败: $e');
      return false;
    }
  }

  /// 同步单个场景
  Future<bool> syncScene(
      String novelId, String actId, String chapterId, String sceneId) async {
    // 如果服务已关闭，直接返回
    if (_isDisposed) {
      AppLogger.w('SyncService', '服务已关闭，无法同步场景');
      return false;
    }
    
    if (!_currentState.isOnline) {
      _updateSyncState(error: '无网络连接，无法同步');
      return false;
    }

    try {
      // 获取本地场景
      final localScene = await localStorageService.getSceneContent(
          novelId, actId, chapterId, sceneId);
      if (localScene == null) return false;

      // 上传到服务器
      final sceneData = localScene.toJson();
      await apiService.updateScene(sceneData);

      // 标记为已同步
      final sceneKey = '${novelId}_${actId}_${chapterId}_$sceneId';
      await localStorageService.clearSyncFlagByType('scene', sceneKey);

      return true;
    } catch (e) {
      AppLogger.e('Services/sync_service', '同步场景失败', e);
      _updateSyncState(error: '同步场景失败: $e');
      return false;
    }
  }

  /// 同步单个编辑器内容
  Future<bool> syncEditorContent(String novelId, String chapterId,
      String sceneId) async {
    // 如果服务已关闭，直接返回
    if (_isDisposed) {
      AppLogger.w('SyncService', '服务已关闭，无法同步编辑器内容');
      return false;
    }
    
    if (!_currentState.isOnline) {
      _updateSyncState(error: '无网络连接，无法同步');
      return false;
    }

    try {
      // 获取本地编辑器内容
      final localContent = await localStorageService.getEditorContent(
          novelId, chapterId, ''); // 传递空的 sceneId 或适配
      if (localContent == null) return false;

      // 上传到服务器
      await apiService.saveEditorContent(
          novelId, chapterId, localContent.toJson());

      // 标记为已同步
      final contentKey = '${novelId}_$chapterId'; // 调整 key
      await localStorageService.clearSyncFlagByType('editor', contentKey);

      return true;
    } catch (e) {
      AppLogger.e('Services/sync_service', '同步编辑器内容失败', e);
      _updateSyncState(error: '同步编辑器内容失败: $e');
      return false;
    }
  }

  /// 同步单个聊天会话元数据 (不再发送消息历史)
  Future<bool> syncChatSession(String sessionId) async {
    // 如果服务已关闭，直接返回
    if (_isDisposed) {
      AppLogger.w('SyncService', '服务已关闭，无法同步聊天会话');
      return false;
    }
    
    if (!_currentState.isOnline) {
      _updateSyncState(error: '无网络连接，无法同步');
      return false;
    }

    try {
      final session = await localStorageService.getChatSession(sessionId);
      if (session == null) {
        AppLogger.w('SyncService', '尝试同步单个会话元数据，但本地未找到: $sessionId');
        await localStorageService.clearSyncFlagByType(
            'chat_session', sessionId); // 清除无效标记
        return false; // 无法同步不存在的会话
      }

      // 同步元数据 (例如: title)
      final Map<String, dynamic> updates = {'title': session.title};

      if (updates.isNotEmpty) {
        await apiService.updateAiChatSession(
          userId: await _getCurrentUserId(), // 如果 API 需要，获取 userId
          sessionId: session.id,
          updates: updates,
        );
        AppLogger.d('SyncService', '单个聊天会话元数据 API 更新调用完成: $sessionId');
      } else {
        AppLogger.d('SyncService', '单个聊天会话 ${session.id} 没有需要同步的元数据更新');
      }

      // ======== 移除: 不再通过 getMessagesForSession 循环发送消息 ========

      // 清除此会话的元数据同步标记
      await localStorageService.clearSyncFlagByType('chat_session', sessionId);
      AppLogger.i('SyncService', '单个聊天会话元数据同步处理完成: $sessionId');
      return true;
    } catch (e, stackTrace) {
      // 捕获所有可能的错误
      AppLogger.e('SyncService', '同步单个聊天会话元数据失败 ($sessionId)', e, stackTrace);
      _updateSyncState(error: '同步单个聊天会话元数据失败: $e');
      // 同步失败，暂时不清除标记，留待下次重试
      return false;
    }
  }

  /// 解决冲突 (需要根据聊天数据的具体冲突场景来完善)

  /// 关闭服务，释放资源
  void dispose() {
    // 设置已关闭标志
    _isDisposed = true;
    
    // 取消网络监听和定时器
    _connectivitySubscription?.cancel();
    _autoSyncTimer?.cancel();
    
    // 关闭状态流
    if (!_syncStateController.isClosed) {
      _syncStateController.close();
    }
    
    // 清除当前小说ID，避免后续同步错误
    localStorageService.setCurrentNovelId('').then((_) {
      AppLogger.i('SyncService', '同步服务已关闭，清除当前小说ID');
    });
    
    AppLogger.i('SyncService', '同步服务已关闭');
  }

  /// 获取当前用户ID (使用 AppConfig 实现)
  Future<String> _getCurrentUserId() async {
    final userId = AppConfig.userId; // 从 AppConfig 获取用户ID
    if (userId == null || userId.isEmpty) {
      AppLogger.e('SyncService', '无法获取当前用户ID，同步操作可能失败或无法执行。');
      // 根据需求，可以抛出异常或返回占位符/空字符串
      // 如果 userId 是必需的，抛出异常更安全
      throw SyncException('无法获取当前用户ID，无法执行需要用户ID的同步操作。');
    }
    return userId;
  }

  /// 直接设置当前小说ID
  Future<void> setCurrentNovelId(String novelId) async {
    // 即使服务已关闭也允许设置，但记录警告
    if (_isDisposed) {
      AppLogger.w('SyncService', '尝试在服务已关闭状态下设置当前小说ID: $novelId');
      // 考虑到可能在关闭过程中调用此方法，仍然允许操作继续
    }
    
    await localStorageService.setCurrentNovelId(novelId);
    AppLogger.i('SyncService', '同步服务已设置当前小说ID: $novelId');
  }
}

/// 同步状态类
class SyncState {
  SyncState({
    required this.isOnline, // 网络是否连接
    required this.isSyncing, // 是否正在同步中
    this.error, // 同步错误信息，null表示无错误
    this.progress = 0.0, // 同步进度 (0.0 到 1.0)
  });

  /// 空闲状态 (默认在线)
  factory SyncState.idle({bool online = true}) {
    return SyncState(
      isOnline: online,
      isSyncing: false,
    );
  }

  /// 同步中状态
  factory SyncState.syncing({double progress = 0.0}) {
    return SyncState(
      isOnline: true, // 同步时必须在线
      isSyncing: true,
      progress: progress,
    );
  }

  /// 离线状态
  factory SyncState.offline() {
    return SyncState(
      isOnline: false,
      isSyncing: false, // 离线时不能同步
    );
  }

  /// 错误状态 (允许指定当时的网络状态)
  factory SyncState.error(String errorMessage, {bool online = true}) {
    return SyncState(
      isOnline: online, // 错误可能在线或离线时发生
      isSyncing: false, // 出错时停止同步
      error: errorMessage,
    );
  }
  final bool isOnline;
  final bool isSyncing;
  final String? error;
  final double progress;

  @override
  String toString() {
    // 提供更清晰的状态描述
    return 'SyncState(在线: $isOnline, 同步中: $isSyncing, 进度: ${progress.toStringAsFixed(2)}, 错误: ${error ?? "无"})';
  }
}

/// 同步异常类
class SyncException implements Exception {
  SyncException(this.message);
  final String message; // 异常信息

  @override
  String toString() => 'SyncException: $message';
}
